Zuletzt bearbeitet vor 2 Wochen
von Daniel Quathamer

Aufbau eines SuperX-Moduls

Version vom 3. September 2026, 09:14 Uhr von Daniel Quathamer (Diskussion | Beiträge) (→‎Gestaltung der Formulare)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

Einleitung

Dieser Artikel beschreibt den Aufbau eines Moduls in SuperX. Es wird erläutert welche Dateien ein Modul umfasst, wo sie abgelegt und wie sie aufgebaut sind.

Begriffsklärung

  • Installation: SuperX stellt eine Menge von Modulen zur Verfügung, die je nach Bedarf einzeln installiert werden können. Eine Installation ist einmal bei der Installation der HISinOne-BI notwendig.
  • Upgrade: Ein Upgrade eines Moduls ist notwendig, wenn eine Neue Version oder ein Patch vorhanden ist und die BI-Komponente technisch auf den aktuellen Stand gebracht werden soll. Ein Upgrade ist bei jeder neuen Version, jedem Release, jedem ServicePack und jedem Patch notwendig.
  • Update: Ein Update eines Moduls sorgt dafür, dass aktuelle Daten aus dem Quellsystem in die BI überführt werden. Ein Update wird jede Nacht automatisiert durchgeführt.
  • Laderoutine: Eine Laderoutine führt ein Update durch.
  • In HISinOne-BI wird ein Modul als "BI-Komponente" bezeichnet

Modul-XML-Datei

Es existiert zu jedem Modul eine zentrale Datei:

superx/WEB-INF/conf/edustore/db/module/<<modulname>>/conf/<<modulname>>.xml

Diese Datei enthält das Datenmodell. Aus ihr werden mit XSLT alle Skripte erzeugt, die für die Installation, Deinstallation, das Upgrade und die Laderoutine (Update) einer Komponente benötigt werden. Das XML-Format hat den Vorteil, dass die Skripte dynamisch für PostgreSQL und Informix erzeugt werden können, und dass die Skripte vereinheitlicht werden. Aus dieser Datei werden die Skripte erzeugt, die das Modul jeweils für Postgres und Informix installieren / updaten /aktualisieren / überprüfen und entfernen.

lightbulb.svg Die Modul-Dateien sind sehr groß und daher unübersichtlich. In Eclipse hilft die View Outline den Überblick zu behalten.

Grundsätzlich ist wichtig, dass zwischen Groß- und Kleinschreibung bei Tabellen- und Feldnamen unterschieden wird, d.h. "Gang" ist nicht gleich "gang". Außerdem sind zusätzliche Leerzeichen eine häufige Fehlerquelle.

Aufbau

<module>
	<description></description>
	<database></database>
	<install></install>
    <uninstall-step></uninstall-step>
    <upgrade></upgrade>
    <etl></etl>
    <olap-system></olap-system>
    <dbforms></dbforms>
</module>

Die Attribute des XML-tag <modul> sind wie folgt:

  • name:
  • version:
  • sachgebiet_id:
  • systeminfo_id:
  • system:
  • thema:
  • thema_parent:

Unterbereich database

In diesem Unterbereich werden die Tabellen, Views, Themen und Masken integriert.

<database>
   <sachgebiet></sachgebiet>
   <table></table>
   ...
   <table></table>
   <views></views>
   <functions></functions>
   <themen></themen>
   <masken></masken>
   <data-integrity></data-integrity>
</database>

Die Attribute des XML-tag <database> sind wie folgt:

  • name:
  • version:
  • system:

Tabellen

Dies ist der Kernbereich.

<table>
   <description></description>
   <columns>
      <column></column>
      ...      
      <column></column>
   </columns>
   <primaryKeys></primaryKeys>
</table>

Die Attribute des XML-tag <table> sind wie folgt:

  • name: Tabellenname
  • caption: Beschreibung
  • version: Version der Tabelle
  • thema: Das Thema, dem die Tabelle zugeordnet werden kann.
  • typ: Art der Tabelle
  • datenquelle:

Art der Tabelle: Per Konvention folgen die meisten Tabellen einem gewissen Schema, darin erfüllen sie eine bestimmte Funktion und sind an der Namensgebung zu erkennen. Beispielhafte Tabellen:

  • Stagingtabelle: zum Sammeln von Daten, die ins Vorsystem geladen wurden
    • Beispielname: tabelle_neu.sql
  • Datentabelle: zur Datenhaltung
    • Beispielname: tabelle.sql
  • Aggregationstabelle: gehören zur Präsentationsschicht, für Berichte
    • Beispielname: tabelle_aggr.sql
  • Cubetabelle: bauen normalerweise auf Aggregationstabellen auf und überführen diese in eine numerische Verschlüsselung, für OLAP
    • Beispielname: tabelle_cube.sql
  • Dimensionstabelle: für Datenblätter, (OLAP)
    • Beispielname: tabelle_cif.sql
tabelle_cifx.sql
dim_bp_tabelle_apnr

Das Element <description> bietet die Möglichkeit eine ausführlichere Beschreibung der Tabelle zu hinterlassen.
In dem Element <columns> werden die Spalten der Tabelle definiert. Die Attribute des XML-tag <column> sind wie folgt:

  • name: Name der Spalte
  • type: Datentyp
  • size: größe des Datentyps
  • notnull: ob das Feld leergelassen werden darf
  • description: Beschreibung der Spalte (wird in den jsp-Seiten der BI angezeigt)
  • currentlyUsed: Wenn false, wird die Spalte in Datenblatt-Berichten nicht angezeigt.
  • comment: Hier kann noch ein zusätzlicher Kommentar rein (erscheint in der Datenbankdokumentation)

Im Element "primaryKeys" werden die Primärschlüssel der Tabelle eingetragen. Hier gilt folgende Syntax:

<rs>
   <row>
      <fld name="table_cat">superx</fld>
      <fld name="table_schem">superx</fld>
      <fld name="table_name">gang_stg_astat</fld>
      <fld name="column_name">tid</fld>
      <fld name="key_seq">1</fld>
      <fld name="pk_name">gang_stg_stat_tid</fld>
   </row>
</rs>

Die Elemente "fld name" müssen hier von "rs" und "row" umschlossen werden. Für einen Weiteren "primaryKey" wird ein neues Element "row" in dem selben "rs" geschrieben. Zur Beschreibung:

  • table_cat: Databasenamen
  • table_schem: Databasename
  • table_name: Tabellenname in dem der Primarykey steht
  • column_name: Spaltenname vom Primarykey
  • key_seq: Der wievielte Primarykey ist dies von der Tabelle?
  • pk_name: Name vom Primarykey, üblicherweise <<Tabellenname>>_<<Spaltenname>>

Beispiel <table>

<table name="gang_stg_astat" caption="Studienfächer (amtlich) zu Lehreinheiten" version="0.1" 	thema="Studiengänge" typ="Schlüsseltabelle" datenquelle="1">
 <description>Zuordnung amtlicher Studienfächer einer Hochschule zu internen 	Lehreinheiten.</description>
 <columns>
  <column name="tid" type="SERIAL" size="4" default="" notnull="true" description="Laufnummer" 	isKey="true"/>
  <column name="lehreinheit" type="CHAR" size="10" notnull="false" 	description="Lehreinheit"><comment>(hochschulinterner Schlüssel)</comment></column>
  <column name="beschreibung" type="CHAR" size="150" notnull="false" description="Bezeichnung des 	Studienfachs"/>
  <column name="astat" type="CHAR" size="3" notnull="false" description="Externer Schlüssel"/>
  <column name="studienbereich" type="CHAR" size="10" notnull="false" description="Schlüssel 	Studienbereich"/>
  <column name="aktiv" type="SMALLINT" notnull="false" description="Aktiv"><comment>Nur aktive Stati 	(1) werden im Studiengangsbaum angezeigt</comment></column>
  <column name="bund_key" type="CHAR" size="10" notnull="false" description="Bundesschlüssel 	Lehreinheit"/>
  <column name="datenquelle" type="INTEGER" size="4" default="1" notnull="false" 	description="Datenquelle für diesen Datensatz"/>
  <column name="erzeugt_am" type="DATE" size="4" default="today()" notnull="false" 	description="Datum der Erzeugung des Datensatzes" currentlyUsed="false"/>
  <column name="geaendert_am" type="DATE" size="4" default="" notnull="false" description="Datum der 	letzten Änderung des Datensatzes" currentlyUsed="false"/>
  <column name="geaendert_von_id" type="INTEGER" size="4" default="" notnull="false" 	description="UserID des Ändernden" currentlyUsed="false"/>
  <column name="erzeugt_von_id" type="INTEGER" size="4" default="" notnull="false" 	description="UserID des Erzeugers" currentlyUsed="false"/>
 </columns>
 <primaryKeys>
  <rs>
   <row>
    <fld name="table_cat">superx</fld>
    <fld name="table_schem">superx</fld>
    <fld name="table_name">gang_stg_astat</fld>
    <fld name="column_name">tid</fld>
    <fld name="key_seq">1</fld>
    <fld name="pk_name">gang_stg_stat_tid</fld>
   </row>
  </rs>
 </primaryKeys>
</table>

Views

Für die Views wird wie bei den Tabellen eine bestimmte Syntax verfolgt. Diese erläutere ich an dem Beispiel der gang_k_sb:

<view name="gang_k_sb" version="0.1">
   <description>View Studienbereiche (Landesschlüssel)</description>
   <columns>
      <column name="apnr" type ="char" size ="2" default ="" notnull ="true" />
      <column name="kurz" type ="VARCHAR" size ="150" default ="" notnull ="false" />
      <column name="druck" type ="VARCHAR" size ="255" default ="" notnull ="false" />
      <column name="lang_1" type ="VARCHAR" size ="255" default ="" notnull ="false" />
      <column name="astat" type ="SMALLINT" size ="2" default ="" notnull ="false" />
   </columns>
<sql dbsystem=""><![CDATA[SELECT apnr,kurz,druck ,lang_1,astat FROM gang_cifx where key=3 ]]></sql>
</view>

Die Vorgehensweise ähnelt hier der der Tabellen. In "view" wird der Name und die Version des Views eingetragen und in "description" die Beschreibung. In "columns" wird für jede Spalte ein "column" Element angelegt mit den entsprechenden Eigenschaften, wie "name", "type", "size" ... . In "sql" wird dann der select des Views eingetragen. Die Besonderheit hier ist das "CDATA". Durch diesen Befehl wird der eingeschlossene Text nicht von XSLT ausgewertet, sondern direkt übergeben.

Themen

Hier handelt es sich um die Überschriften im Themenbaum, z.B. "Auswertungen zu Studiengängen". Im Attribut Parent wird das übergeordnete Element definiert.

<thema name="Auswertungen zu Studiengängen" parent="Studiengänge">Abfragen zur Akkreditierung</thema>

Masken

Hier werden die Masken bzw. Berichte des Moduls definiert. Diese Definitionen werden z.B. genutzt, um die Masken zu installieren oder zu entladen.

<maske tid="25240" name="Zulassung" thema="Auswertungen zu Studiengängen">
   <src><path>$GANG_PFAD/masken</path><author>D. Quathamer</author><lastChange>23.5.2007</lastChange><dbsystem>INFORMIX</dbsystem></src>
   <src><path>$GANG_PFAD/masken</path><author>D. Quathamer</author><lastChange>23.5.2007</lastChange><dbsystem>POSTGRES</dbsystem></src>
</maske>

Data-integrity

In der Data-integrity werden die Verknüpfungen der Tabellen eingetragen. Dies ist einmal für die <<Modul>>.html wichtig, da dann die Verknüpfungen auch als Link zu der entsprechenden Tabelle erscheinen und damit in SuperX in den entsprechenden Tabellen nicht nur eine Nummer, sondern auch ein aussagekräftiger Text steht. In meinem Beispiel verknüpfe ich die Tabellen gang_k_lehr_hs mit der gang_stg_astat. Auch die Reihenfolge spielt hier eine wichtige Rolle. Die erste Tabelle ist die, in der der entsprechende Inhalt und der Schlüssel in einer Spalte stehen. Die zweite Tabelle enthält nur den Schlüssel. Daher wird in der <<Modul>>.xml in der Zweiten Tabelle der entsprechende Fremdschlüssel eingetragen. In visibleFields wird die entsprechende Spalte eingetragen, die ausgegeben werden soll. Mit zwei Pipes "||" können auch mehrere Spalten miteinander verbunden werden, wenn z.B. der Key und der Text ausgegeben werden soll.

Beispiel:

<!--gang_stg_astat -->
<relation from="gang_k_lehr_hs" to="gang_stg_astat" delete="FALSE" displayType="select" visibleFields="key_apnr || trim(drucktext)" format="%s">
   <relation-column from="key_apnr" to="lehreinheit" />
</relation>

Zur Beschreibung "relation":

  • from: Tabelle mit Schlüssel und zugehörigen Text
  • to: Tabelle nur mit Schlüssel
  • delete:
  • displayType:
  • visibleFields: Welche Spalten angezeigt werden sollen (z.B. in dbforms FK-Bezizehungen)
  • format: Format der Anzeige

Zur Beschreibung "relation-column":

  • from: Key-Spalte der ersten Tabelle
  • to: Key-Spalte der zweiten Tabelle

Unterbereiche install, uninstall, ETL und upgrade

Hier werden Aktionen und Ladeschritte bei der jeweiligen Aktion eines Moduls definiert. Das Hauptaugenmark liegt hier auf "nativeaction" und "loadtable". Eine "nativeaction wäre z.B.:

<nativeaction sql="" scriptfile="$GANG_PFAD/conf/gang_tabellen_fuellen.sql" 
	database=""/>

Hier wird der Inhalt der SQL Datei genommen und ausgeführt. Es ist auch möglich einen SQL Befehl direkt in das Attribut "sql" zu schreiben. Falls erforderlich, kann auch noch als Bedingung die Datenbank angegeben werden (z.B. POSTGRES oder INFORMIX), für die diese "nativeaction" gedacht ist. Für "loadtable" ist folgendes Beispiel:

<loadtable refresh="false" delimiter="^" header="false" tabname="gang_cifx"><file path="$GANG_PFAD/schluesseltabellen/gang_cifx.unl"/></loadtable>

Hier wird der Inhalt einer Tabelle in eine Datei abgespeichert. "delimiter" steht für Feldtrenner, "header", ob die Spaltenüberschrift übernommen werden soll und "tabname" für den Tabellennamen. in "file" in dem Attribut "path" wird der Pfad mit Dateinamen angegeben, wo der Inhalt abgespeichert werden soll.

Spezialität bei ETL

In dem ETL Modul sind 6 Stufen eingebaut. Zu beachten ist hier auch, wenn eine Stufe nicht richtig verarbeitet wird, bricht das SKript komplett ab. Zu den einzelnen Stufen:

Unload
Hier werden die Daten aus dem Vorsystem entladen.
Load
Hier werden die Daten in das Datawarehouse geladen.
Trans
Hier wird die Transformation durchgeführt. D.h. es wird eine Schlüsselharmonisierung durchgeführt.
Aggregation
Hier werden die Hilfstabellen gefüllt.
System
Hier wird das Datum aktualisiert, welches die Aktualität angibt.
Test
Hier findet die Prüfroutine statt.


dbforms

In der Modul-XML werden auch die Vorlagen für die DBforms gemacht. Dabei wird mit XSLT aus der abstrakten Beschreibung des Formulars eine funktionstüchtige JSP-Seite erzeugt. Hier werde ich nur auf die wichtigsten Felder eingehen.

Erläuterung der XML-Elemente

Tabellenname
Als erstes sollte der Tabellenname eingetragen werden. Dieser wird hier an mehreren Stellen benötigt. (Bei: "table", "path", "customfield", ..)
path
Zu beachten ist, dass der Tabellenname sowie das Modul in den Pfad ("path") Angaben auch richtig eingetragen wird.
name , caption
Im ersten Block wird meist in den Feldern "name" und "caption" dasselbe eingetragen und zwar eine kurze aber aussagekräftige Bezeichnung der Tabelle. Diese kann auch in dem zweiten Block übernommen werden. Dort gibt es genau dieselben Felder.
descpription
Eine ausführlichere Beschreibung der Tabelle wird in das Feld "description" geschrieben. Diese Beschreibung sollte aber auch nicht länger sein als ein normaler Satz.
field-selection / customfield
Wenn man <field-selection complete="true" /> wählt, dann werden automatisch alle Felder der Tabelle im Formular angezeigt. Wenn Sie nur einige Felder anzeigen wollen, nutzen Sie das Element <customfield>. Außerdem kann man mit customfield spezielle Layoutanweisungen kombinieren, z.B. Feldgröße.
<form name="Studienfächer (amtlich) zu Lehreinheiten (Liste)"
 table="gang_stg_astat"
 path="/edit/gang/gang_stg_astat_list.jsp"
 followUp=""
 caption="Studienfächer (amtlich) zu Lehreinheiten (Liste)"
 orderBy="astat"
 gotoHt=""
 helpfile=""
 maxRows="*"
 mode="update_insert"> 
<description>Zuordnung amtlicher Studienfächer einer Hochschule zu internen Lehreinheiten.</description>
<filters>
</filters>
<field-selection  complete="false"  />
<customfield name="tid" nullFieldValue="" />
<customfield name="astat" type="label" nullFieldValue="" visibleSize="10"/>
<customfield type="link" name="Details" path="/superx/edit/gang/gang_stg_astat_edit.jsp" linkid="tid"/>
</form>


<form name="Studienfächer (amtlich) zu Lehreinheiten"
 table="gang_stg_astat"
 path="/edit/gang/gang_stg_astat_edit.jsp"
 followUp=""
 caption="Studienfächer (amtlich) zu Lehreinheiten bearbeiten"
 orderBy="astat"
 gotoHt="tid"
 helpfile=""
 maxRows="1"
 mode="full"> 
<description>Zuordnung amtlicher Studienfächer einer Hochschule zu internen Lehreinheiten.</description>
<filters>

</filters>
<field-selection  complete="false"  />
<customfield name="tid" nullFieldValue="" />
<customfield name="lehreinheit" nullFieldValue="" visibleSize="10"/>
<customfield name="beschreibung" nullFieldValue="" visibleSize="30"/>
<customfield name="astat" nullFieldValue="" visibleSize="100"/>
<customfield name="studienbereich" nullFieldValue="" visibleSize="30"/>
<customfield name="aktiv" nullFieldValue="" visibleSize="10"/>
<customfield name="bund_key" nullFieldValue="" visibleSize="30"/>
<customfield name="Datensatzstatus" type="include" path="/edit/gang/datensatzstatus.inc"/>
</form>
Optionen für die Merkmale
  1. mode
    • full
    • update_insert
    • update
    • insert
    • ...
  2. type
    • include
    • link
    • lable (Nur Bezeichnung)
    • ...
  3. filters
    • Beispiel: in gang.xml: form name="zuordnung"
<filters>
<filter mandatory="true" type="equals">tid</filter>
</filters>

Test der Formulare

Die Formulare werden in der Modul-XML-Datei definiert (s.o.). Die JSP-Seiten werden dann generiert, indem man das Modulscripte generieren ausführt. Danach muss man einen Modulupgrade ausführen, damit die Formulare in der Datenbank gespeichert werden. Und dann kann man die Formulare testen, indem man im Menü Administration-> "Tabelle suchen"-> Bearbeiten anklickt.

Wenn Sie die Bearbeitungsformulare auch im Themenbaum anzeigen wollen, müssen Sie eine Suchmaske vorschalten, in der

  • die Datensätze gefiltert werden können
  • über einen' Bearbeiten' Button Pencil.gif(Spaltenname "nextedit") zugänglich gemacht werden.

Sie z.B. die Maske "Tabelle suchen", diese ist ein gutes, einfaches Beispiel für eine Kombination aus Suchformular und Bearbeitungsformular.

Gestaltung der Formulare

Auswahl aus Schlüsseltabelle
Wenn Inhalte zur Auswahl aus einer verknüften Schlüsseltabelle angezeigt werden sollen, müssen folgende Bedingungen erfüllt sein:
  • Die Beziehung ist als data-integrity-relation eingetragen.
  • in der Relation ist unter visibleFields="..." das Feld eingetragen, dessen Inhalt an der Oberfläche erscheinen soll.
Spaltenbeschriftung
Wenn nicht der Spaltennahme aus der Tabelle angezeigt werden soll, sondern eine sprechendere Bezeichnung muss bei description:
 <database> <table> <columns> <column name="..." '''description= "..."''' >
die entsprechende Bezeichnung eingetragen werden.
Formular in Maske einbinden
Wenn durch eintragen von "nextedit" bereits ein Verweis auf das (funktionierende) Formular erstellt wurde, es aber nicht gefunden wird, muss:
  • zunächst die jsp Seite unter superx/edit/MODULE generiert werden