Reverse-Engineering des eStudy-Moduls Planer

Aus THM-Wiki
Wechseln zu: Navigation, Suche
Kurs
Kursname Web-Engineering
Kurstyp Projektkurs
Dozent KQC
Semester WS 10/11
Studiengang Master


Aufgabenstellung

In diesem Projekt geht es um die Überarbeitung des eStudy Moduls 'Planner'. Das Modul wurde erstmalig im Softwaretechnikpraktikum im Wintersemester 08/09 erstellt und während der Mastervorlesung MSP im Wintersemester 09/10 überarbeitet.

Zunächst wird eine Ist-Analyse durchgeführt, bei der verschiedene Diagramme und eine Codeanalyse Aufschluss über das Modul geben. Um verschiedene Bad Smells im Code zu beseitigen wird daraufhinn ein Refactoring durchgeführt. Weitere Themen sind I18N & L10N, Barrierefreiheit, Datenschutz, Sicherheit und Performance. Zum Abschluss wird das Ergebnis als Screencast dokumentiert.

Planner Pattern Beschreibung

Das CMI-Pattern zum Modul Planner ist in einem separaten Artikel beschrieben.

Aktuelle Situation und Quellcodeanalyse

Paketdiagramm

Package.jpeg


Klassendiagramm

Fehler beim Erstellen des Vorschaubildes: Datei fehlt


Use-Case Diagramm

Das Use-Case Diagramm wurde mit dem Enterprise Architect 8.0.864 erstellt.

Fehler beim Erstellen des Vorschaubildes: Datei fehlt

(Bearbeitet von B. Rupp und D. V. Kops)

Datenbankschema

Der Planner verfügt in der eStudy-Datenbank über zwei Tabellen. Alle Planungsabschnitte werden dabei in der Tabelle planningsection gespeichert. Diese Tabelle hat folgende Spalten:

Datenbank planingsection.png

Die Spalte planID stellt den Primärschlüssel dar. Über courseID ist der Planungsabschnitt dabei dem Kurs / der eCom zugeordnet. title, content beinhalten den Inhalt des Planungsabschnittes. starttime und endtime geben an, von wann bis wann ein Planungsabschnitt sichtbar ist, während eventstart und evendend angeben, von wann bis wann ein Planungsabschnitt gültig ist. create_date gibt den Erstellungszeitpunkt an.

Optimierungsmöglichkeiten: Im Gegensatz zu allen anderen Datumsfeldern, die in der Tabelle angelegt sind, wird in create_date ein UNIX-Timestamp hinterlegt. Diese Inkonsistenz sollte behoben werden (entsprechend dem Format, dass sonst in eStudy standardmäßig für Datumsinformationen genutzt wird.

Darüberhinaus existiert die Tabelle planning_resource. Sie stellt eine Beziehungstabelle dar und speichert alle an einen Planungsabschnitt angefügten Materialien.

DatenbankPlanningResources.PNG

Über planID wird die Resource einem Planungsabschnitt zugeordnet. Sie selbst wird über typeID und resourceType identifiziert.

Mögliche Optimierungen: resourceID ist momentan in Verbindung mit courseID der Primärschlüssel der Tabelle. Zusätzlich verfügt resourceID über ein auto_increment. Dies ist redundant. Die Zuordnung zum Kurs erfolgt schon impliziert über planID.

Verknüpfung zum Kalender

Wird ein Planungsabschnitt in einen Kalender eingefügt, wird zusätzlich ein Eintrag in der Tabelle calendar_planninsections angelegt, der den Kalendertermin mit dem Planungsabschnitt verknüpft.

(Bearbeitet von T. Winkelmann)

Software Metriken

Folgende Metriken wurden den Auswertungen des Hudson Continuous Integration Serves des Fachbereichs MNI der FH Gießen-Friedberg entnommen:

NPath Complexity:

Cyclomatic Complexity:

Excessive Public Count:

Excessive Class Complexity:

Excessive Parameter List:

Bad Smells

Duplicated Code:

Datei: class.estudydb.inc.php, Zeile: 602, Typ: Duplizierter Quelltext, Priorität: Niedrig 17 Zeilen duplizierter Sourcetext. Dupliziert in: trunk/web/planner/classes/class.estudydb.inc.php (679)

Datei: class.plannermashup.inc.php, Zeile: 56, Typ: Duplizierter Quelltext, Priorität: Niedrig 8 Zeilen duplizierter Sourcetext. Dupliziert in: trunk/web/planner/classes/class.plannermashup.inc.php (106)

Datei: class.template.inc.php, Zeile: 24, Typ: Duplizierter Quelltext, Priorität: Normal 28 Zeilen duplizierter Sourcetext. Dupliziert in: trunk/web/eyeos/classes/class.template.inc.php (25)

Datei: class.template.inc.php, Zeile: 24, Typ: Duplizierter Quelltext, Priorität: Normal 26 Zeilen duplizierter Sourcetext. Dupliziert in: trunk/web/literatur/classes/class.template.inc.php (24)

Datei: class.template.inc.php, Zeile: 36, Typ: Duplizierter Quelltext, Priorität: Niedrig 14 Zeilen duplizierter Sourcetext. Dupliziert in: trunk/web/announcement/classes/class.template.inc.php (32)

Bad Smell Ort Beschreibung
Data Class class.planningsection.inc.php, class.planningsections.inc.php Klasse ennthält nur getter und setter, kein Verhalten
Large Class class.estudydb.inc.php
Long Parameter List EstudyDB::addPlanningSection

Sonstige Anmerkungen zum Quellcode

  • Gänzlich fehlende Unit-Tests
  • Unvollständige Dokumentation
  • Tabellenlayout für Formulare

Refactoring

Softwaremetriken und Bad Smells(Ist Zustand)

Softwaremetriken (Veränderungen):

  • Die NPath Complexity der Methode start() der Klasse class.plannereditormashup.inc.php konnte von 500 auf 375 reduziert werden. plannereditormashup
  • Die NPath Complexity der Methode show() der Klasse class.planningsectionview.inc.php ist von 0 auf 514 gestiegen was wohl der Einfügung von I18N und der Anzeige des Monatsnahmens zu schulden ist. Dadurch ist auch die Cyclomatic Complexity von 12 auf 14 gestiegen. planningsectionview
  • In der Klasse class.estudydb.inc.php konnte die lange Parameterliste der Funktion addPlanningSection() beseitigt werden, indem die Methode mit der Methode editPlanningSection() zusammengeführt wurde und jetzt die Signatur public static function addEditPlanningSection(PlanningSection $section) besitzt. estudydb

Duplizierter Code (Vollständige Angabe):

Datei: class.estudydb.inc.php:557, Duplizierter Quelltext, Priorität: Niedrig 17 Zeilen duplizierter Sourcetext. Dupliziert in: trunk/web/planner/classes/class.estudydb.inc.php (635)

Datei: class.plannermashup.inc.php:57, Duplizierter Quelltext, Priorität: Niedrig 8 Zeilen duplizierter Sourcetext. Dupliziert in: trunk/web/planner/classes/controller/class.plannermashup.inc.php (107)

Bad Smell: Large Class: class.estudydb.inc.php

Klassendiagramm Soll Zustand

Fehler beim Erstellen des Vorschaubildes: Datei fehlt

(Bearbeitet von Kai Neumann) U12745 19:45, 21. Feb. 2011 (CET)

I18N & L10N

Der Artikel Internationalisierung von eStudy beschreibt die Vorrangehensweise für das Übersetzen von Software. Für das Übersetzen des Planners wurden sowohl die im Artikel beschriebene Tools gettext[1]] und mbstring[2] benutzt, als auch eine Erweiterung der Eclipse IDE: Eclipse Monkey .

Ausgangszustand

Das Modul Planner ist bereits zu einem geringen Prozentsatz übersetzt. In einigen Klassen findet man breits den Zugriff auf das Übersetzungs-Wörterbuch per
$this->translate->_("Zeichenkette").

Soll-Zustand

Ziel ist es alle Klassen zu 100% zu übersetzen. Dazu werden sämtliche Zeichenketten, die später als Text ausgegeben werden sollen, gegen
$this->translate->_("Zeichenkette")
ausgetauscht. Unter Umständen muss das benötigte Translate-Objekt noch instanziiert werden.

Eclipse Monkey

Das Übersetzen gliedert sich also in zwei Schritte: Extrahierung der Zeichenketten (durch copy & paste) und die Übersetzung der Zeichenketten. Schritt 1 kann unter Umständen sehr lange dauern. Dieser Vorgang lässt sich allerdings enorm Beschleunigen. Für Eclipse gibt es eine Erweiterung namens Eclipse Monkey[3] mit deren Hilfe man Scripte für die IDE programmieren kann. Diese Scripte lassen sich entweder über die Eclipse-View "Scripts" oder über eine Tastenkombination aufrufen. Wir programmierten zwei Scripts, mit deren Hilfe wir den zu übersetzenden Text einfach markieren und dann das Script ausführen müssen. Das Script generiert aus dem markierten Text dann den benötigten php-Code. EclipseMonkey.png

Beispiel

Man makiert aus folgender Zeichenkette die Zeichenkette erledigt.
echo "<b>erledigt</b>";
Dann führt man das Script translate selection aus und das Script verändert die Zeile in
echo "<b>".$this->translate->_("erledigt")."</b>";

Script: translate selection

/* 
 * Menu: eStudy > translate selection
 * Key: M1+M2+M3+T
 * Kudos: Dennis Becker & Benjamin Rühl
 * License: EPL 1.0
 * DOM: http://download.eclipse.org/technology/dash/update/org.eclipse.eclipsemonkey.lang.javascript
 */
function main(){
        var sourceEditor = editors.activeEditor;

        var valid = true;
        
        // make sure we have an editor
        if (sourceEditor === undefined) {
                valid = false;
                showError("No active editor");
        }
        
        // inject
        if (valid) {
                        var range = sourceEditor.selectionRange;
                        var offset = range.startingOffset;
                        var deleteLength = range.endingOffset - range.startingOffset;
                        var source = sourceEditor.source;
                        
                        var selection = source.substring(range.startingOffset, range.endingOffset);
                        selection = '".$this->translate->_("' + selection + '")."';
                        
                        // apply edit and reveal in editor
                        sourceEditor.applyEdit(offset, deleteLength, selection);
                        sourceEditor.selectAndReveal(offset, selection.length);
                        
                        
        }
}

Script: translate single selection

/* 
 * Menu: eStudy > translate single selection
 * Key: M1+M2+M3+R
 * Kudos: Dennis Becker & Benjamin Rühl
 * License: EPL 1.0
 * DOM: http://download.eclipse.org/technology/dash/update/org.eclipse.eclipsemonkey.lang.javascript
 */
function main(){
        var sourceEditor = editors.activeEditor;

        var valid = true;
        
        // make sure we have an editor
        if (sourceEditor === undefined) {
                valid = false;
                showError("No active editor");
        }
        
        // inject
        if (valid) {
                        var range = sourceEditor.selectionRange;
                        var offset = range.startingOffset;
                        var deleteLength = range.endingOffset - range.startingOffset;
                        var source = sourceEditor.source;
                        
                        var selection = source.substring(range.startingOffset, range.endingOffset);
                        selection = '$this->translate->_(' + selection + ')';
                        
                        // apply edit and reveal in editor
                        sourceEditor.applyEdit(offset, deleteLength, selection);
                        sourceEditor.selectAndReveal(offset, selection.length);
        }
}

(Bearbeitet von Benjamin Rühl & Dennis Becker)

Barrierefreiheit

Barrierefreiheit und Usability der Dialoge optimieren und Funktionalität erweitern

Datenschutz

Für das Modul „Planner“ wurde ein Verfahrensverzeichnis erstellt. Dieses ist im Ordner „Planner“ im Format „txt“ abgelegt.

Sicherheit

Das Modul Planner wird über die Zentrale Sicherheitsinstanz von eStudy überwacht. eStudy bietet als Sicherheitsarchitektur die Validierung und Maskierung von Ein- und Ausgaben über die sogenannte DATA-Klasse. Alle Eingaben werden, bevor sie in die Datenbank geschrieben oder anderweitig verarbeitet werden, auf Schadcode geprüft. Das in eStudy integrierte PHP-IDS loggt zusätzlich alle Angriffe oder leitet weitere Maßnahmen ein, falls ein bestimmter Impactwert überschritten wird. Zusätzlich wird die Sicherheit von eStudy durch Suhosin überwacht. Der Upload von Dateien wird durch Clam-AV gesichert. Allerdings fehlt an dieser Stelle noch die Funktionalität, um mehrere Dateien zu prüfen, wie im Ticket 692 und 689 vermerkt.

(Bearbeitet von Kai Neumann) U12745 19:45, 21. Feb. 2011 (CET)

Performance

Performance optimieren

Ergebnisse

Die wichtigsten Änderungen und Optimierungen werden in einem Screencast vorgestellt: Er ist unter http://www.youtube.com/watch?v=OFL5CM8X7l0 abrufbar.

Eine abschließende Präsentation der Ergebnisse auf dem 3D CSS Cube II (Funktioniert nur im Safari Browser): http://ibl-server.de/cube/touch.html .