Dienstag, 23. Dezember 2008

Sonntag, 21. Dezember 2008

Freaky Friday - A6: Almighty Webservice Client

Ein paar abendliche Punsch können erstaunliche Auswirkungen auf die Kreativität des menschlichen Gehirns haben - so geschehen Freitag abend, als auf der Heimfahrt in der U-Bahn die Idee geboren wurde, einen universellen Webservice Client zu erschaffen.

Die Idee hat sich hartnäckig gehalten und so sind Skripte und Quellen unter http://almighty.pri.univie.ac.at/~aXXXXXXX/a6/client/ zu finden - die Matrikelnummer bitte wieder selbst aus der Teilnehmerliste kopieren.

Ein paar der interessanten Features sind:
  • Komplett automatisiert (Nur WS Name / Ersteller / WSDL URL sind manuell erfasst)
  • Formulargenerierung inkl. Labels
  • Geparster Methodenname als Formulartitel (erkennt "get", "add", CamelCase)
  • Unterstützung komplexer Typen, auch verschachtelt
  • Unterstützung von Arrays als Input Parameter (immer 3 Elemente)
  • Tracelog (Per JavaScript Ein/Ausblendbar)
  • Retournierte Arrays werden als Listen ausgegeben
  • Retournierte Objekte werden als Tabelle ausgegeben (Attributname und Wert)
Sehr viel Magie ist leider nicht dabei, hauptsächlich besteht die Arbeit aus stupidem (quick and dirty) Parsen. Mit ein paar gescheiten Regex wäre das ganze kürzer geworden, aber hauptsächlich ging es mir darum just for fun einen Prototypen zu erstellen. Interessant sind:
  • Reflection für die Objekte: get_object_vars($result); in response.php
  • Method Invocation für den SOAP Client: call_user_func_array( array($this->client,$operation) , $arguments); in definitions.php
Die Anzahl der Server, die damit kompatibel sind ist zwar erschreckend gering, das liegt allerdings an Fehlern in deren Implementierung - Feedback ist in der Auswahlliste zu finden.

Montag, 8. Dezember 2008

A6: Webservice Server Release

Das zuvor beschriebene Arzneimittel-Codex Webservice ist nun fertig implementiert, hier gibt es die Details.

Operation 1: String[] getArzneimittelliste(String stoffklasse)
Operation 2: Medikament getMedikament(String handelsname)

Der komplexe Datentyp Medikament enthält (in dieser Reihenfolge) die String-Elemente handelsname, freiname, wirkstoff, indikationen, kontraindikationen

Folgende Arzneimittelklassen sind vorhanden: Antibiotika, Antihistaminika, Benzodiazepine, Sonstiges. Je nach Kategorie werden dabei zwischen 1 und 3 Medikamente (Array Elemente) gespeichert. Wird eine "unbekannte" Arzneimittelklasse angefordert, so werden immer die Allheilmittel Panazee und Theriak zurückgeliefert.

Mögliche Medikamente sind Fenistil, Floxapen, Invanz, Ospamox, Panazee, Psychopax, Theriak und Valium. Zu diesen 8 Medikamenten können mit Operation 2 auch Details abgerufen werden. Bei einem unbekannten Medikament sind alle Attribute des zurückgelieferten Objekts NULL-Werte.

Wer bereits den Client implementieren will, dem kann ich versprechen dass ich keine Änderungen mehr geplant habe. WSDL und Server Source befinden sich am Almighty (http://almighty.pri.univie.ac.at/~aXXXXXXX/a6/). Interessenten mögen die Matrikelnummer in der Teilnehmerliste der Übungsumgebung nachschlagen, da ich sie hier nicht gleich Google direkt in den Rachen werfen möchte.

Sonntag, 7. Dezember 2008

A6: Webservice Server Preview

Meine aktuelle Idee zu dieser Aufgabe kommt einmal mehr aus dem Bereich der medizinischen Informatik.

Operation 1 erhält als Parameter eine Arzneimittelklasse, und retourniert ein Array von Präparaten (Handelsnamen). Eine Liste dazu gibt es unter http://www.meduniwien.ac.at/medtools/medlist/ind-list.pdf, ein Teil davon wird wohl per Copy und Paste Einzug in mein Webservice erhalten.

Operation 2 realisiert einen Arzneimittelkodex (In Österreich: "Austria Codex"). Als Parameter wird der Handelsname eines Präparats als String übergeben, der komplexe Datentyp "Medikament" mit detailierten Informationen (Freiname, Wirkstoff, Indikationen, Kontraindikationen) zurückgegeben. Online verfügbare Kodizes sind unter http://www.meduniwien.ac.at/medtools/medlist/cms1/ueberuns/00000095fc12aeb01/index.php verlinkt. Die Schweizer Liste ist auch ohne vorhergehender Registrierung komplett abrufbar - einfach mal "Aspirin" oder sonst etwas bekanntes auf http://www.kompendium.ch/Search.aspx?lang=de eingeben.

A4: XPath Abfragen

Nach der Deadline gibt es nun auch die "Auflösung":
  • Zu welchen Tumoren wurde noch kein Krebsmeldeblatt angelegt?

    //tumor[count(krebsmeldeblatt)=0]

  • Untersuchungen, bei denen ein Residuum entdeckt wurde

    //untersuchung[diagnose/tumorstatus="Residuum"]

  • Die Ausdehnung aller benignen Tumoren des Patienten mit der SVNR 1234010155

    //patient[@svnr="1234010155"]/untersuchung/diagnose[id(@tumor)
    [differenzierung/@name="benign"]]/ausdehnung
Das ganze auch für die Regierungs-Teilaufgabe:

  • Die Namen aller SPÖ-Sozialminister

    id(//minister[@ressort="sozial"]/@person_id)[@partei="SPÖ"]/@name
    XPath2: distinct-values( id(//minister[@ressort="sozial"]/@person_id)[@partei="SPÖ"]/@name)

  • Zurückgetretene FPÖ-Minister

    //minister[ id(@person_id)/@partei="FPÖ" and @durchgehalten="nein" ]

  • Bundeskanzler gescheiterter Regierungen

    //minister[ @bundeskanzler="ja" and ../@vorzeitige_neuwahlen="ja" ]

  • Die durchschnittliche Amtszeit von Regierungen (nur XPath 2)

    sum(//legislaturperiode/number(@end_jahr - @beginn_jahr)) div count(//legislaturperiode)
Da sind auch einige Abfragen mit id() dabei, die ResultSets werden daher in der Übungsumgebung nicht ganz wie gewohnt farblich markiert - aber sie funktionieren.

Wer vor ähnlichen Problemen steht, kann ganz einfach mit Saxon arbeiten (unterstützt auch XPath2, Download: http://saxon.sf.net). Die Abfrage muss in eine Datei geschrieben werden (zb q.txt), der Aufruf lautet dann wie folgt:

java -cp saxon9.jar net.sf.saxon.Query -s file.xml q.txt

A5b: XSLT

Schon vor etwas mehr als einer Woche habe ich angefangen, A5 zu erledigen. Variante B (XSLT) war vermutlich die einfachste Aufgabe nach A1 (HTML) und dementsprechend schnell fertig. Die XML-Datenquelle war schnell erstellt, für das XSLT war auch nicht viel mehr nötig, als die vorhandene HTML Seite mit XSL-Tags auszustatten.

Zwei Tipps an dieser Stelle: Das erste Beispiel zeigt das Grundgerüst zum Sortieren einer Liste. Das zweite Beispiel demonstriert, wie man Werte in ein HTML Attribut einfügen kann (<xsl:value-of> wäre ja ein Tag im Tag und funktioniert somit auch nicht). Der String innerhalb der geschwungenen Klammern ist dabei der XPath-Ausdruck, der normalerweise im select="..." stehen würde)
<xsl:for-each select="...">
<xsl:sort select="..." />
</xsl:for-each>

<img id="cover" src="{cover}" alt="{titel}" />
(Fleiß-)Aufgabe A5a werde ich mir dann ersparen, wenn bis 16.12. schon die nächste (Teil)aufgabe Webservice Server abzugeben ist. Außerdem beginnt am 9.12. ja wieder die ORF Ski-Challenge 09, da muss dann natürlich fleißig trainiert werden.

Freitag, 28. November 2008

XML in Farbe und bunt

Wer Latex verwendet, ist ein wenig verwöhnt, was das Einfügen von XML betrifft - Syntax Highlighting inklusive:
...
\usepackage{listings}
...
\lstset{
language=XML
}
\begin{lstlisting}
% XML Quelltext ...
\end{lstlisting}
Mit einem kleinen Trick erzielt man den gleichen Effekt auch in gewohnten Textverarbeitungsprogrammen à la Word und OpenOffice Writer: XML Dokument in Eclipse öffnen, per Copy und Paste ins Textdokument einfügen - fertig!

Mittwoch, 26. November 2008

A4: XPath - Kopfweh inklusive, eine bittere Wahrheit

Mein Modell habe ich bereits in einem früheren Blog-Eintrag vorgestellt. Meine dazugehörigen XPath Abfragen sind die folgenden (in der Realität auch tatsächlich gestellten Fragen):
  • Zu welchen Tumoren wurde noch kein Krebsmeldeblatt angelegt? (Eigentlich wollte ich folgendes abfragen: Zu welchen Erst- und Zweit-Tumoren wurde noch kein Krebsmeldeblatt angelegt? Warum das nicht geht, seht ihr wenn die Scrollleiste am unteren Browserrand ansteht) - Ärzte sind verpflichtet bei allen neu aufgetretenen Tumoren (Also Erst-,Zweittumoren, nicht aber Rezidive oder Residuen) ein Krebsmeldeblatt an das Krebsmelderegister der Statistik Austria zu senden.
  • Untersuchungen, bei denen ein Residuum entdeckt wurde (Da hat dann der Chirurg zu wenig weggeschnibbelt)
  • Die Ausdehnung aller benignen Tumoren des Patienten mit der SVNR 1234010155 (knifflig!)
Schon bei Anfrage 3 werde ich etwas stutzig - die XML Arbeitsumgebung markiert das ResultSet nicht wie gewohnt rot.

Weiter gings mit Teil 2 - XPath Abfragen für das Regierungs-Modell. Auf der verzweifelten Suche nach *sinnvollen* Abfragen fallen mir allzu banale und einige anspruchsvollere ein. Mit Hilfe der "Evaluate XPath" Funktion im XML Spy (der die Abfragen live beim Tippen aktualisiert und so auf dem Lösungsweg unterstützt) sind bald alle fertig formuliert - doch die XML Arbeitsumgebung hält einen Teil davon für ungültig. Es kommen leichte Zweifel auf: propriätäre Funktionen von XML Spy? Nein, die W3C XPath Recommendation enthält sie ebenfalls. Also schnell ein paar ganz simple Abfragen testen: number(), current-date(), ... und siehe da: denkste! Die Arbeitsumgebung wird doch nicht ...

Ein paar Tests in Xalan und Saxon später: Xalan verweigert seinen Dienst, Saxon liefert genau das erwartete Ergebnis. Jetzt noch schnell am Almighty einloggen und "env" tippen - sofort sticht "CLASSPATH= (...) /opt/Axis/lib/xercesImpl.jar" ins Auge. Xalan baut auf Xerces auf, und unterstützt nur XPath 1 - das gilt dann auch für das Frontend in der Arbeitsumgebung.

Schade :(

Freitag, 21. November 2008

The Power of J2EE + Richfaces - oder: Wer hat den kürzeren?

Michael Derntl hat vor wenigen Tagen berichtet, wie er sich mit Hilfe von Bibliotheken (Prototype) das Leben einfacher macht. Das selbst gesetzte Ziel war es, den nötigen selbsterstellten Quelltext von AJAX Applilkationen zu verkürzen - ganz nach dem Motto "Code less, create more".

Ich behaupte frech, es geht noch viel einfacher und trete gleich den Beweis an. Unterstützen lasse ich mich dabei von JBoss RichFaces, einer JSF Implementierung mit AJAX Out-of-the-Box Support.

Der Taschenrechner wäre mit folgendem Code erledigt:
<h1>AJAX Calculator Demo</h1><a4j:form>
Multiply <h:inputText value="#{calculator.x}" /> x <h:inputText value="#{calculator.y}" />
<a4j:commandButton value="=" action="#{calculator.calc}" reRender="result" />
<b><h:span id="result">#{calculator.result}</h:span></b>
</a4j:form>

public class Calculator
{
private int x,y,result;
public int getX() { return x; }
public int getY() { return y; }
public int getResult() { return result; }
public void setX(x) { this.x = x; }
public void setY(y) { this.y = y; }
public void calc() { result = x*y; }
}

Das Beispiel zum Bearbeiten von Texten sobald man draufklickt, reduziert sich überhaupt auf eine einzige Zeile:
<rich:inplaceInput value="#{bean.text}" />
Wers nicht glaubt, oder live ausprobieren mag, kann sich Demos zum A4J CommandButton und zum Rich InplaceInput anschauen.

Was lernen wir daraus? Mit den richtigen Frameworks und Bibliotheken hat man mehr Zeit für wichtige Dinge. Software entwickeln statt Programmieren. Held der Arbeit statt Coding Monkey.

Donnerstag, 20. November 2008

A3: XML / DTD

Nachdems anlässlich des von David Selig veröffentlichten Klassendiagramms keine Beschwerden gegeben hat, tue ich es ihm hiermit gleich. Damit erspare ich mir einen zweiten Post nach der Deadline zur gleichen Aufgabe, außerdem schätze ich mein Thema als exotisch genug ein um anderen nicht in die Quere zu kommen. Ich habe wieder einmal mein Faible für die Medizin ausgelebt und ein Mini-Tumordokumentationssystem abgebildet:


Hintergrundinformation

Patienten werden erst dann erfasst, wenn sie einen Tumor haben. Diese Tatsache spiegelt sich in den Kardinalitäten der Beziehung zwischen Patient (1) und Tumor (N, jedoch mindestens 1) wieder.

Ein Tumor wird eindeutig identifiziert durch die Lage und die Differenzierung. Die Lage wird angegeben durch einen obligatorischen Organbezirk (zB Nasenhaupthöhle) und gegebenenfalls eine Organseite (Links, Rechts, Mitte, oder Keine Seite wenn anatomisch auch keine vorhanden ist). Die Differenzierung ist ist die histologische Einteilung in benign, malign, semimalign oder undifferenziert. Zwei vollständige Beispiele wären also „Nasenhaupthöhle Rechts malign“ und „Zungenspitze Mitte benign“.

Zu jedem Tumor kann ein Krebsmeldeblatt zur Einsendung an das Krebsmelderegister der Statistik Austria angelegt werden, muss aber nicht.

Im Rahmen der Untersuchungen eines Patienten werden allgemeine Anamnese-Daten erfasst, etwa das Gewicht und Tumor unspezifische Begleiterkrankungen (Hypertonie, Diabetes, ...). Bei jeder Untersuchung werden entweder alle oder nur ein Teil der Tumoren genau untersucht. Dabei werden der Tumorstatus (Ersttumor, Zweittumor, Rezidiv, Residuum) seine Ausdehnung (befallene Organbezirke), sowie spezifische Krankheitssymptome und Nervenläsionen erfasst.

In der Praxis werden unter anderem auch noch eingesetzte Diagnoseverfahren (zB Bildgebung [Röntgen, PET, Szintigraphie, ...], Endoskopie, Gewebsentnahme/Histologie) und Therapien
(Chemotherapie, Radiotherapie, Kombitherapie, Operation, Sonstige Verfahren) dokumentiert, in diesem Modell jedoch nicht abgebildet.

Das DTD ...

... veröffentliche ich natürlich nicht :p

Als viel beschäftigter Mensch bin ich natürlich interessiert, mir möglichst wenig Arbeit zu machen und die unvermeidbaren Dinge möglichst effizient zu lösen. Darum habe ich ein wenig geschummelt und die Anweisung von oben, "Erstellen Sie zur DTD ein XML Dokument" missachtet. Am Anfang war das XML, und das XML war bei XMLSpy, und bei XMLSpy ward das DTD.

Damits nicht ganz so billig ist, gabs danach einen Handarbeits-Feinschliff: ID und IDREF wurden genutzt, das Gewicht hat eine FIXED Einheit ("kg") und zu guter Letzt gab es noch Enumerierungen für die Organseite (links|rechts|mitte|keine) sowie Differenzierung (benign|malign|semimalign|undifferenziert|unbekannt).

Jetzt müssen höhere Mächte nur noch die XML Arbeitsumgebung reanimieren (Command env not found!), damit ich das ganze fertig abgeben kann.

Dienstag, 18. November 2008

P [3,4]: Review

Der furchtlose Kollege Klaffenböck aus Team 2 hat hier [1] und hier [2] Entwürfe seines Komponentendiagramms vorgestellt.

Was mich dabei am Entwurf [1] stört:

  • "Userprofil anzeigen / erstellen / bearbeiten" sind Anwendungsfälle, (imho) keine Komponenten
  • Ebenso die anderen Layer 1 - "Komponenten"
Ad [2]:

  • Folie 2: Bearbeiten und Kommentieren sind Anwendungsfälle, mit dem Rest kann ich leben wenn ich es mir richtig interpretiere
Das zieht sich eigentlich durch die meisten Diagramme, und auch der folgende Blogeintrag vermittelt mir irgendwie das Gefühl, dass aus etwas das sinnvollerweise ein Klassendiagramm bzw. Usecase-Diagramm sein sollte, krampfhaft in "Komponenten" gezwängt wird, siehe auch:

(...) darauf praktisch die Inhalte unseres letzten UML-Diagramms abbilden, also "was kann ich mit dem System alles machen?", denn das beschreibt ja meiner Meinung nach die logischen Funktionen
Bei Architektur und Komponenten denke ich da viel mehr ans ganz Grobe, bzw. an die Struktur des Projekts im Filesystem (bzw. das logische Mapping dann dazu, die Java Packages).

Sinnvolle Komponenten könnten dann meiner Meinung nach sein: Java Packages, Verzeichnisse, Bibliotheken (zb Hibernate/PDO/JDBC für den DB-Zugriff --> Komponente Datenbankanbindung), ...

Genau aus diesem Grund ist unser Entwurf auch sehr generisch (er könnte eigentlich für jedes beliebige Projekt genommen werden) und beinhaltet auch keine explizit erwähnten Klassen (wie zB "Prüfung", "Lehrveranstaltung", "Hörsaal", "Prüfungsanmeldung", "Prüfungsergebnis") - all diese Klassen würden meiner Meinung nach dann in ein Klassendiagramm kommen, dass deren Attribute und Beziehungen abbildet - fürs Komponentendiagramm sollte ihr gemeinsamer "Übervater" Entity bzw. Model als Paket bzw. Komponente bestens passen.

Hm ja... Schlafenszeit :p

P3: Architektur

Zugegebenermaßen, ich habe mich die letzten paar Tage nicht mit dem Blog beschäftigt (weder dem eigenen noch jenen der anderen Kollegen aus SWA) . Erst jetzt nach der Abgabe von P3, bemerkte ich dass wir eigentlich etwas gezeichnet haben, dass sich von den anderen Entwürfen sehr stark unterscheidet.

Im nächsten Eintrag werde ich dann einen Review zur Architektur von Team 2 aus Gruppe 4 posten, und damit auch ein wenig begründen warum unser Diagramm so anders ist.

Da die Deadline ohnehin schon vorbei ist, stelle ich hier einmal unsere Variante vor, wobei die Erläuterungen aus der Abgabe 1:1 kopiert sind.



Das System verwendet das Presentation-Abstraction-Control Pattern für seine grundlegende Architektur. Im Groben orientiert sich diese an den Ideen des JBoss Seam Frameworks.

Der Presentation Layer wird dabei von einem Pull-basiertem Template-System und einer Presenter-Klasse gebildet, die die PHP Objekte on Demand zur Verfügung stellt und für den Pageflow sowie Fehler- und Erfolgsmeldungen verantwortlich ist. Die Zuordnung zwischen Template-Variable und Backing Bean dabei über den Klassennamen bzw. Attributsnamen. Das Importieren von Objekten erfolgt dabei über Schnittstellen zur Cotrol Komponente.

Der Control Layer übernimmt die Steuerung der Webanwendung und verbindet die beiden anderen Layer Abstraction und Presentation. Zentraler Einstiegspunkt ist der Front Controller mit integriertem Request Dispatcher. Bei jedem HTTP Request wird die korrespondierende Methode der Anwendungslogik aufgerufen, und benötigte Request Parameter als Argumente übergeben. Zur Entkopplung "echter Business-Logik" und Web-Programmierung bietet dieser Layer auch Schnittstellen für Authentifizierung, Rechtemanagement, und Verwaltung der Session.

Der Application Layer ist für die eigentliche Business-Logik zuständig. Die "Application Logic" Komponente beinhaltet dabei alle Klassen zur Umsetzung der funktionalen Anforderungen, deren Methoden sind die Implementierung von Anwendungsfällen und werden vom Front Controller gestartet.

Das Objektmodell wird im Subsystem Model realisiert. Im Paket "Entity" befinden sich (analog zu POJOs) die Klassen zur Abbildung der Realität mit entsprechenden Attributen und dazugehörigen gettern und settern. Diese können von der Applikationslogik über eine Factory instanziert werden. Der Persistence Manager übernimmt das Laden und Speichern der Objekte im gewünschten Persistenzsystem, also zB einer relationalen Datenbank oder XML-Dateien. Die dafür benötigten Meta-Informationen (Spaltennamen, ...) werden dabei entweder über Konvention (Klassenname == Tabellenname, Attributname == Spaltenname, ...) oder Annotationen festgelegt.

<?php echo "intim" ?>

Ob der Titel wohl wieder dazu führt, dass ein weiterer SWA-Blog als Spamblog oder als nicht jugendfreier Blog eingestuft wird?

Dieser Eintrag stellt eine Premiere in meinem Blog dar: es ist der erste ganz ohne jeden Bezug zu einer Aufgabe.

In einem SWA Foren-Eintrag wurde einmal der Ratschlag gegeben, die einfachen Hochkommas beim Echo durch doppelte zu ersetzen.

In den meisten Fällen wird das gemacht, wenn man im echo-Text nochmals einfache oder doppelte Hochkommas ausgeben will. Wo aber liegt der Unterschied?

Strings unter einfachem Hochkomma werden von PHP nicht weiter geparst, sondern "raw" ausgegeben, solche unter doppeltem Hochkomma erst ausgewertet.

Beispiel:

$a=1;
echo '$a'; //Ausgabe: $a
echo "$a"; //Ausgabe: 1

Übrigens: echo ist keine Funktion! Unkreativerweise zitiere ich hier nur das offizielle PHP Manual:

echo() ist nicht wirklich eine Funktion sondern ein Sprach-Konstrukt, daher brauchen Sie keine Klammern verwenden. echo() verhält sich im Gegensatz zu einigen anderen Sprach-Konstrukten nicht wie eine Funktion, deshalb kann es nicht immer in einem Funktionskontext verwendet werden. Hinzu kommt, dass bei der Angabe mehrerer Parameter für echo() diese nicht von Klammern umschlossen sein dürfen.

Das hat eine besondere Auswirkung: die beiden folgenden Statements produzieren die gleiche Ausgabe, intern gibt es aber Unterschiede.

echo 'A'.'B'.'C'.'D';
echo 'A','B','C','D';

Einmal verwende ich also Punkte, dabei wird der String zusammengesetzt (A... AB... ABC... ABCD...) und erst dann ausgegeben (bzw. genau genommen eigentlich in den Output Buffer geschrieben).

Beim zweiten Mal verwende ich Kommas, dabei wird jeder Teil sofort ausgegeben. Das erspart Zeit und Speicher.

Möglich ist das wie gesagt nur deshalb, weil echo keine Funktion, sondern ein Konstrukt ist. Natürlich wird $a = 'a','b','c'; im Gegensatz zu $a = 'a'.'b'.'c'; NICHT funktionieren.

Draufgekommen bin über Umwege ich im Rahmen eines Seminars, bei dem ich PHP Obfuscator Software untersucht habe. Einige dieser Produkte produzieren "Bytecode" (eigentlich einen PHO Operation Cache), mit bcompiler kann man diesen dann aber "disassemblieren". Bei der Analyse einiger Skripte ist mir dieser Unterschied dann aufgefallen.

A2: So schnell können drei Wochen vergehen

Es war einmal vor langer Zeit, da gab es eine Vorschau auf die zweite Einzelaufgabe. Einen halben Tag später war die geforderte Funktionalität auch schon implementiert.

Dann kamen noch zwei weitere Aufgaben für Interssierte dazu, wovon ich die zweite auch bald danach umgesetzt habe. Die eigentlich einfachere erste Fleißaufgabe wollte ich dann später noch machen. Aus später wurde aber zu spät, und so fiel sie ins Wasser.

Trotzdem gibt es hier noch ein paar Gedanken und Hints dazu...

Teil 1: Files

Soweit so gut, oder auch nicht - File Uploads stellen eine gefährliche Quelle für Sicherheitslücken dar. Wer ein Bild erwartet, der sollte sicherstellen, dass auch tatsächlich ein Bild hochgeladen wurde. Sonst kann es auch sein, dass eine "Bildergallerie" plötzlich als Ablage für Warez-Archive dient (auch wenn diese Zeit seit P2P mehr oder weniger vorbei ist).

Eine solche Prüfung darf nie nur auf der Dateiendung basieren, die ist auch für Laien beliebig veränderbar. Eine Überprüfung des ContentType ist da schon eine wesentlich größere Hürde für Otto Normalsurfer, für die Absicherung gegen irrtümlich falsche Datei-Uploads sollte das ausreichen. Wer genug kriminelle Energie hat, wird sich davon aber nicht abhalten lassen und seinen Browser überreden einen falschen ContentType mitzuteilen. Für Interessierte gibt es dazu eine nette Präsentation: http://www.scribd.com/doc/2971490/Secure-PHP-Upload

Teil 2: Mehrere Alben verwalten

Mein Ansatz dazu war, jedem neu angelegten Album als ID den aktuellen Timestamp zu verpassen. Jedes Album wird in ein File persistiert, dass als Namen die ID trägt, und in einem data Verzeichnis gesammelt wird. Zur Erstellung der Liste, welche Alben vorhanden sind, wird dann einfach mit der entsprechenden PHP-Funktionen (glob) durch das Verzeichnis gewandert.

Sonntag, 2. November 2008

A2: PHP

Beim Lesen der Vorschau ist mir sofort einiges eingefallen, um das Leben (und das Programmieren) zu erleichtern.

Da wären erstens folgende beiden Funktionen zum Lesen und Schreiben einer Datei, die das File-Handling (fopen, fclose) ersparen:

Für die einzelnen Tracks braucht man nicht für jedes Formularfeld eine eigene Variable, sondern kann Arrays verwenden:

<input name="titel[0]" value="" type="text"> <input name="length[0]" value="" type="text">
...
<input name="titel[9]" value="" type="text"> <input name="length[9]" value="" type="text">

Im PHP kann dann ganz einfach über die Array-Einträge iteriert werden:
for($i=0; $i<10; $i++)
{
if($titel[$i]!="")
$album->tracks[] = new Track( $titel[$i], $length[$i] );
}

P2: Anforderungen

Die Task-Analyse war für diese Aufgabe recht schnell erledigt. Ausgehend von unserer Beschreibung der Projektidee wurde überlegt, welche einzelnen Tätigkeiten hinter den groben Forderungen ans System stecken - die Benennung (Überschriften) der Tasks war dann quasi schon fertig, und damit auch die Taskliste. Die Beschreibung der Tasks konnte aus der Überlegung der einzelnen Arbeitsschritte sowie Vor- und Nachbedingungen erledigt werden. Die UseCases waren dann eigentlich nur mehr das Umsetzen der grafischen Darstellung.

Nichtfunktionale Anforderungen laufen immer schnell Gefahr, sehr schwammig zu werden. Es stehen zwar schnell die üblichen Verdächtigen wie "Usability", "Performance" und "Wartbarkeit" im Raum, doch sind diese nicht direkt messbar. Sehr hilfreich sind an dieser Stelle Kennzahlen: Requests/Sek., Responsetime/Request, Mean Time Between Failure (MTBF), Mean Time Between Maintenance (MTBM), Mean Time To Recover (MTTR). Für die Messung der Usability haben wir das Kriterium definiert "80% der Testprobanden sollen in der Lage sein, die Aktionen Gruppenanmeldung und Prüfungsanmeldung innerhalb von einer halben Minute erfolgreich durchzuführen.".

P1: Projektidee

Zufälligerweise habe ich mich kurz vor der ersten PR-Einheit mit A4J (Ajax für JSF; ein Bestandteil der RichFaces Bibliothek) beschäftigt, wo mir auch die Komponenten a4j:push und a4j:poll untergekommen sind. Schon damals habe ich mir gedacht, dass diese Funktionalität sinnvoll für eine Anzeige freier Plätze (bei Reservierungssystemen aller Art) ist.

Die Aufforderung eine eingene Projektidee zu erstellen, kam dann gerade recht. Eine wesentliche Motivation gerade für unser Thema (LVA-Verwaltung) war die eigene Erfahrung mit ebensolchen an verschiedensten Universitäten.

An der Uni Wien gibt/gab es Univis, wo ich alle Prüfungsergebnisse ansehen kann. Zusätzlich tragen einige, aber nicht alle LVA-Leiter, die Noten auch ins PISWI ein. LVA-Anmeldungen finden entweder über das PISWI statt, oder aber im Rahmen einer Vorbesprechung, in der man sich auf eine Liste eintragen muss (einige LVA-Leiter entscheiden übrigens erst dann über einen Fixplatz anhand von Kriterien wie Studienabschnitt oder Anzahl erfolgloser Teilnahmeversuche in Vorsemestern). Die meisten - und verbindlichsten - Informationen findet man dann wiederum auf der Homepage des jeweiligen Vortragenden, vor allem wenn die LVA geblockt ist (da ist PISWI vermutlich mit der Terminverwaltung überfordert).

An der TU Wien gibt es TUWIS++, das im wesentlichen alle Funktionalitäten vom Univis und dem PISWI vereint, und noch etliches mehr bietet (Terminkalender, LVA-Evaluierung, etc). Für die meisten LVAs findet man dort alles was man braucht: Inhaltsangaben, Termine (sowohl bei Dauer- als auch bei Blockterminen), Anmeldungen zu LVA und Prüfung, ... Aus der Reihe tanzen vor allem die "Mathematiker" (Mathematik 1/2, Statistik) - sie haben eigene Homepages wo vor allem die Übungstermine angekündigt werden sowie die jeweils vorzubereitenden Beispiele. Völlig verschieden gehandhabt wird hingegen auch hier die Verbreitung der Vortragsfolien: von per USB-Stick oder Mail (bei exklusiveren LVAs im Masterstudium mit nur ~10 Teilnehmern), Institus-Homepage, Blog, und TUWEL Elearning Plattform habe ich schon alles einmal erlebt.

An der MedUni Wien existiert das Problem trotz der geringen Anzahl an Studiengängen ebenfalls, auch wenn man es ohne Kratzen an der Oberfläche nicht immer gleich merkt. Sowohl Human- als auch Zahnmedizin sind extrem "verschult". Kurz vor Semesterbeginn meldet man sich zu einer Praktikums-Kleingruppe (ca. 10 Studenten) an, und kann dann anhand der Gruppennummer im Studenplan nachsehen, wann man zu welchem Praktikum in welchem Raum erscheint (angesichts der Tatsache dass es ca. 70 Gruppen im 1. Jahr gibt eine immer aufs neue spannende Suche). Vorlesungen finden prinzipiell von Montag bis Freitag von 8-12 Uhr statt, die Themen der einzelnen Einheiten kann man fürs Ganze Jahr im Voraus dem Stundenplan entnehmen - nicht aber die Vortragenden. Da es keine Hörsäle gibt die groß genug für ca. 700 Studierende im 1. Jahr sind, werden diese auf 3 Kohorten (= 3 Hörsäle) aufgeteilt. Ist man brav, sitzt man dann im eingeteilten Hörsaal. Böse Jungs und Mädchen möchten aber manchmal lieber dem unterhaltsamsten / einprägsamsten Vortragenden lauschen. Die notwendige Information sollte man eigentlich im Vorlesungsverzeichnis finden - das Problem ist nur: die Vortragenden sind fast nie dort wo sie laut Plan sein sollten (falls es nicht überhaupt andere Vortragende sind, weil die Realität der Verfügbarkeit zB bei klinisch tätigen Professoren nicht immer der Jahresvorausplanung entspricht). Für die Pflichtlehrveranstaltungen ist das aber in der Praxis eher verschmerzbar. Jeder Medizinstudent muss aber auch noch Wahlfächer absolvieren, und hier gibt es keinen rettenden Stundenplan. Ankündigungen können im Vorlesungsverzeichnis, auf einer Institutshomepage, oder auch quasi "unter Ausschluss der modernen Öffentlichkeit" in "versteckten" Schaukästen irgendeines finsteren AKH-Gangs zu finden sein. Die Anmeldung erfolgt dann je nach Laune des Abhaltenden per Mail, persönlicher Anmeldung im Sekretariat, oder in der Vorbesprechung, die Termine richten sich oft kurzfristig nach Patientenandrang.

Dienstag, 28. Oktober 2008

A1: HTML/CSS

Da ich meine erste Webseite bereits 1998 erstellt habe, war diese Aufgabe bereits nach wenigen Minuten wieder erledigt.

Für diese Aufgabe reichte ein einfacher Editor völlig aus. Anfänger tun sich mit spezialisierteren HTML/CSS-Editoren (Highlighting, Tag-Auto-Closing, etc) sicher leichter.

Für größere Projekte, in denen auch serverseitige Skripte erstellt werden (PHP, Java, etc.) ist auch das Monster Eclipse mit entsprechenden Plugins eine interessante Option.

Wenn ich selbst einmal etwas nachschlagen muss, dann verwende ich dazu die offiziellen Spezifikationen des W3C:

Hello World

"Der erste Satz ist immer der schwerste" behaupten Autoren von Welt ebenso wie der kleine Mann. Ob jeder davon die Worte zuvor in die Waagschale geworfen hat, um diese Aussage auf ein wissenschaftliches Fundament zu stützen, ist mir leider nicht bekannt. Was mir Google jedoch verrät ist die Anzahl der Treffer zu dieser Phrase: 151 an der Zahl. Auf gerade mal ein Zehntel kommt "Der erste Satz ist immer der schwierigste". Was aber hat diese neunmalkluge Feststellung mit SWA zu tun? Nichts, außer dich für ein paar Sekunden mit einem im Vergleich zu anderen ersten Worten kreativen Text zu begrüßen, mich in dein Gedächtnis zu prägen und meinem Blog zu mehr Visits zu verhelfen, wenn du erst einmal den Eindruck gewonnen hast, hier auch zukünftig kurzweilige Kommentare zu finden. So könnte eine Begründung lauten. Eine andere wäre, hier einen Vergleich zu schaffen, dass sich oftmals nicht die "beste" Variante durchsetzt. Auch ein technisch perfektes Software-Produkt wird ohne komfortables User-Interface ins Hintertreffen geraten. Wie real die Schwierigkeit ist, Innenleben (SW-Architektur etc) und äußeres Erscheinungsbild (GUI etc) bzw. Wünsche des Auftraggebers und Rahmenbedinungen auf Auftragnehmerseite gleichermaßen unter einen Hut zu bringen (vgl. Vorlesung Kapitel 1, Seite 4ff) erlebe ich gerade bei der Realiserung des praktischen Teils meiner Diplomarbeit. Aufgrund meiner langjährigen Erfahrung habe ich alle "Anfängerprobleme" bereits hinter mir und werde daher in den Blogeinträgen zu den folgenden Übungsaufgaben eher weiterführende Themen anreißen, um aufzuzeigen wie man sich durch geschickten Einsatz von Tools und Bibliotheken das Leben wesentlich erleichtern kann.