From 15b9be7cc8ca9e762e11cbd65264d652db541473 Mon Sep 17 00:00:00 2001 From: Andreas Dinauer Date: Sat, 18 Apr 2026 14:34:49 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=20Add=20snapshot=20parser=20+=20fi?= =?UTF-8?q?x=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../maven/core/MavenContextProvider.java | 21 +++-- .../maven/core/model/ExtensionParser.java | 36 +++++++++ .../dinauer/maven/maven/core/model/File.java | 49 +++++------- .../maven/maven/core/model/FileHash.java | 2 +- .../maven/maven/core/model/FileParser.java | 39 +++++++++ .../maven/maven/core/model/SnapshotFile.java | 41 ++++++++++ .../maven/core/model/SnapshotFileParser.java | 80 +++++++++++++++++++ .../{ => parser}/MavenMetadataUrlParser.java | 2 +- .../core/{ => parser}/MavenUrlParser.java | 2 +- .../maven/core/model/ExtensionParserTest.java | 43 ++++++++++ .../core/model/SnapshotFileParserTest.java | 21 +++++ 11 files changed, 299 insertions(+), 37 deletions(-) create mode 100644 src/main/java/dev/dinauer/maven/maven/core/model/ExtensionParser.java create mode 100644 src/main/java/dev/dinauer/maven/maven/core/model/FileParser.java create mode 100644 src/main/java/dev/dinauer/maven/maven/core/model/SnapshotFile.java create mode 100644 src/main/java/dev/dinauer/maven/maven/core/model/SnapshotFileParser.java rename src/main/java/dev/dinauer/maven/maven/core/{ => parser}/MavenMetadataUrlParser.java (95%) rename src/main/java/dev/dinauer/maven/maven/core/{ => parser}/MavenUrlParser.java (96%) create mode 100644 src/test/java/dev/dinauer/maven/maven/core/model/ExtensionParserTest.java create mode 100644 src/test/java/dev/dinauer/maven/maven/core/model/SnapshotFileParserTest.java diff --git a/src/main/java/dev/dinauer/maven/maven/core/MavenContextProvider.java b/src/main/java/dev/dinauer/maven/maven/core/MavenContextProvider.java index 156147a..8ce287d 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/MavenContextProvider.java +++ b/src/main/java/dev/dinauer/maven/maven/core/MavenContextProvider.java @@ -1,7 +1,9 @@ package dev.dinauer.maven.maven.core; -import dev.dinauer.maven.maven.core.model.File; -import dev.dinauer.maven.maven.core.model.MavenContext; +import dev.dinauer.maven.maven.core.model.*; +import dev.dinauer.maven.maven.core.parser.MavenMetadataUrlParser; +import dev.dinauer.maven.maven.core.parser.MavenUrlParser; +import org.apache.commons.io.FilenameUtils; import java.nio.file.Path; @@ -9,20 +11,27 @@ public class MavenContextProvider { public static MavenContext parse(String path) { - File file = File.parse(Path.of(path).getFileName().toString()); - switch (file.getType()) + switch (getExtension(path)) { case JAR, POM -> { MavenUrlParser parser = MavenUrlParser.parse(path); - return new MavenContext(path, parser.groupId(), parser.artifactId(), parser.version(), file); + String artifact = parser.artifactId(); + Version version = parser.version(); + return new MavenContext(path, parser.groupId(), artifact, version, FileParser.parse(artifact, version.getRaw(), Path.of(path).getFileName().toString())); } case XML -> { MavenMetadataUrlParser parser = MavenMetadataUrlParser.parse(path); - return new MavenContext(path, parser.groupId(), parser.artifactId(), null, file); + String artifact = parser.artifactId(); + return new MavenContext(path, parser.groupId(), parser.artifactId(), null, null); } } throw new RuntimeException(); } + + private static FileType getExtension(String filename) + { + return ExtensionParser.parse(filename).ext(); + } } diff --git a/src/main/java/dev/dinauer/maven/maven/core/model/ExtensionParser.java b/src/main/java/dev/dinauer/maven/maven/core/model/ExtensionParser.java new file mode 100644 index 0000000..04c5539 --- /dev/null +++ b/src/main/java/dev/dinauer/maven/maven/core/model/ExtensionParser.java @@ -0,0 +1,36 @@ +package dev.dinauer.maven.maven.core.model; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.Strings; + +import java.util.List; + +public class ExtensionParser +{ + private static final List FILE_TYPES = List.of("jar", "pom", "xml"); + private static final List FILE_HASHES = List.of("md5", "sha1", "sha256", "sha512"); + + public static Result parse(String raw) + { + String firstLevelExtension = FilenameUtils.getExtension(raw); + String firstLevelBase = Strings.CI.removeEnd(raw, String.format(".%s", firstLevelExtension)); + if (FILE_TYPES.contains(firstLevelExtension)) + { + return new Result(firstLevelBase, FileType.valueOf(firstLevelExtension.toUpperCase()), null); + } + if (FILE_HASHES.contains(firstLevelExtension)) + { + String secondLevelExtension = FilenameUtils.getExtension(firstLevelBase); + if (FILE_TYPES.contains(secondLevelExtension)) + { + String secondLevelBase = Strings.CI.removeEnd(firstLevelBase, String.format(".%s", secondLevelExtension)); + return new Result(secondLevelBase, FileType.valueOf(secondLevelExtension.toUpperCase()), FileHash.valueOf(firstLevelExtension.toUpperCase())); + } + } + throw new RuntimeException(); + } + + public record Result(String base, FileType ext, FileHash hashExt) + { + } +} diff --git a/src/main/java/dev/dinauer/maven/maven/core/model/File.java b/src/main/java/dev/dinauer/maven/maven/core/model/File.java index 3e9d4a8..cfd9abb 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/model/File.java +++ b/src/main/java/dev/dinauer/maven/maven/core/model/File.java @@ -7,10 +7,8 @@ import java.util.List; public class File { - private static final String METADATA_FILENAME = "maven-metadata"; - private static final List FILE_TYPES = List.of("jar", "pom", "xml"); - private static final List FILE_HASHES = List.of("md5", "sha1"); - + private String artifactId; + private String version; private String raw; private String base; private FileType type; @@ -60,30 +58,25 @@ public class File return this; } - public static File parse(String raw) + public String getArtifactId() { - File file = new File().setRaw(raw); - String extension = FilenameUtils.getExtension(raw); - String base = FilenameUtils.getBaseName(raw); - if (FILE_TYPES.contains(extension.toLowerCase())) - { - file.setType(FileType.valueOf(extension.toUpperCase())); - file.setBase(base); - file.setHash(FileHash.NONE); - return file; - } - if (FILE_HASHES.contains(extension)) - { - file.setHash(FileHash.valueOf(extension.toUpperCase())); - String secondaryExtension = FilenameUtils.getExtension(base); - String secondaryBase = FilenameUtils.getBaseName(base); - if (FILE_TYPES.contains(secondaryExtension.toLowerCase())) - { - file.setType(FileType.valueOf(secondaryExtension.toUpperCase())); - file.setBase(secondaryBase); - return file; - } - } - throw new BadRequestException(); + return artifactId; + } + + public File setArtifactId(String artifactId) + { + this.artifactId = artifactId; + return this; + } + + public String getVersion() + { + return version; + } + + public File setVersion(String version) + { + this.version = version; + return this; } } diff --git a/src/main/java/dev/dinauer/maven/maven/core/model/FileHash.java b/src/main/java/dev/dinauer/maven/maven/core/model/FileHash.java index 16684ce..39402cb 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/model/FileHash.java +++ b/src/main/java/dev/dinauer/maven/maven/core/model/FileHash.java @@ -2,5 +2,5 @@ package dev.dinauer.maven.maven.core.model; public enum FileHash { - SHA1, MD5, NONE + SHA1, SHA256, SHA512, MD5, NONE } diff --git a/src/main/java/dev/dinauer/maven/maven/core/model/FileParser.java b/src/main/java/dev/dinauer/maven/maven/core/model/FileParser.java new file mode 100644 index 0000000..94e709e --- /dev/null +++ b/src/main/java/dev/dinauer/maven/maven/core/model/FileParser.java @@ -0,0 +1,39 @@ +package dev.dinauer.maven.maven.core.model; + +import jakarta.ws.rs.BadRequestException; +import org.apache.commons.io.FilenameUtils; + +import java.util.List; + +public class FileParser +{ + private static final List FILE_TYPES = List.of("jar", "pom", "xml"); + private static final List FILE_HASHES = List.of("md5", "sha1"); + + public static File parse(String artifactId, String version, String raw) + { + File file = new File().setRaw(raw); + String extension = FilenameUtils.getExtension(raw); + String base = FilenameUtils.getBaseName(raw); + if (FILE_TYPES.contains(extension.toLowerCase())) + { + file.setType(FileType.valueOf(extension.toUpperCase())); + file.setBase(base); + file.setHash(FileHash.NONE); + return file; + } + if (FILE_HASHES.contains(extension)) + { + file.setHash(FileHash.valueOf(extension.toUpperCase())); + String secondaryExtension = FilenameUtils.getExtension(base); + String secondaryBase = FilenameUtils.getBaseName(base); + if (FILE_TYPES.contains(secondaryExtension.toLowerCase())) + { + file.setType(FileType.valueOf(secondaryExtension.toUpperCase())); + file.setBase(secondaryBase); + return file; + } + } + throw new BadRequestException(); + } +} diff --git a/src/main/java/dev/dinauer/maven/maven/core/model/SnapshotFile.java b/src/main/java/dev/dinauer/maven/maven/core/model/SnapshotFile.java new file mode 100644 index 0000000..49fce40 --- /dev/null +++ b/src/main/java/dev/dinauer/maven/maven/core/model/SnapshotFile.java @@ -0,0 +1,41 @@ +package dev.dinauer.maven.maven.core.model; + +public class SnapshotFile extends File +{ + private int buildNumber; + private String date; + private String time; + + public int getBuildNumber() + { + return buildNumber; + } + + public SnapshotFile setBuildNumber(int buildNumber) + { + this.buildNumber = buildNumber; + return this; + } + + public String getDate() + { + return date; + } + + public SnapshotFile setDate(String date) + { + this.date = date; + return this; + } + + public String getTime() + { + return time; + } + + public SnapshotFile setTime(String time) + { + this.time = time; + return this; + } +} diff --git a/src/main/java/dev/dinauer/maven/maven/core/model/SnapshotFileParser.java b/src/main/java/dev/dinauer/maven/maven/core/model/SnapshotFileParser.java new file mode 100644 index 0000000..e25ca95 --- /dev/null +++ b/src/main/java/dev/dinauer/maven/maven/core/model/SnapshotFileParser.java @@ -0,0 +1,80 @@ +package dev.dinauer.maven.maven.core.model; + +import jakarta.ws.rs.BadRequestException; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.Strings; + +import java.util.List; +import java.util.OptionalInt; +import java.util.stream.IntStream; + +public class SnapshotFileParser +{ + public static SnapshotFile parse(String artifactId, String version, String raw) + { + ExtensionParser.Result extensionResult = ExtensionParser.parse(raw); + + SnapshotFile file = new SnapshotFile(); + + file.setBase(extensionResult.base()); + file.setType(extensionResult.ext()); + file.setHash(extensionResult.hashExt()); + + file.setRaw(raw); + file.setArtifactId(artifactId); + file.setVersion(version); + + String dataString = prepareForData(artifactId, version, raw); + file.setDate(getDate(dataString)); + + String timeString = prepareForTime(dataString); + file.setTime(getTime(timeString)); + + String buildNumberString = prepareForBuildNumber(timeString); + file.setBuildNumber(getBuildNumber(buildNumberString)); + + return file; + } + + private static String prepareForData(String artifact, String version, String raw) + { + return Strings.CI.removeStart(raw, String.format("%s-%s-", artifact, prepareVersion(version))); + } + + private static String prepareForTime(String path) + { + return Strings.CI.removeStart(path.substring(9), "."); + } + + private static String prepareForBuildNumber(String path) + { + return Strings.CI.removeStart(path.substring(7), "-"); + } + + private static int getBuildNumber(String path) + { + int nextDot = path.indexOf("."); + int nextDash = path.indexOf("-"); + OptionalInt optInt = IntStream.of(nextDash, nextDot).filter(index -> index > 0).min(); + if (optInt.isPresent()) + { + return Integer.parseInt(path.substring(0, optInt.getAsInt())); + } + throw new IllegalArgumentException(); + } + + private static String getDate(String path) + { + return path.substring(0, 8); + } + + private static String getTime(String path) + { + return path.substring(0, 6); + } + + private static String prepareVersion(String version) + { + return Strings.CI.removeEnd(version, "-SNAPSHOT"); + } +} diff --git a/src/main/java/dev/dinauer/maven/maven/core/MavenMetadataUrlParser.java b/src/main/java/dev/dinauer/maven/maven/core/parser/MavenMetadataUrlParser.java similarity index 95% rename from src/main/java/dev/dinauer/maven/maven/core/MavenMetadataUrlParser.java rename to src/main/java/dev/dinauer/maven/maven/core/parser/MavenMetadataUrlParser.java index 77f00e1..a46c6e9 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/MavenMetadataUrlParser.java +++ b/src/main/java/dev/dinauer/maven/maven/core/parser/MavenMetadataUrlParser.java @@ -1,4 +1,4 @@ -package dev.dinauer.maven.maven.core; +package dev.dinauer.maven.maven.core.parser; import jakarta.ws.rs.BadRequestException; diff --git a/src/main/java/dev/dinauer/maven/maven/core/MavenUrlParser.java b/src/main/java/dev/dinauer/maven/maven/core/parser/MavenUrlParser.java similarity index 96% rename from src/main/java/dev/dinauer/maven/maven/core/MavenUrlParser.java rename to src/main/java/dev/dinauer/maven/maven/core/parser/MavenUrlParser.java index 1e4f489..f031562 100644 --- a/src/main/java/dev/dinauer/maven/maven/core/MavenUrlParser.java +++ b/src/main/java/dev/dinauer/maven/maven/core/parser/MavenUrlParser.java @@ -1,4 +1,4 @@ -package dev.dinauer.maven.maven.core; +package dev.dinauer.maven.maven.core.parser; import dev.dinauer.maven.maven.core.model.Version; import jakarta.ws.rs.BadRequestException; diff --git a/src/test/java/dev/dinauer/maven/maven/core/model/ExtensionParserTest.java b/src/test/java/dev/dinauer/maven/maven/core/model/ExtensionParserTest.java new file mode 100644 index 0000000..5f89173 --- /dev/null +++ b/src/test/java/dev/dinauer/maven/maven/core/model/ExtensionParserTest.java @@ -0,0 +1,43 @@ +package dev.dinauer.maven.maven.core.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ExtensionParserTest +{ + @Test + void test_01() + { + String filename = "test.jar.md5"; + + ExtensionParser.Result result = ExtensionParser.parse(filename); + + Assertions.assertEquals("test", result.base()); + Assertions.assertEquals(FileType.JAR, result.ext()); + Assertions.assertEquals(FileHash.MD5, result.hashExt()); + } + + @Test + void test_02() + { + String filename = "test.pom.sha1"; + + ExtensionParser.Result result = ExtensionParser.parse(filename); + + Assertions.assertEquals("test", result.base()); + Assertions.assertEquals(FileType.POM, result.ext()); + Assertions.assertEquals(FileHash.SHA1, result.hashExt()); + } + + @Test + void test_03() + { + String filename = "test.jar"; + + ExtensionParser.Result result = ExtensionParser.parse(filename); + + Assertions.assertEquals("test", result.base()); + Assertions.assertEquals(FileType.JAR, result.ext()); + Assertions.assertNull(result.hashExt()); + } +} diff --git a/src/test/java/dev/dinauer/maven/maven/core/model/SnapshotFileParserTest.java b/src/test/java/dev/dinauer/maven/maven/core/model/SnapshotFileParserTest.java new file mode 100644 index 0000000..1a052ab --- /dev/null +++ b/src/test/java/dev/dinauer/maven/maven/core/model/SnapshotFileParserTest.java @@ -0,0 +1,21 @@ +package dev.dinauer.maven.maven.core.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class SnapshotFileParserTest +{ + @Test + void test() + { + String filename = "my-library-1.0.0-20240315.142307-3-tests.jar.md5"; + + SnapshotFile file = SnapshotFileParser.parse("my-library", "1.0.0-SNAPSHOT", filename); + + Assertions.assertEquals("20240315", file.getDate()); + Assertions.assertEquals("142307", file.getTime()); + Assertions.assertEquals(3, file.getBuildNumber()); + Assertions.assertEquals(FileType.JAR, file.getType()); + Assertions.assertEquals(FileHash.MD5, file.getHash()); + } +}