mirror of
https://github.com/pcvolkmer/onkostar-plugin-dnpm.git
synced 2025-07-02 09:12:54 +00:00
Issue #19: Integration des ATC-Codes-Plugins in dieses Plugin
closes #19
This commit is contained in:
24
README.md
24
README.md
@ -1,5 +1,9 @@
|
|||||||
# Onkostar-Plugin zur Verwendung mit der DNPM-Formularsammlung
|
# Onkostar-Plugin zur Verwendung mit der DNPM-Formularsammlung
|
||||||
|
|
||||||
|
## ATC-Codes
|
||||||
|
|
||||||
|
Dieses Plugin integriert das ATC-Codes-Plugin vollständig. Dieses kann daher nicht zusätzlich in Onkostar installiert werden.
|
||||||
|
|
||||||
## Consent
|
## Consent
|
||||||
|
|
||||||
Das Plugin ist auf die Übernahme des DNPM-Consents ausgelegt. Hierzu muss die Einstellung `consentform` festgelegt werden.
|
Das Plugin ist auf die Übernahme des DNPM-Consents ausgelegt. Hierzu muss die Einstellung `consentform` festgelegt werden.
|
||||||
@ -78,5 +82,25 @@ In der Klasse `DefaultSystemtherapieService` wird zur Laufzeit der erforderliche
|
|||||||
|
|
||||||
An dieser Stelle kann auch eine eigene Implementierung - eine neue Klasse, die das Interface `ProzedurToProzedurwerteMapper` implementiert - integriert werden, indem das zu verwendende Formular (Formularname) je `SID` und die zu verwendende Mapping-Klasse für den Formularnamen angegeben wird.
|
An dieser Stelle kann auch eine eigene Implementierung - eine neue Klasse, die das Interface `ProzedurToProzedurwerteMapper` implementiert - integriert werden, indem das zu verwendende Formular (Formularname) je `SID` und die zu verwendende Mapping-Klasse für den Formularnamen angegeben wird.
|
||||||
|
|
||||||
|
## Bauen des Plugins
|
||||||
|
|
||||||
|
Für das Bauen des Plugins ist zwingend JDK in Version 11 erforderlich.
|
||||||
|
Spätere Versionen des JDK beinhalten einige Methoden nicht mehr, die von Onkostar und dort benutzten Libraries verwendet
|
||||||
|
werden.
|
||||||
|
|
||||||
|
Voraussetzung ist das Kopieren der Datei `onkostar-api-2.11.1.1.jar` (oder neuer) in das Projektverzeichnis `libs`.
|
||||||
|
|
||||||
|
Weiterhin verwendet dieses Plugin das [ATC-Codes-Plugin](https://github.com/CCC-MF/onkostar-plugin-atccodes).
|
||||||
|
Die zugehörige JAR-Datei muss ebenfalls in das Projektverzeichnis `libs` kopiert werden. Aktuell wird Version 0.5.0 verwendet.
|
||||||
|
|
||||||
|
**_Hinweis_**: Bei Verwendung einer neueren Version der Onkostar-API oder des ATC-Codes-Plugins
|
||||||
|
muss die Datei `pom.xml` entsprechend angepasst werden.
|
||||||
|
|
||||||
|
Danach Ausführen des Befehls:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
./mvnw package
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
7
pom.xml
7
pom.xml
@ -29,9 +29,9 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>de.ukw</groupId>
|
<groupId>de.ukw</groupId>
|
||||||
<artifactId>onkostar-plugin-atccodes</artifactId>
|
<artifactId>onkostar-plugin-atccodes</artifactId>
|
||||||
<version>0.4.0</version>
|
<version>0.5.0</version>
|
||||||
<scope>system</scope>
|
<scope>system</scope>
|
||||||
<systemPath>${project.basedir}/libs/onkostar-plugin-atccodes-0.4.0.jar</systemPath>
|
<systemPath>${project.basedir}/libs/onkostar-plugin-atccodes-0.5.0.jar</systemPath>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Hibernate -->
|
<!-- Hibernate -->
|
||||||
@ -159,7 +159,8 @@
|
|||||||
${project.build.directory}/classes/
|
${project.build.directory}/classes/
|
||||||
</outputDirectory>
|
</outputDirectory>
|
||||||
<includes>
|
<includes>
|
||||||
de/ukw/ccc/**/*.class
|
de/ukw/ccc/**/*.class,
|
||||||
|
de/ukw/ccc/**/*.js
|
||||||
</includes>
|
</includes>
|
||||||
<excludeTransitive>true</excludeTransitive>
|
<excludeTransitive>true</excludeTransitive>
|
||||||
<includeScope>system</includeScope>
|
<includeScope>system</includeScope>
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
package ATCCodes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common Agent Code definition
|
|
||||||
*
|
|
||||||
* @author Paul-Christian Volkmer
|
|
||||||
* @since 0.1.0
|
|
||||||
*/
|
|
||||||
public interface AgentCode extends Comparable<AgentCode> {
|
|
||||||
String getCode();
|
|
||||||
|
|
||||||
String getName();
|
|
||||||
|
|
||||||
CodeSystem getSystem();
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
package ATCCodes;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ATC-Code as used in WHO XML file
|
|
||||||
*
|
|
||||||
* @author Paul-Christian Volkmer
|
|
||||||
* @since 0.1.0
|
|
||||||
*/
|
|
||||||
public class AtcCode implements AgentCode {
|
|
||||||
|
|
||||||
private final String code;
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
public AtcCode(String code, String name) {
|
|
||||||
this.code = code;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CodeSystem getSystem() {
|
|
||||||
return CodeSystem.ATC;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(final AgentCode agentCode) {
|
|
||||||
return this.name.toLowerCase().compareTo(agentCode.getName().toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(final Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
AgentCode otherAgentCode = (AgentCode) o;
|
|
||||||
return Objects.equals(code.toLowerCase(), otherAgentCode.getCode().toLowerCase())
|
|
||||||
&& Objects.equals(name.toLowerCase(), otherAgentCode.getName().toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(code.toLowerCase(), name.toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prüft auf gültiges ATCCode-Schema ab Ebene 2
|
|
||||||
* @param code Der zu prüfende Code
|
|
||||||
* @return Gibt <code>true</code> zurück, wenn der angegebene Code dem ATCCode-Schema entspricht
|
|
||||||
*/
|
|
||||||
public static boolean isAtcCode(String code) {
|
|
||||||
return null != code
|
|
||||||
&& ! code.isBlank()
|
|
||||||
&& code.matches("[ABCDGHJLMNPRSV][0-2][1-9]([A-Z]([A-Z]([0-9]{2})?)?)?");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,110 +0,0 @@
|
|||||||
package ATCCodes;
|
|
||||||
|
|
||||||
import de.itc.onkostar.api.Disease;
|
|
||||||
import de.itc.onkostar.api.Procedure;
|
|
||||||
import de.itc.onkostar.api.analysis.AnalyzerRequirement;
|
|
||||||
import de.itc.onkostar.api.analysis.IProcedureAnalyzer;
|
|
||||||
import de.itc.onkostar.api.analysis.OnkostarPluginType;
|
|
||||||
import ATCCodes.services.AgentCodeService;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Plugin implementation
|
|
||||||
* Provides methods exposed to Onkostar
|
|
||||||
*
|
|
||||||
* @author Paul-Christian Volkmer
|
|
||||||
* @since 0.1.0
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class AtcCodesPlugin implements IProcedureAnalyzer {
|
|
||||||
|
|
||||||
private final List<AgentCodeService> agentCodeServices;
|
|
||||||
|
|
||||||
public AtcCodesPlugin(List<AgentCodeService> agentCodeServices) {
|
|
||||||
this.agentCodeServices = agentCodeServices;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OnkostarPluginType getType() {
|
|
||||||
return OnkostarPluginType.BACKEND_SERVICE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getVersion() {
|
|
||||||
return "0.4.0";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "ATC-Codes und Substanzen";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDescription() {
|
|
||||||
return "ATC-Codes und Substanzen";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSynchronous() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AnalyzerRequirement getRequirement() {
|
|
||||||
return AnalyzerRequirement.PROCEDURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRelevantForDeletedProcedure() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRelevantForAnalyzer(final Procedure procedure, final Disease disease) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void analyze(final Procedure procedure, final Disease disease) {
|
|
||||||
// Nothing to do - should never be called
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return list with ATC codes and agents.
|
|
||||||
* Usage in script:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* executePluginMethod(
|
|
||||||
* 'AtcCodesPlugin',
|
|
||||||
* 'query',
|
|
||||||
* { q: '', size: 10 },
|
|
||||||
* function (result) {console.log(result);},
|
|
||||||
* false
|
|
||||||
* );
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @param input The data Map
|
|
||||||
* @return The result list filtered by input
|
|
||||||
*/
|
|
||||||
public List<AgentCode> query(final Map<String, Object> input) {
|
|
||||||
String query = "";
|
|
||||||
if (null != input.get("q")) {
|
|
||||||
query = input.get("q").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
int size = Integer.parseInt(input.get("size").toString());
|
|
||||||
if (size == 0) {
|
|
||||||
size = 10;
|
|
||||||
}
|
|
||||||
var result = new ArrayList<AgentCode>();
|
|
||||||
for (var agentCodeService : this.agentCodeServices) {
|
|
||||||
result.addAll(agentCodeService.findAgentCodes(query, size));
|
|
||||||
}
|
|
||||||
return result.stream().distinct().sorted().collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package ATCCodes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This enum provides usable coding systems
|
|
||||||
*
|
|
||||||
* @author Paul-Christion Volkmer
|
|
||||||
* @since 0.1.0
|
|
||||||
*/
|
|
||||||
public enum CodeSystem {
|
|
||||||
ATC,
|
|
||||||
UNREGISTERED
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
package ATCCodes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exception to be thrown if any file parsing error occurs
|
|
||||||
*
|
|
||||||
* @author Paul-Christian Volkmer
|
|
||||||
* @since 0.1.0
|
|
||||||
*/
|
|
||||||
public class FileParsingException extends RuntimeException {
|
|
||||||
|
|
||||||
public FileParsingException(final String msg) {
|
|
||||||
super(msg);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
package ATCCodes;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregistered code as used in Onkostar database
|
|
||||||
*
|
|
||||||
* @author Paul-Christian Volkmer
|
|
||||||
* @since 0.1.0
|
|
||||||
*/
|
|
||||||
public class UnregisteredCode implements AgentCode {
|
|
||||||
|
|
||||||
private final String code;
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
public UnregisteredCode(String code, String name) {
|
|
||||||
this.code = code;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CodeSystem getSystem() {
|
|
||||||
return CodeSystem.UNREGISTERED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(final AgentCode agentCode) {
|
|
||||||
return this.name.toLowerCase().compareTo(agentCode.getName().toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(final Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
AgentCode otherAgentCode = (AgentCode) o;
|
|
||||||
return Objects.equals(code.toLowerCase(), otherAgentCode.getCode().toLowerCase())
|
|
||||||
&& Objects.equals(name.toLowerCase(), otherAgentCode.getName().toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(code.toLowerCase(), name.toLowerCase());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package ATCCodes.services;
|
|
||||||
|
|
||||||
import ATCCodes.AgentCode;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common interface for agent code services
|
|
||||||
*
|
|
||||||
* @author Paul-Christian Volkmer
|
|
||||||
*/
|
|
||||||
public interface AgentCodeService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries source for agents with name and code starting with query string.
|
|
||||||
* If size is zero, all available results will be returned.
|
|
||||||
*
|
|
||||||
* @param query The query string
|
|
||||||
* @param size Maximal amount of responses
|
|
||||||
* @return A list with agent codes
|
|
||||||
*/
|
|
||||||
List<AgentCode> findAgentCodes(String query, int size);
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
package ATCCodes.services;
|
|
||||||
|
|
||||||
import ATCCodes.AgentCode;
|
|
||||||
import ATCCodes.AtcCode;
|
|
||||||
import ATCCodes.FileParsingException;
|
|
||||||
import org.apache.commons.csv.CSVFormat;
|
|
||||||
import org.springframework.core.io.ResourceLoader;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service to query for agent codes based on WHO xml file
|
|
||||||
*
|
|
||||||
* @author Paul-Christian Volkmer
|
|
||||||
* @since 0.1.0
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class CsvAtcCodeService extends FileBasedAgentCodeService {
|
|
||||||
|
|
||||||
public CsvAtcCodeService(final ResourceLoader resourceLoader) {
|
|
||||||
super(resourceLoader);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected List<AgentCode> parseFile(final ResourceLoader resourceLoader) {
|
|
||||||
var result = new ArrayList<AgentCode>();
|
|
||||||
var filename = getFilePath("atc.csv");
|
|
||||||
try {
|
|
||||||
var inputStream = resourceLoader.getResource(filename).getInputStream();
|
|
||||||
var parser = CSVFormat.RFC4180
|
|
||||||
.withHeader()
|
|
||||||
.withSkipHeaderRecord()
|
|
||||||
.parse(new InputStreamReader(inputStream));
|
|
||||||
for (var row : parser) {
|
|
||||||
if (!row.isMapped("CODE") || !row.isMapped("NAME")) {
|
|
||||||
throw new FileParsingException("No CSV column 'CODE' or 'NAME' found");
|
|
||||||
}
|
|
||||||
result.add(new AtcCode(row.get("CODE"), row.get("NAME")));
|
|
||||||
}
|
|
||||||
logger.info("Found CSV file for ATC-Codes.");
|
|
||||||
return result;
|
|
||||||
} catch (IOException | FileParsingException e) {
|
|
||||||
logger.warn("Error reading CSV file '{}' for ATC-Codes. Proceeding without data", filename);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
package ATCCodes.services;
|
|
||||||
|
|
||||||
import ATCCodes.AgentCode;
|
|
||||||
import org.apache.commons.lang.SystemUtils;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.core.io.ResourceLoader;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract {@link AgentCodeService} for use with files that will load information into memory
|
|
||||||
*
|
|
||||||
* @author Paul-Christian Volkmer
|
|
||||||
* @since 0.1.0
|
|
||||||
*/
|
|
||||||
public abstract class FileBasedAgentCodeService implements AgentCodeService {
|
|
||||||
|
|
||||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
||||||
|
|
||||||
protected final List<AgentCode> codeList = new ArrayList<>();
|
|
||||||
|
|
||||||
FileBasedAgentCodeService(final ResourceLoader resourceLoader) {
|
|
||||||
this.codeList.addAll(parseFile(resourceLoader));
|
|
||||||
}
|
|
||||||
|
|
||||||
static String getFilePath(final String filename) {
|
|
||||||
String pluginPathPart = "onkostar/files/onkostar/plugins/onkostar-plugin-atccodes";
|
|
||||||
|
|
||||||
if (SystemUtils.IS_OS_WINDOWS) {
|
|
||||||
return String.format("file:///c:/%s/%s", pluginPathPart, filename);
|
|
||||||
} else if (SystemUtils.IS_OS_LINUX) {
|
|
||||||
return String.format("file:///opt/%s/%s", pluginPathPart, filename);
|
|
||||||
}
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract List<AgentCode> parseFile(final ResourceLoader resourceLoader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries source for agents code starting with or name containing query string.
|
|
||||||
* If size is zero, all available results will be returned.
|
|
||||||
*
|
|
||||||
* @param query The query string
|
|
||||||
* @param size Maximal amount of responses
|
|
||||||
* @return A list with agent codes
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<AgentCode> findAgentCodes(final String query, final int size) {
|
|
||||||
var resultStream = this.codeList.stream().filter(agentCode ->
|
|
||||||
agentCode.getCode().toLowerCase().startsWith(query.toLowerCase())
|
|
||||||
|| agentCode.getName().toLowerCase().contains(query.toLowerCase())
|
|
||||||
);
|
|
||||||
|
|
||||||
if (size > 0) {
|
|
||||||
return resultStream.limit(size).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
return resultStream.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
package ATCCodes.services;
|
|
||||||
|
|
||||||
import ATCCodes.AgentCode;
|
|
||||||
import ATCCodes.AtcCode;
|
|
||||||
import ATCCodes.UnregisteredCode;
|
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of {@link AgentCodeService} that uses database to query for unregistered agents
|
|
||||||
*
|
|
||||||
* @author Paul-Christian Volkmer
|
|
||||||
* @since 0.1.0
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class OnkostarAgentCodeService implements AgentCodeService {
|
|
||||||
|
|
||||||
private final JdbcTemplate jdbcTemplate;
|
|
||||||
|
|
||||||
public OnkostarAgentCodeService(final DataSource dataSource) {
|
|
||||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries source for agents code starting with or name containing query string.
|
|
||||||
* If size is zero, all available results will be returned.
|
|
||||||
*
|
|
||||||
* @param query The query string
|
|
||||||
* @param size Maximal amount of responses
|
|
||||||
* @return A list with agent codes
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<AgentCode> findAgentCodes(final String query, final int size) {
|
|
||||||
var sql = "SELECT code, shortdesc\n" +
|
|
||||||
" FROM property_catalogue\n" +
|
|
||||||
" JOIN property_catalogue_version ON (property_catalogue_version.datacatalog_id = property_catalogue.id)\n" +
|
|
||||||
" JOIN property_catalogue_version_entry p ON (p.property_version_id = property_catalogue_version.id)\n" +
|
|
||||||
" WHERE name = 'OS.Substanzen'\n" +
|
|
||||||
" AND (LOWER(code) LIKE ? OR LOWER(shortdesc) LIKE ? OR LOWER(synonyms) LIKE ?)";
|
|
||||||
|
|
||||||
if (size > 0) {
|
|
||||||
sql = sql + " LIMIT " + size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return jdbcTemplate.query(
|
|
||||||
sql,
|
|
||||||
new Object[]{query + "%", "%" + query + "%", "%" + query + "%"},
|
|
||||||
(resultSet, i) -> {
|
|
||||||
var code = resultSet.getString("code");
|
|
||||||
var shortdesc = resultSet.getString("shortdesc");
|
|
||||||
if (AtcCode.isAtcCode(code)) {
|
|
||||||
return new AtcCode(code, shortdesc);
|
|
||||||
}
|
|
||||||
return new UnregisteredCode(code, shortdesc);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
package ATCCodes.services;
|
|
||||||
|
|
||||||
import ATCCodes.AgentCode;
|
|
||||||
import ATCCodes.AtcCode;
|
|
||||||
import ATCCodes.FileParsingException;
|
|
||||||
import org.springframework.core.io.ResourceLoader;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import javax.xml.bind.JAXBContext;
|
|
||||||
import javax.xml.bind.JAXBException;
|
|
||||||
import javax.xml.bind.annotation.XmlAttribute;
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Service to query for agent codes based on WHO xml file
|
|
||||||
*
|
|
||||||
* @author Paul-Christian Volkmer
|
|
||||||
* @since 0.1.0
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class WhoAtcCodeService extends FileBasedAgentCodeService {
|
|
||||||
|
|
||||||
public WhoAtcCodeService(final ResourceLoader resourceLoader) {
|
|
||||||
super(resourceLoader);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected List<AgentCode> parseFile(final ResourceLoader resourceLoader) {
|
|
||||||
var result = new ArrayList<AgentCode>();
|
|
||||||
var filename = getFilePath("atc.xml");
|
|
||||||
try {
|
|
||||||
var inputStream = resourceLoader.getResource(filename).getInputStream();
|
|
||||||
var context = JAXBContext.newInstance(XmlResource.class);
|
|
||||||
var xmlResource = (XmlResource) context.createUnmarshaller().unmarshal(inputStream);
|
|
||||||
for (var row : xmlResource.data.rows) {
|
|
||||||
if (null == row.code || null == row.name) {
|
|
||||||
throw new FileParsingException("No XML attribute 'ATCCode' or 'Name' found");
|
|
||||||
}
|
|
||||||
result.add(new AtcCode(row.code, row.name));
|
|
||||||
}
|
|
||||||
logger.info("Found WHO XML file for ATC-Codes.");
|
|
||||||
return result;
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.warn("Error reading WHO XML file '{}' for ATC-Codes. Proceeding without inserting data", filename);
|
|
||||||
} catch (JAXBException | FileParsingException e) {
|
|
||||||
logger.warn("Error parsing WHO XML file '{}' for ATC-Codes. Proceeding without inserting data", filename);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@XmlRootElement(name = "xml")
|
|
||||||
private static class XmlResource {
|
|
||||||
@XmlElement(name = "data", namespace = "urn:schemas-microsoft-com:rowset")
|
|
||||||
public XmlData data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class XmlData {
|
|
||||||
@XmlElement(name = "row", namespace = "#RowsetSchema")
|
|
||||||
public List<XmlRow> rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class XmlRow {
|
|
||||||
@XmlAttribute(name = "ATCCode")
|
|
||||||
public String code;
|
|
||||||
|
|
||||||
@XmlAttribute(name = "Name")
|
|
||||||
public String name;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +1,10 @@
|
|||||||
package DNPM.services.systemtherapie;
|
package DNPM.services.systemtherapie;
|
||||||
|
|
||||||
import ATCCodes.AtcCode;
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import de.itc.onkostar.api.Item;
|
import de.itc.onkostar.api.Item;
|
||||||
import de.itc.onkostar.api.Procedure;
|
import de.itc.onkostar.api.Procedure;
|
||||||
|
import de.ukw.ccc.onkostar.atccodes.AtcCode;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -26,4 +26,5 @@
|
|||||||
<context:component-scan base-package="DNPM.config" />
|
<context:component-scan base-package="DNPM.config" />
|
||||||
|
|
||||||
<mvc:resources mapping="/app/lib/umr/**" location="classpath:/app/lib/umr/" />
|
<mvc:resources mapping="/app/lib/umr/**" location="classpath:/app/lib/umr/" />
|
||||||
|
<mvc:resources mapping="/app/plugins/atccodes/**" location="classpath:/de/ukw/ccc/onkostar/atccodes/" />
|
||||||
</beans>
|
</beans>
|
@ -1,28 +0,0 @@
|
|||||||
package ATCCodes;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
class AtcCodeTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testShouldDetectAtcCodeScheme() {
|
|
||||||
assertTrue(AtcCode.isAtcCode("L01"));
|
|
||||||
assertTrue(AtcCode.isAtcCode("L01A"));
|
|
||||||
assertTrue(AtcCode.isAtcCode("L01AA"));
|
|
||||||
assertTrue(AtcCode.isAtcCode("L01AA01"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testShouldDetectInvalidAtcCodeScheme() {
|
|
||||||
assertFalse(AtcCode.isAtcCode(null));
|
|
||||||
assertFalse(AtcCode.isAtcCode(" "));
|
|
||||||
assertFalse(AtcCode.isAtcCode("irgendwas"));
|
|
||||||
assertFalse(AtcCode.isAtcCode("L00AA"));
|
|
||||||
assertFalse(AtcCode.isAtcCode("Z01AA"));
|
|
||||||
assertFalse(AtcCode.isAtcCode("L01AA0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Reference in New Issue
Block a user