diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 2c3bfa2ff..aeabf7538 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -9,6 +9,7 @@ Release with new features and bugfixes: * https://github.com/devonfw/IDEasy/issues/1552[#1552]: Add Commandlet to fix TLS issue * https://github.com/devonfw/IDEasy/issues/1799[#1799]: Add support for file URL in GitUrl validation for local development * https://github.com/devonfw/IDEasy/issues/1760[#1760]: Accept empty input for single option +* https://github.com/devonfw/IDEasy/issues/1775[#1775]: validated and updated CPE's for all products The full list of changes for this release can be found in https://github.com/devonfw/IDEasy/milestone/43?closed=1[milestone 2026.04.002]. diff --git a/documentation/contributing/README.adoc b/documentation/contributing/README.adoc index 485b58629..3389ed19b 100644 --- a/documentation/contributing/README.adoc +++ b/documentation/contributing/README.adoc @@ -18,3 +18,6 @@ To support cross-platform testing also consider link:testing-linux-on-windows.ad You may also install Windows or other OS in a VM if you need to test the IDEasy installation process itself and retest it multiple times using VM snapshots without tweaking or even breaking your host OS. Further, we documented link:junit-testing.adoc[JUnit-testing] and link:integration-testing.adoc[integration-testing] to help you properly testing your new code. + +For security mapping in URL updater development, see link:cpe-url-updater.adoc[CPE integration for URL updaters]. + diff --git a/security/src/main/java/com/devonfw/tools/IDEasy/dev/BuildSecurityJsonFiles.java b/security/src/main/java/com/devonfw/tools/IDEasy/dev/BuildSecurityJsonFiles.java index 33662b1eb..8b6a19f42 100644 --- a/security/src/main/java/com/devonfw/tools/IDEasy/dev/BuildSecurityJsonFiles.java +++ b/security/src/main/java/com/devonfw/tools/IDEasy/dev/BuildSecurityJsonFiles.java @@ -4,6 +4,7 @@ import java.nio.file.Path; import java.time.Instant; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -77,13 +78,10 @@ public void run() { String updaterName = updater.getClass().getSimpleName(); String tool = updater.getTool(); LOG.info("Processing {} for tool {}", updaterName, tool); - CpeBuilder cpeBuilder = new CpeBuilder(); - cpeBuilder.vendor(updater.getCpeVendor()); - cpeBuilder.product(updater.getCpeProduct()); - Cpe cpe = cpeBuilder.build(); - List vulnerabilities = database.getVulnerabilities(cpe); + List vulnerabilities = findVulnerabilities(database, updater); if ((vulnerabilities == null) || (vulnerabilities.isEmpty())) { - LOG.info("No vulnerabilities found for {} with CPE {}", updaterName, cpe); + LOG.info("No vulnerabilities found for {} with CPE {}:{}", updaterName, updater.getCpeRegistry().getPrimaryVendor(), + updater.getCpeRegistry().getPrimaryProduct()); } else { for (String edition : updater.getEditions()) { LOG.info("Processing edition {} for tool {}", edition, tool); @@ -161,9 +159,7 @@ private static List toVersions(Vulnerability vulnerability, String private static VersionRange toVersionRange(VulnerableSoftware range, String edition, AbstractUrlUpdater urlUpdater, String id) { - if (!range.getVendor().equals(urlUpdater.getCpeVendor())) { - return null; - } else if (!range.getProduct().equals(urlUpdater.getCpeProduct())) { + if (!urlUpdater.matchesCpe(range.getVendor(), range.getProduct())) { return null; } String cpeEdition = findCpeEdition(range); @@ -257,6 +253,59 @@ private static boolean isSpecificValue(String value) { return (value != null) && !"*".equals(value) && !IGNORED_VALUES.contains(value); } + private static List findVulnerabilities(CveDB database, AbstractUrlUpdater updater) { + + List searchCpes = createSearchCpes(updater); + List vulnerabilities = new ArrayList<>(); + Set seenNames = new LinkedHashSet<>(); + for (int i = 0; i < searchCpes.size(); i++) { + Cpe cpe = searchCpes.get(i); + List found = database.getVulnerabilities(cpe); + if ((found != null) && !found.isEmpty()) { + for (Vulnerability vulnerability : found) { + if (seenNames.add(vulnerability.getName())) { + vulnerabilities.add(vulnerability); + } + } + if (i == 0) { + return vulnerabilities; + } + } + } + return vulnerabilities; + } + + private static List createSearchCpes(AbstractUrlUpdater updater) { + + AbstractUrlUpdater.CpeRegistry cpe = updater.getCpeRegistry(); + List searchCpes = new ArrayList<>(); + addSearchCpe(searchCpes, cpe.getPrimaryVendor(), cpe.getPrimaryProduct()); + addSearchCpe(searchCpes, cpe.getPrimaryVendor(), "*"); + addSearchCpe(searchCpes, "*", cpe.getPrimaryProduct()); + return searchCpes; + } + + private static void addSearchCpe(List searchCpes, String vendor, String product) { + + if ((vendor == null) || (product == null)) { + return; + } + try { + CpeBuilder cpeBuilder = new CpeBuilder(); + cpeBuilder.vendor(vendor); + cpeBuilder.product(product); + Cpe cpe = cpeBuilder.build(); + for (Cpe existing : searchCpes) { + if (existing.getVendor().equals(cpe.getVendor()) && existing.getProduct().equals(cpe.getProduct())) { + return; + } + } + searchCpes.add(cpe); + } catch (Exception e) { + throw new IllegalStateException("Failed to create search CPE for vendor '" + vendor + "' and product '" + product + "'.", e); + } + } + /** * Determines the severity of the vulnerability. * diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdater.java index 052e65430..5b60b9877 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/androidstudio/AndroidStudioUrlUpdater.java @@ -76,14 +76,5 @@ protected Collection getVersionItems(AndroidJsonObject jsonObje return jsonObject.content().item(); } - - @Override - public String getCpeVendor() { - return "google"; - } - - @Override - public String getCpeProduct() { - return "android_studio"; - } + } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/aws/AwsUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/aws/AwsUrlUpdater.java index df8f46ca9..6e1c28521 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/aws/AwsUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/aws/AwsUrlUpdater.java @@ -73,7 +73,7 @@ public String getCpeVendor() { @Override public String getCpeProduct() { - return "aws"; + return "aws_command_line_interface"; } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/az/AzureUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/az/AzureUrlUpdater.java index 900808380..c95901664 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/az/AzureUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/az/AzureUrlUpdater.java @@ -63,6 +63,6 @@ public String getCpeVendor() { @Override public String getCpeProduct() { - return "az"; + return "azure_command-line_interface"; } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/corepack/CorepackUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/corepack/CorepackUrlUpdater.java index a99973721..72099893d 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/corepack/CorepackUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/corepack/CorepackUrlUpdater.java @@ -18,14 +18,5 @@ protected String getPackageName() { return "corepack"; } - - @Override - public String getCpeVendor() { - return "corepack"; - } - - @Override - public String getCpeProduct() { - return "corepack"; - } + } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java index 0ddcc65f2..a0f65d49f 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/docker/DockerDesktopUrlUpdater.java @@ -83,6 +83,6 @@ public String getCpeVendor() { @Override public String getCpeProduct() { - return "docker"; + return "desktop"; } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/dotnet/DotNetUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/dotnet/DotNetUrlUpdater.java index 3f78068ce..692537d15 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/dotnet/DotNetUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/dotnet/DotNetUrlUpdater.java @@ -69,6 +69,6 @@ public String getCpeVendor() { @Override public String getCpeProduct() { - return "dotnet"; + return ".net"; } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseUrlUpdater.java index 3148e7246..17c514fa6 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/eclipse/EclipseUrlUpdater.java @@ -126,6 +126,6 @@ public String getCpeVendor() { @Override public String getCpeProduct() { - return "eclipse"; + return "eclipse_ide"; } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcloud/GCloudUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcloud/GCloudUrlUpdater.java index 8c045e00f..f58a33990 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcloud/GCloudUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcloud/GCloudUrlUpdater.java @@ -51,15 +51,6 @@ protected void addVersion(UrlVersion urlVersion) { } } } - - @Override - public String getCpeVendor() { - return "google"; - } - - @Override - public String getCpeProduct() { - return "gcloud"; - } + } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcviewer/GcViewerUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcviewer/GcViewerUrlUpdater.java index 1c66206f7..4b9c583dd 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcviewer/GcViewerUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gcviewer/GcViewerUrlUpdater.java @@ -47,15 +47,4 @@ public String mapVersion(String version) { return null; } } - - @Override - public String getCpeVendor() { - return "chewiebug"; - } - - @Override - public String getCpeProduct() { - return "gcviewer"; - } - } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gh/GhUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gh/GhUrlUpdater.java index fa4267caa..b6870bc98 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gh/GhUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/gh/GhUrlUpdater.java @@ -59,6 +59,6 @@ public String getCpeVendor() { @Override public String getCpeProduct() { - return "gh"; + return "cli"; } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/go/GoUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/go/GoUrlUpdater.java index 4fa02f5a3..620479c27 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/go/GoUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/go/GoUrlUpdater.java @@ -66,5 +66,17 @@ protected void addVersion(UrlVersion urlVersion) { protected String getCustomVersionFilter() { return "rc"; } + + @Override + public String getCpeVendor() { + return "golang"; + } + + @Override + public String getCpeProduct() { + return "go"; + } + + } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/helm/HelmUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/helm/HelmUrlUpdater.java index 5eced042a..03c42df90 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/helm/HelmUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/helm/HelmUrlUpdater.java @@ -35,17 +35,6 @@ protected String getDownloadBaseUrl() { return "https://get.helm.sh"; } - @Override - public String getCpeVendor() { - - return "helm"; - } - - @Override - public String getCpeProduct() { - - return "helm"; - } @Override protected void addVersion(UrlVersion urlVersion) { @@ -67,5 +56,16 @@ public String mapVersion(String version) { return super.mapVersion("v" + version); } + @Override + public String getCpeVendor() { + + return "helm"; + } + + @Override + public String getCpeProduct() { + + return "helm"; + } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdater.java index 9713acf0e..398e8f835 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/intellij/IntellijUrlUpdater.java @@ -47,7 +47,7 @@ public String getCpeVendor() { @Override public String getCpeProduct() { - return "intellij"; + return "intellij_idea"; } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jasypt/JasyptUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jasypt/JasyptUrlUpdater.java index aa143483d..c1a3601a0 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jasypt/JasyptUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jasypt/JasyptUrlUpdater.java @@ -28,15 +28,6 @@ protected String getMavenArtifcatId() { return "jasypt"; } - @Override - public String getCpeVendor() { - return "jasypt"; - } - - @Override - public String getCpeProduct() { - return "jasypt"; - } @Override public boolean isValidVersion(String version) { @@ -48,4 +39,14 @@ public boolean isValidVersion(String version) { return false; } + @Override + public String getCpeVendor() { + return "jasypt_project"; + } + + @Override + public String getCpeProduct() { + return "jasypt"; + } + } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaJsonVersion.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaJsonVersion.java index 48b5a5cc8..aa381291a 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaJsonVersion.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaJsonVersion.java @@ -8,7 +8,9 @@ * * @see JavaJsonObject#versions() */ -public record JavaJsonVersion(@JsonProperty("openjdk_version") String openjdkVersion, @JsonProperty("semver") String semver) implements JsonVersionItem { +public record JavaJsonVersion( + @JsonProperty("openjdk_version") String openjdkVersion, + @JsonProperty("semver") String semver) implements JsonVersionItem { @Override public String version() { diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdater.java index 93c8fa0f3..09eedc21a 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/java/JavaUrlUpdater.java @@ -26,17 +26,6 @@ public String mapVersion(String version) { return super.mapVersion(version); } - @Override - public String getCpeVendor() { - - return "eclipse"; - } - - @Override - public String getCpeProduct() { - - return "temurin"; - } @Override protected void addVersion(UrlVersion urlVersion) { @@ -107,4 +96,23 @@ protected Collection getVersionItems(JavaJsonObject jsonObject) return jsonObject.versions(); } + + @Override + public String getCpeVendor() { + + return "oracle"; + } + + @Override + public String getCpeProduct() { + + return "jdk"; + } + + @Override + protected void initCpe(CpeRegistry cpe) { + cpe.addVendor("oracle") + .addProduct("jdk") + .addProduct("java_se"); + } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jenkins/JenkinsUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jenkins/JenkinsUrlUpdater.java index 83405a52e..1010a0bf0 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jenkins/JenkinsUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jenkins/JenkinsUrlUpdater.java @@ -50,7 +50,7 @@ protected void addVersion(UrlVersion urlVersion) { @Override public String getCpeVendor() { - return "jenkinsci"; + return "jenkins"; } @Override diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jmc/JmcUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jmc/JmcUrlUpdater.java index 1790963f0..f6052b6f7 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jmc/JmcUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/jmc/JmcUrlUpdater.java @@ -35,14 +35,4 @@ protected void addVersion(UrlVersion urlVersion) { doAddVersion(urlVersion, baseUrl + "macosx.cocoa.x86_64.tar.gz", MAC); doAddVersion(urlVersion, baseUrl + "linux.gtk.x86_64.tar.gz", LINUX); } - - @Override - public String getCpeVendor() { - return "adoptium"; - } - - @Override - public String getCpeProduct() { - return "jmc-build"; - } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/kotlinc/KotlincNativeUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/kotlinc/KotlincNativeUrlUpdater.java index 498f445e7..b5e0d6664 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/kotlinc/KotlincNativeUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/kotlinc/KotlincNativeUrlUpdater.java @@ -50,15 +50,5 @@ protected Pattern getVersionPattern() { return Pattern.compile("[0-9]+\\.[0-9]+\\.[0-9]+"); } - - @Override - public String getCpeVendor() { - return "jetbrains"; - } - - @Override - public String getCpeProduct() { - return "kotlin-native"; - } - + } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/lazydocker/LazyDockerUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/lazydocker/LazyDockerUrlUpdater.java index 2adac25a1..c91d831a1 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/lazydocker/LazyDockerUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/lazydocker/LazyDockerUrlUpdater.java @@ -53,15 +53,4 @@ protected void addVersion(UrlVersion urlVersion) { doAddVersion(urlVersion, baseUrl + "Darwin_arm64.tar.gz", MAC, ARM64); } } - - @Override - public String getCpeVendor() { - return "jesseduffield"; - } - - @Override - public String getCpeProduct() { - return "lazydocker"; - } - } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/mvn/MvnUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/mvn/MvnUrlUpdater.java index caa4f3d30..b2b6f3a68 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/mvn/MvnUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/mvn/MvnUrlUpdater.java @@ -20,17 +20,6 @@ public String getTool() { return "mvn"; } - @Override - public String getCpeVendor() { - - return "apache"; - } - - @Override - public String getCpeProduct() { - - return "maven"; - } @Override protected String getGithubOrganization() { @@ -80,4 +69,16 @@ protected void addVersion(UrlVersion urlVersion) { doAddVersion(urlVersion, getDownloadBaseUrl() + "/dist/maven/" + majorFolder + "/${version}/binaries/apache-maven-${version}-bin.zip"); } } + + @Override + public String getCpeVendor() { + + return "apache"; + } + + @Override + public String getCpeProduct() { + + return "maven"; + } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/node/NodeUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/node/NodeUrlUpdater.java index e81991321..e9d78be89 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/node/NodeUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/node/NodeUrlUpdater.java @@ -65,20 +65,20 @@ protected void addVersion(UrlVersion urlVersion) { } } + @Override - public String getCpeVendor() { - return "nodejs"; + public String mapVersion(String version) { + + return super.mapVersion("v" + version); } @Override - public String getCpeProduct() { - return "node"; + public String getCpeVendor() { + return "nodejs"; } @Override - public String mapVersion(String version) { - - return super.mapVersion("v" + version); + public String getCpeProduct() { + return "node.js"; } - } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/npm/NpmUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/npm/NpmUrlUpdater.java index aab4a2a31..d2fa98d51 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/npm/NpmUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/npm/NpmUrlUpdater.java @@ -21,7 +21,7 @@ protected String getPackageName() { @Override public String getCpeVendor() { - return "npm"; + return "npmjs"; } @Override diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/oc/OcUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/oc/OcUrlUpdater.java index 78ad5a6a8..41d226e20 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/oc/OcUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/oc/OcUrlUpdater.java @@ -33,16 +33,6 @@ protected void addVersion(UrlVersion urlVersion) { doAddVersion(urlVersion, baseUrl + "mac-${version}.tar.gz", MAC); } - @Override - public String getCpeVendor() { - return "openshift"; - } - - @Override - public String getCpeProduct() { - return "oc"; - } - @Override protected String getVersionUrl() { diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pgadmin/PgAdminUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pgadmin/PgAdminUrlUpdater.java index 1e17f269e..723df09cd 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pgadmin/PgAdminUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pgadmin/PgAdminUrlUpdater.java @@ -68,12 +68,12 @@ protected void addVersion(UrlVersion urlVersion) { @Override public String getCpeVendor() { - return "pgadmin-org"; + return "pgadmin"; } @Override public String getCpeProduct() { - return "pgadmin"; + return "pgadmin_4"; } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pycharm/PycharmUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pycharm/PycharmUrlUpdater.java index afe32ce40..27a2dd8c7 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pycharm/PycharmUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/pycharm/PycharmUrlUpdater.java @@ -34,6 +34,13 @@ protected IntellijJsonObject getJsonObjectFromResponse(String response, String e return jsonObjects[EDITIONS.indexOf(edition)]; } + + @Override + protected String doGetVersionUrl() { + + return getVersionBaseUrl() + "/" + JSON_URL; + } + @Override public String getCpeVendor() { return "jetbrains"; @@ -43,10 +50,4 @@ public String getCpeVendor() { public String getCpeProduct() { return "pycharm"; } - - @Override - protected String doGetVersionUrl() { - - return getVersionBaseUrl() + "/" + JSON_URL; - } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdater.java index d04756b95..c31374918 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/python/PythonUrlUpdater.java @@ -73,15 +73,6 @@ protected String doGetVersionUrl() { return getVersionBaseUrl() + "/" + VERSION_FILENAME; } - @Override - public String getCpeVendor() { - return "python"; - } - - @Override - public String getCpeProduct() { - return "python"; - } @Override protected Class getJsonObjectType() { @@ -103,4 +94,13 @@ protected Collection getVersionItems(PythonJsonObject jsonObject) return jsonObject.getReleases(); } + @Override + public String getCpeVendor() { + return "python"; + } + + @Override + public String getCpeProduct() { + return "python"; + } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/quarkus/QuarkusUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/quarkus/QuarkusUrlUpdater.java index a3439d461..8c8399a4c 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/quarkus/QuarkusUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/quarkus/QuarkusUrlUpdater.java @@ -42,13 +42,11 @@ protected void addVersion(UrlVersion urlVersion) { @Override public String getCpeVendor() { - return "quarkus"; } @Override public String getCpeProduct() { - return "quarkus"; } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/sonar/SonarUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/sonar/SonarUrlUpdater.java index 38231dd8b..a8e15cb5f 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/sonar/SonarUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/sonar/SonarUrlUpdater.java @@ -45,6 +45,6 @@ public String getCpeVendor() { @Override public String getCpeProduct() { - return "sonar"; + return "sonarqube"; } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/uv/UvUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/uv/UvUrlUpdater.java index b0b86193f..a6031b9ed 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/uv/UvUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/uv/UvUrlUpdater.java @@ -1,6 +1,7 @@ package com.devonfw.tools.ide.url.tool.uv; import com.devonfw.tools.ide.url.model.folder.UrlVersion; +import com.devonfw.tools.ide.url.updater.AbstractUrlUpdater; import com.devonfw.tools.ide.url.updater.GithubUrlTagUpdater; import com.devonfw.tools.ide.version.VersionIdentifier; @@ -40,7 +41,6 @@ public String mapVersion(String version) { @Override protected void addVersion(UrlVersion urlVersion) { - VersionIdentifier vid = urlVersion.getVersionIdentifier(); String baseUrl = getDownloadBaseUrl() + "/" + getGithubOrganization() + "/" + getGithubRepository() + "/releases/download/${version}/uv-"; doAddVersion(urlVersion, baseUrl + "x86_64-pc-windows-msvc.zip", WINDOWS, X64); @@ -53,7 +53,7 @@ protected void addVersion(UrlVersion urlVersion) { @Override public String getCpeVendor() { - return "astral-sh"; + return "astral"; } @Override @@ -61,4 +61,12 @@ public String getCpeProduct() { return "uv"; } + @Override + protected void initCpe(AbstractUrlUpdater.CpeRegistry cpe) { + + cpe.addVendor("astral") + .addVendorInfix("astral-sh") + .addProduct("uv"); + } + } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/vscode/VsCodeUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/vscode/VsCodeUrlUpdater.java index 994d9c05f..ec3bf00d7 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/vscode/VsCodeUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/tool/vscode/VsCodeUrlUpdater.java @@ -52,7 +52,7 @@ public String getCpeVendor() { @Override public String getCpeProduct() { - return "vscode"; + return "visual_studio_code"; } } diff --git a/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java index b072fd29d..7183bc287 100644 --- a/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java +++ b/url-updater/src/main/java/com/devonfw/tools/ide/url/updater/AbstractUrlUpdater.java @@ -156,6 +156,207 @@ public String getCpeEdition() { return getTool(); } + /** + * Configures the CPE aliases used by this updater. The default implementation keeps the existing behavior and registers the current + * {@link #getCpeVendor() vendor} and {@link #getCpeProduct() product} as exact matches. + * + * @param cpe the registry to configure. + */ + protected void initCpe(CpeRegistry cpe) { + + cpe.addVendor(getCpeVendor()).addProduct(getCpeProduct()); + } + + /** + * @return the configured CPE registry for this updater. + */ + public final CpeRegistry getCpeRegistry() { + + CpeRegistry cpe = new CpeRegistry(); + initCpe(cpe); + cpe.validate(); + return cpe; + } + + /** + * Checks if the given vendor/product combination matches this updater's configured CPE aliases. + * + * @param vendor the CPE vendor. + * @param product the CPE product. + * @return {@code true} if the CPE matches, {@code false} otherwise. + */ + public final boolean matchesCpe(String vendor, String product) { + + return getCpeRegistry().matches(vendor, product); + } + + /** + * Registry for CPE aliases of an updater. + */ + public static final class CpeRegistry { + + private final List vendors = new ArrayList<>(); + + private final List products = new ArrayList<>(); + + /** + * Adds an exact vendor match. + * + * @param vendor the vendor value. + * @return this registry. + */ + public CpeRegistry addVendor(String vendor) { + + addValue(this.vendors, vendor, false); + return this; + } + + /** + * Adds an infix vendor match. + * + * @param vendor the vendor infix. + * @return this registry. + */ + public CpeRegistry addVendorInfix(String vendor) { + + addValue(this.vendors, vendor, true); + return this; + } + + /** + * Adds an exact product match. + * + * @param product the product value. + * @return this registry. + */ + public CpeRegistry addProduct(String product) { + + addValue(this.products, product, false); + return this; + } + + /** + * Adds an infix product match. + * + * @param product the product infix. + * @return this registry. + */ + public CpeRegistry addProductInfix(String product) { + + addValue(this.products, product, true); + return this; + } + + /** + * @return the primary vendor, i.e. the first configured vendor alias. + */ + public String getPrimaryVendor() { + + return getPrimaryValue(this.vendors, "vendor"); + } + + /** + * @return the primary product, i.e. the first configured product alias. + */ + public String getPrimaryProduct() { + + return getPrimaryValue(this.products, "product"); + } + + /** + * @param vendor the vendor to check. + * @param product the product to check. + * @return {@code true} if both values match the configured aliases. + */ + public boolean matches(String vendor, String product) { + + return matches(vendor, this.vendors) && matches(product, this.products); + } + + /** + * Validates that at least one vendor and one product have been configured. + */ + public void validate() { + + if (this.vendors.isEmpty()) { + throw new IllegalStateException("No CPE vendor configured. Add at least one vendor via initCpe(...)."); + } + if (this.products.isEmpty()) { + throw new IllegalStateException("No CPE product configured. Add at least one product via initCpe(...)."); + } + } + + private static void addValue(List values, String value, boolean infix) { + + String normalized = normalizeCpeValue(value); + if (normalized.isEmpty()) { + throw new IllegalArgumentException("CPE value must not be empty."); + } + values.add(new CpeValue(normalized, infix)); + } + + private CpeRegistry() { + super(); + } + + private static String getPrimaryValue(List values, String type) { + + if (values.isEmpty()) { + throw new IllegalStateException("No CPE " + type + " configured."); + } + return values.getFirst().value(); + } + + private static boolean matches(String value, List values) { + + if (value == null) { + return false; + } + String normalized = normalizeCpeValue(value); + for (CpeValue candidate : values) { + if (candidate.matches(normalized)) { + return true; + } + } + return false; + } + } + + /** + * Single configured CPE value. + */ + private static final class CpeValue { + + private final String value; + + private final boolean infix; + + private CpeValue(String value, boolean infix) { + + this.value = value; + this.infix = infix; + } + + private String value() { + + return this.value; + } + + private boolean matches(String actualValue) { + + if (this.infix) { + return actualValue.contains(this.value); + } + return actualValue.equals(this.value); + } + } + + private static String normalizeCpeValue(String value) { + + Objects.requireNonNull(value, "CPE value must not be null."); + return value.trim().toLowerCase(Locale.ROOT); + } + /** * Retrieves the response body from a given URL. *