KSM Datenmodell =============== Yves Fischer :lang: de :doctype: book :toc: :toc-title: Inhaltsbla :encoding: utf-8 :data-uri: Einleitung ---------- Mit der Entwicklung einer KSM Anwendung auf Eclipse-RCP Basis war es nötig ein Datenmodell zu entwerfen welches zum MVC-ähnlichen Muster des Eclipse Graphical Editor Framework (GEF) kompatibel ist. Grundsätzlich lassen sich alle Datenmodelle mit GEF abbilden, jedoch existierte in KSM/Swing nur ein stark mit der GUI und Logik verflochtenes und fehlerhaftes Datenmodell, dessen Serialisierung mit einer XML-Bibliothek erfolgte die nicht mehr weiter verwendet werden soll. Da es nicht beabsichtigt ist die KSM/Swing Anwendung auf kurze Zeit abzulösen liegt es nahe, dass das Datenmodell universell einsetzbar sein sollte. Mit der Umstellung von KSM/Swing auf ein neues Datenmodell ist einerseits die Daten-Kompatibiltät zwischen KSM/Swing und KSM/RCP gegeben und das Ziel die XML-Serialisierung in KSM/Swing zu überarbeiten kann einfacher erreicht werden. Dieses Dokument beschreibt die Implementation einer API zum Zugriff auf das in XML-Schema beschriebene Datenformat. Dieses Datenformat erlaubt es darüberhinaus freie Felder zu definieren welche ebenfalls in diesem Dokument spezifiert werden. Das XML-Schema -------------- Die Namespace URL für das XML-Schema lautet: http://www.ba-horb.de/~ksm/xml/ksm-1 die Schemadatei ist abrufbar unter: http://www.ba-horb.de/~ksm/xml/ksm-1.xsd Das XML-Schema ist angereichert um JAXB-Annotationen die den XML-Schema-Java-Compiler bei der Klassenerzeugung steuert. Typen des Datenmodell --------------------- Die Bibltiohekt besteht aus einem Package in dem Interfaces die API-Beschreiben und einem Package mit Implementationen dieser Interfaces die jedoch für den Benutzer unsichtbar und daher austauschbar sind. Das folgende Diagram zeigt das Interface das dem Benutzer zur Verfügung steht: de.dhbw.horb.ksm. xmlschema.api +----------------------------------------------------------+ | +-------------+ +---------------+ +------------+ | | |_____KSM_____| *|___NodeGroup___| *|____Node____| | | |getNodeGroup +---+getNodeGroups()+---+getC.tions()| | | |getVersion() | |getNodes() | | | | | | | | | | | | | +---^---------+ +---------------+ +--+---+-----+ | | | \ | ________________/ | | | | \1 |1 /1 |* | | | +-+-----+-+--+ +---+--------+ | | | |_Properties_|1 |_Connection_| | | | |getString() +----------------+getTo() | | | | |getInteger()| | | | | | |...... | | | | | | +------------+ +------------+ | | | | +----------------------------------------------------------+ | de.dhbw.horb.ksm. xmlschema.impl +-------------------------------+ | | | | +------------------+ | | |____KSMFactory____| | | |createEmptyKSM() | | | |saveKSM() | | | |loadKSM() | | | +------------------+ | +-------------------------------+ Ein Diagramm wird erstellt indem ein neues ('createEmptyKSM()') erstellt wird oder eines geladen wird ('loadKSM()'). Die weitere Navigation erfolgt durch Absteigen in dem Objekt-Baum der durch NodeGroup- und schliesslich Node-Objekte gebildet wird. Datentypen der Eigenschaften ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Im Modell gibt es die Datentypen KSM, NodeGroup, Node und Connection (siehe Klassen-Diagramm). Zusätzlich gibt es die Klasse Properties mit der an die Datentypen zusätzliche Eigenschaften mit einem Text-Bezeichner angehängt werden können. Für die Eigenschaften stehen folgende Typen zur Verfügung: ''string'', ''integer'', ''boolean'', ''integerList'', ''decimalList'', ''stringList''. Der Datentyp erschliesst sich aus dem Namen. Prinzipiell kann jeder Bezeichner für jeden Datentyp einmal verwendet werden, ein Bezeichner sollte jedoch wegen der Übersichtlichkeit nur einmal verwendet werden. Verwendung der ChangeListener ----------------------------- Die Klassen __NodeGroup__, __Node__ und __Properties__ implementieren Change-Listener auf die sich Listener-Klassen registrieren können um über Änderungen am Datenmodell informiert zu werden. Dies wird beispielsweise benötigt, wenn zwei Programmteile wie ein Eigenschaften-Editor in Tabellenform und ein grafischer Editor voneinander unabhängig auf das Datenmodell zugreifen und beispielsweise die Farbe eines Knoten ändern. Die Spalte 'Index' zeigt an ob das Event eine Index-Eigenschaft hat die andeutet welches Element in einer Liste geändert wurde. Die Spalte 'Version' zeigt an, ab welcher Version des Datenformat (=Version dieses Dokumentes, Version Attribut in Element) dieser Event unterstützt wird. .__NodeGroup__-Events [width="80%",cols="3,2,2,10",options="header"] |========================================================= |Property-Name | Version | Index? |Beschreibung |nodes | 1+ | ✓ | Eine __Node__ wurde dieser __NodeGroup__ hinzugefügt oder entfernt |========================================================= .__Node__-Events [width="80%",cols="3,2,2,10",options="header"] |========================================================= |Property-Name | Version | Index? |Beschreibung |connections | 1+ | ✓ | Eine __Connection__ wurde erstellt oder gelöscht |========================================================= .__Properties__-Events [width="80%",cols="3,2,2,10",options="header"] |========================================================= |Property-Name | Version | Index? |Beschreibung |string: 'X' | 1+ | ✗ | Eine Zeichenketten Eigenschaft mit Name 'X' wurde geändert |decimal: 'X' | 1+ | ✗ | Eine Fliesskommazahl Eigenschaft mit Name 'X' wurde geändert |integer: 'X' | 1+ | ✗ | Eine ganzzahlige Eigenschaft mit Name 'X' wurde geändert |boolean: 'X' | 1+ | ✗ | Eine boolsche Eigenschaft mit Name 'X' wurde geändert |integerList: 'X' | 1+ | ✓ | Eine Ganzzahl Liste mit Name 'X' wurde manipuliert |decimalList: 'X' | 1+ | ✓ | Eine Fliesskommazahl Liste mit Name 'X' wurde manipuliert |stringList: 'X' | 1+ | ✓ | Eine Zeichenketten Liste mit Name 'X' wurde manipuliert |========================================================= Eigenschaften (Properties) -------------------------- Allen Elementen im Datenmodell lassen sich dynamische, dass heist nicht in einem Schema festgelegte, Eigenschaften zuwiesen. Dies hat zur Folge, dass eine Anwendung sowohl den Fall handhaben muss, dass eine erwartete Eigenschaft nicht vorhanden ist als auch, dass Eigenschaften vorhanden sind die unbekannt sind und ignoriert werden müssen. Dazu steht der Anwendung jedoch das Attribut 'Version' im Schema (siehe KSM#getVersion()) zur Verfügung, welches auf eine Version von diesem Dokument zeigt. Dieser Ansatz wurde gewählt, da sich gezeigt hat, dass die Studienarbeiten im KSM-Projekt einen begrenzten Fokus haben und es daher für einen einzelnen Studenten schwer möglich ist, alle benötigten Datenfelder zu definieren. Das bisherige KSM-Datenformat handhabt dies, indem das XML-Schema beliebig verändert wurde und damit sinnlos wurde. Da dies unvermeidbar ist wird es mit diesem Ansatz aktiv unterstützt. Eine alternative Herangehensweise wäre die Verwendung von verschiedenen XML-Schemas gewesen wobei mit jeder Erweiterung ein zusätzlicher Namensraum eingeführt wird. Dies schien jedoch sehr viel umständlicher und unnötig kompliziert. Eigenschaften von Modellen (KSM) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Die Spalte 'Typ' zeigt den Datentyp der Eigenschaft an. Die Spalte 'Schlüssel' den Bezeichner welcher in Kombination mit dem Typ eindeutig ist. Die Spalte 'Version' zeigt an, ab welcher Version des Datenformat (=Version dieses Dokumentes, Version Attribut in Element) dieser Event unterstützt wird. .KSM Properties [width="80%",cols="3,4,2,10",options="header"] |========================================================= |Typ | Schlüssel | Version | Beschreibung |nichts | ist | definiert | - |========================================================= Eigenschaften von Knoten (Node) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .Node Properties [width="80%",cols="3,4,1,10",options="header"] |========================================================= |Typ | Schlüssel | Ver. | Beschreibung | string | visual.caption | 1+ | Titel der Node im Editor. | string | visual.color | 1+ | Farbliches Merkmal der Node Hexadezimal im 8-Bit RGB Format wie folgt: +#RRGGBB+. | integer | visual.location.x | 1+ | X-Position relativ zur übergeordneten NodeGroup | integer | visual.location.y | 1+ | Y-Position relativ zur übergeordneten NodeGroup | decimal | data.user_value | 1+ | User Value (?) | decimal | data.min_value | 1+ | Minimal Value (?) | decimal | data.max_value | 1+ | Maximal Value (?) | decimal | data.extern | 1+ | Extern Value (?) |========================================================= Als Erbe aus dem KSM/Swing Projekt kann ''visual.color'' die folgenden Werte annehmen, diese sollen auf den folgenden RGB-Wert übertragen werden: * +White+ -> +#ffffff+ * +Light Yellow+ -> +#faffa2+ * +Medium Yellow+ -> +#f4ff4b+ * +Yellow+ -> +#edfc00+ * +Light Blue+ -> +#d4d5e9+ * +Medium Blue+ -> +#7678ff+ * +Blue+ -> +#0002f8+ * +Light Green+ -> +#c8f8c9+ * +Medium Green+ -> +#7afa7e+ * +Green+ -> +#1af520+ * +Light Red+ -> +#fdcccc+ * +Medium Red+ -> +#f95959+ * +Red+ -> +#f62020+ Eigenschaften von Verbindungen (Connection) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .Connection Properties [width="80%",cols="3,4,1,10",options="header"] |========================================================= |Typ | Schlüssel | Ver. | Beschreibung | string | visual.caption | 1+ | Titel der Connection im Editor. | string | visual.color | 1+ | Farbliches Merkmal der Connection | string | data.functionType | 1+ | Ein Funktionstyp von: 'straight-line', 'individual', 'parable', 'parabolic-sections'. | decimalList | data.function | 1+ | KSM-Simulator Funktionsparameter dieses Knoten |========================================================= ''data.function'' enthält eine Liste von Argumenten für die verwendete, durch ''data.functionType'' festgelegte Funktion. Eigenschaften von Gruppen (NodeGroup) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .NodeGroup Properties [width="80%",cols="3,4,1,10",options="header"] |============================================================= | Typ | Schlüssel | Ver. | Beschreibung | string | visual.caption | 1+ | Titel der Group im Editor. | string | visual.color | 1+ | Farbliches Merkmal der Group | integer | visual.location.x | 1+ | X-Position relativ zu übergeordneten NodeGroup | integer | visual.location.y | 1+ | Y-Position relativ zu übergeordneten NodeGroup |============================================================= Dokumentation der Implementierung --------------------------------- Das am Anfang vorgestellte Objektmodell wird durch Interfaces im Package 'de.dhbw.horb.ksm. xmlschema.api' umgesetzt. Eine Implementierung dieser Interfaces findet sich im Package 'de.dhbw.horb.ksm. xmlschema.impl'. Von dieser Implementierung ist für äusseren Zugriff nur die Klasse 'KSMFactory' vorgesehen, welche Methoden zum Laden und Speichern von KSM-Modellen zur Verfügung stellt. Die Implementierung benutzt vom XML-Schema-Compiler (xjc) von JAXB generierte Klassen die im Package 'de.dhbw.horb.ksm. xmlschema.generated' liegen. Das generieren wird vom Ant-Task 'compile-xjc' und Annotationen im Schema gesteuert. Der Zugriff auf das geladene Modell erfolgt auschliesslich über die in den Interfaces vorgesehen Methoden, ein direkter Zugriff ist nicht möglich. Neben dem Quellcode in src/ gibt es im Projektverzeichniss noch das Verzeichnis test/ welches JUnit-4 Tests enthält die die Implementierung nahezu 100% abdecken. Die Tests sind dabei zum Teil im Stil des Behavior Driven Development (BDD) geschrieben unter Zuhilfename der Bibliothek mockito. Vorgehensweise bei Änderungen ----------------------------- 1. Eintragung der Änderung in diesem Dokument 2. Erhöhen der Versionszahl 3. Erstellen eines Eintrags in der Revisions Historie in diesem Dokument 4. Anpassen der Versionszahl in build.xml 'project.version' 5. Erstellen einer HTML- und PDF Version von diesem Dokument (asciidoc/a2x). Revisions Historie ------------------ .Revisions [width="80%",cols="1,3,4,10",options="header"] |========================================================= | Ver. | Datum | Person | Änderung | 1 | 2011-03-24 | Yves Fischer | Beginn der Historie, KSM Version 1 | 1 | 2011-04-26 | Fischer, Dreher | Erläuterung Datentypen. Festlegung Funktionsname/Parameter von Connection's. |=========================================================