From bfeebbab67eeda34acf8ceef6bf2cb7c583f1f4a Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer Date: Fri, 13 Feb 2026 12:57:24 +0100 Subject: feat: add methods to collect lastest ATC codes (#251) --- .github/workflows/ci.yml | 8 +- pom.xml | 12 ++- .../oshelper/atc/services/AgentCodeService.java | 63 ++++++++++++++++ .../dnpm/oshelper/atc/AgentCodeServiceTest.java | 88 ++++++++++++++++++++++ 4 files changed, 165 insertions(+), 6 deletions(-) create mode 100644 src/test/java/dev/dnpm/oshelper/atc/AgentCodeServiceTest.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eaee101..eaa49bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,8 +23,8 @@ jobs: - name: Fetch Onkostar-API run: | curl -L --user dnpm:${{ secrets.PACKAGE_TOKEN }} \ - https://git.dnpm.dev/api/packages/Plugin-JF-Onkostar/generic/onkostar-api/2.14.2/onkostar-api-2.14.2.jar \ - --output ${{ github.workspace }}/libs/onkostar-api-2.14.2.jar + https://git.dnpm.dev/api/packages/Plugin-JF-Onkostar/generic/onkostar-api/2.14.0/onkostar-api-2.14.0.jar \ + --output ${{ github.workspace }}/libs/onkostar-api-2.14.0.jar - name: Execute tests run: mvn --batch-mode verify build: @@ -45,8 +45,8 @@ jobs: - name: Fetch Onkostar-API run: | curl -L --user dnpm:${{ secrets.PACKAGE_TOKEN }} \ - https://git.dnpm.dev/api/packages/Plugin-JF-Onkostar/generic/onkostar-api/2.14.2/onkostar-api-2.14.2.jar \ - --output ${{ github.workspace }}/libs/onkostar-api-2.14.2.jar + https://git.dnpm.dev/api/packages/Plugin-JF-Onkostar/generic/onkostar-api/2.14.0/onkostar-api-2.14.0.jar \ + --output ${{ github.workspace }}/libs/onkostar-api-2.14.0.jar - name: Maven package build run: mvn --batch-mode package - name: Release diff --git a/pom.xml b/pom.xml index a48686f..d857c01 100644 --- a/pom.xml +++ b/pom.xml @@ -25,9 +25,17 @@ de.itc onkostar-parent - 2.14.2 + 2.14.0 system - ${project.basedir}/libs/onkostar-api-2.14.2.jar + ${project.basedir}/libs/onkostar-api-2.14.0.jar + + + + + org.jspecify + jspecify + 1.0.0 + compile diff --git a/src/main/java/dev/dnpm/oshelper/atc/services/AgentCodeService.java b/src/main/java/dev/dnpm/oshelper/atc/services/AgentCodeService.java index 5d215a7..16a03f7 100644 --- a/src/main/java/dev/dnpm/oshelper/atc/services/AgentCodeService.java +++ b/src/main/java/dev/dnpm/oshelper/atc/services/AgentCodeService.java @@ -26,8 +26,15 @@ package dev.dnpm.oshelper.atc.services; import dev.dnpm.oshelper.atc.AgentCode; +import org.jspecify.annotations.NullMarked; +import java.util.Comparator; import java.util.List; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.groupingBy; /** * Common interface for agent code services @@ -37,6 +44,62 @@ import java.util.List; */ public interface AgentCodeService { + /** + * Filters the provided list of AgentCodes to include only the latest available versions + * for each unique code name and, if required, code. + * If the input list is empty or null, an empty list will be returned. + * + * @param agentCodes A list of {@link AgentCode} objects to be filtered. Each object in the list + * should contain information about the agent's code, name, system, and version. + * @param classifier A function that returns a string value to be used as a key for grouping agent codes. + * @return A list of {@link AgentCode} objects representing the latest available versions of unique agent codes. + * If no valid inputs are provided, an empty list is returned. + */ + @NullMarked + static List latestAgentCodeVersions(List agentCodes, Function classifier) { + return latestAvailable(agentCodes, classifier); + } + + /** + * Function that extracts the name of an {@link AgentCode} object. + * This function is used as a classifier for grouping agent codes by their name. + */ + Function byCodeOnly = AgentCode::getName; + + /** + * Function that extracts the name and code of an {@link AgentCode} object. + * This function is used as a classifier for grouping agent codes by their name and code. + */ + Function byNameAndCode = (agentCode -> + String.format("%s_%s", agentCode.getCode(), agentCode.getName()) + ); + + + @NullMarked + private static List latestAvailable( + List agentCodes, + Function classifier + ) { + return agentCodes.stream() + .collect(groupingBy(classifier)).values().stream() + .map(list -> + list.stream() + .sorted(Comparator.comparing(AgentCode::getCode)) + .max((ac1, ac2) -> { + if (null == ac1.getVersion()) { + return -1; + } else if (null == ac2.getVersion()) { + return 1; + } + return ac1.getVersion().compareTo(ac2.getVersion()); + }) + .orElse(null) + ) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + } + /** * Queries source for agents with name and code starting with query string. * If size is zero, all available results will be returned. diff --git a/src/test/java/dev/dnpm/oshelper/atc/AgentCodeServiceTest.java b/src/test/java/dev/dnpm/oshelper/atc/AgentCodeServiceTest.java new file mode 100644 index 0000000..5761d8b --- /dev/null +++ b/src/test/java/dev/dnpm/oshelper/atc/AgentCodeServiceTest.java @@ -0,0 +1,88 @@ +/* + * This file is part of onkostar-plugin-dnpm + * + * Copyright (c) 2026 the original author or authors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package dev.dnpm.oshelper.atc; + +import dev.dnpm.oshelper.atc.services.AgentCodeService; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class AgentCodeServiceTest { + + @Test + void shouldReturnLatestAvailableAgentCodeVersion() { + var testAgentCodes = List.of( + new AtcCode("A01AD05", "Acetylsalicylsäure"), + new AtcCode("A01AD05", "Acetylsalicylsäure", "2025"), + new AtcCode("A01AD05", "Acetylsalicylsäure", "2026"), + new UnregisteredCode("A01AD05", "Acetylsalicylsäure"), + new UnregisteredCode("", "Acetylsalicylsäure") + ); + + var actual = AgentCodeService.latestAgentCodeVersions(testAgentCodes, AgentCodeService.byNameAndCode); + + assertThat(actual).containsAll( + List.of( + new AtcCode("A01AD05", "Acetylsalicylsäure", "2026"), + new UnregisteredCode("", "Acetylsalicylsäure") + ) + ); + } + + @Test + void shouldReturnLatestAvailableAgentCodeVersionByNameOnly() { + var testAgentCodes = List.of( + new AtcCode("A01AD05", "Acetylsalicylsäure"), + new AtcCode("A01AD05", "Acetylsalicylsäure", "2025"), + new AtcCode("A01AD05", "Acetylsalicylsäure", "2026"), + new UnregisteredCode("A01AD05", "Acetylsalicylsäure"), + new UnregisteredCode("", "Acetylsalicylsäure") + ); + + var actual = AgentCodeService.latestAgentCodeVersions(testAgentCodes, AgentCodeService.byCodeOnly); + + assertThat(actual).containsExactly( + new AtcCode("A01AD05", "Acetylsalicylsäure", "2026") + ); + } + + @Test + void shouldReturnLatestAvailableAgentCodeWithoutVersionVersionByNameOnly() { + var testAgentCodes = List.of( + new UnregisteredCode("A01AD05", "Acetylsalicylsäure"), + new AtcCode("A01AD05", "Acetylsalicylsäure"), + new UnregisteredCode("", "Acetylsalicylsäure") + ); + + var actual = AgentCodeService.latestAgentCodeVersions(testAgentCodes, AgentCodeService.byCodeOnly); + + assertThat(actual).containsExactly( + new AtcCode("A01AD05", "Acetylsalicylsäure") + ); + } + +} -- cgit v1.2.3