Das Laden der Daten über den Classloader hat im Gegensatz zum Laden aus dem Filesystem den großen Vorteil, dass es völlig plattformunabhängig ist. So kann der Programmcode z.B. ohne Änderungen auf z/OS laufen.
Modellierung und Produktkonfigurierung
Zugriff auf Produktinformationen zur Laufzeit
Nachdem wir die Produktdaten erfasst haben, beschäftigen wir uns nun damit, wie man zur Laufzeit (in einer Anwendung/einem Testfall) auf diese zugreift. Hierzu werden wir einen JUnit-Test schreiben, den wir im Laufe des Tutorials weiter ausbauen.
Zum Zugriff auf Produktdaten stellt Faktor-IPS das Interface „IRuntimeRepository“
bereit. Die Implementierung ClassloaderRuntimeRepository
erlaubt den Zugriff auf die mit Faktor-IPS erfassten Produktdaten und lädt die Daten über einen Classloader. Damit dies möglich ist, macht Faktor-IPS zwei Dinge:
-
Die Dateien, die die Produktinformationen enthalten, werden in den Java Sourcefolder mit dem Namen
„derived“
kopiert. Damit sind diese Dateien im Build Path des Projektes enthalten und können über den Classloader geladen werden. -
Welche Daten sich im ClassloaderRuntimeRepository befinden, ist in einem Inhaltsverzeichnis vermerkt. Dieses Inhaltsverzeichnis (Englisch: table of contents, toc) wird von Faktor-IPS ebenfalls in eine Datei generiert, die als Toc-File bezeichnet wird. Die Datei heißt standardmäßig
„faktorips-repository-toc.xml“
[13].
[13] Die Namen lassen sich in der „.ipsproject“ Datei im Abschnitt IpsObjectPath konfigurieren.
Ein ClassloaderRuntimeRepository wird über die statische create
(…)-Methode der Klasse erzeugt. Als Parameter wird der Pfad zum Toc-File übergeben. Das Toc-File wird direkt beim Erzeugen des Repositorys über Classloader.getResourceAsStream
() gelesen. Alle weiteren Daten werden erst (wiederum über den Classloader) geladen, wenn auf sie zugegriffen wird.
Einen Produktbaustein kann man über die Methode getProductComponent
(…) erhalten. Als Parameter übergibt man die RuntimeId des Bausteins. Da das Interface „IRuntimeRepository“
unabhängig vom konkreten Modell (in unserem Fall also dem Hausratmodell
) ist, muss man das Ergebnis noch auf die konkrete Produktklasse casten.
Probieren wir dies doch einmal in einem JUnit Testfall aus. Legen Sie hierzu zunächst im Projekt Hausratprodukte einen neuen Java Sourcefolder „test“ an. Am einfachsten geht dies, indem Sie im Package-Explorer
das Projekt markieren und im Kontextmenü Build Path ► New Source Folder…aufrufen.
Danach markieren Sie den neuen Sourcefolder und legen einen JUnit Testfall an, indem Sie in der Toolbar auf klicken und dann JUnit Test Case auswählen. In dem Dialog geben Sie als Namen für die Testfallklasse „TutorialTest“ ein und haken an, dass auch die setUp()
Methode generiert werden soll. Die Warnung, dass die Verwendung des Defaultpackages nicht empfohlen wird, ignorieren wir in dem Tutorial. Für unseren Test verwenden wir die JUnit 5 JUnit Jupiter
. Beim Beenden des Wizards werden wir gefragt, ob wir die JUnit Library zum Build Path des Projektes hinzufügen wollen. Klicken Sie in diesem Dialog auf OK.
Der nächste Kasten enthält den Sourcecode der Testfallklasse.
image::{images-folder}junit-wizard.jpg[]
Anstatt die Korrektheit der Produktdaten mit assert
*-Statements zu testen, geben wir sie hier mit println
auf der Konsole aus.
public class TutorialTest {
private IRuntimeRepository repository;
private HausratProdukt kompaktProdukt;
@BeforeEach
public void setUp() throws Exception {
// Repository erzeugen
repository = ClassloaderRuntimeRepository.create(
"org/faktorips/tutorial/produktdaten/internal/faktorips-repository-toc.xml");
// Referenz auf das Kompaktprodukt aus dem Repository holen
IProductComponent pc = repository
.getProductComponent("hausrat.HR-Kompakt 2019-07");
// Auf die eigenen Modellklassen casten
kompaktProdukt = (HausratProdukt) pc;
}
@Test
public void test() {
System.out.println("Produktname: " + kompaktProdukt.getProduktname());
System.out.println("Vorschlag Vs pro 1qm: "
+ kompaktProdukt.getVorschlagVersSummeProQm());
System.out.println("Default Zahlweise: "
+ kompaktProdukt.getDefaultValueZahlweise());
System.out.println("Erlaubte Zahlweisen: "
+ kompaktProdukt.getAllowedValuesForZahlweise(null));
System.out.println(
"Default Vs: " + kompaktProdukt.getDefaultValueVersSumme());
System.out.println(
"Bereich Vs: " + kompaktProdukt.getRangeForVersSumme(null));
System.out.println("Default Wohnflaeche: "
+ kompaktProdukt.getDefaultValueWohnflaeche());
System.out.println("Bereich Wohnflaeche: "
+ kompaktProdukt.getRangeForWohnflaeche(null));
}
Wenn Sie den Test nun ausführen, sollte er folgendes ausgeben:
Produktname: Hausrat Kompakt
Vorschlag Vs pro 1qm: 600.00 EUR
Default Zahlweise: 1
Erlaubte Zahlweisen: [1, 2]
Default Vs: MoneyNull
Bereich Vs: 10000.00 EUR-2000000.00 EUR
Default Wohnflaeche: null
Bereich Wohnflaeche: 0-1000
Damit haben wir einen Einblick in die Modellierung mit Faktor -IPS bekommen, haben erste, einfache Produkte angelegt und zur Laufzeit auf Produktdaten zugegriffen.
In Teil 2 werden wir in die Verwendung von Tabellen & Formeln einführen. Diese werden wir nutzen, um das Hausratmodell so zu erweitern, dass den Produkten flexibel Zusatzdeckungen durch Anwender aus der Fachabteilung hinzu konfiguriert werden können, ohne dass das Modell erweitert werden muss.