Auf den Rückgabeprozess wird in diesem Tutorial nicht weiter eingegangen. Die Implementation ähnelt stark der des Ausleihprozesses. Der Aufwand ist sogar um einiges geringer, da weniger Interaktion mit dem Kunden stattfindet.
Die in der Aufgabenstellung erwähnte, gesetzliche Forderung nach der Aufzeichnung der Leihvorgänge soll in diesem Kapitel umgesetzt werden. Hilfreich dafür sind die im Paket Log
zusammengefassten Klassen des Frameworks.
Log-Einträge
Im Kapitel Der Ausleihprozess wurde durch die Definition einer globalen Protokolldatei bereits eine wichtige Grundlage geschaffen. Diese Datei soll für die Aufzeichnung des Verleihs, sowie der Rückgabe von Videos benutzt werden.
Einträge einer Protokolldatei werden über die Klasse LogEntry
realisiert. Objekte dieser Klasse können über entsprechende Methoden eine Bezeichnung und ein Datum zurückgeben.
Es wird zunächst eine neue Klasse definiert, die von LogEntry
abgeleitet wird. Diese Klasse soll die Protokolleinträge für die Verleih- und Rückgabeereignisse repräsentieren. Die beiden vordefinierten Methoden der Oberklasse werden überschrieben. Dem Konstruktor der neuen Klasse muss der Nutzername und der Titel des Videos, sowie eine boolesche Variable übergeben werden. Die Variable dient der Erkennung, ob es sich um den Verleih oder die Rückgabe eines Videos handelt. Außerdem wird im Konstruktor einer dafür vorgesehenen Variablen die Zeit der Erzeugung zugewiesen.
package videoautomat; public class LogEntryVideo extends LogEntry { private static final long serialVersionUID = 1373171045602909791L; private String user_ID; private String video_name; private boolean rented; private Date date; public LogEntryVideo(String user_ID, String video, boolean rented) { this.user_ID = user_ID; this.video_name = video; this.rented = rented; date = (Date) Shop.getTheShop().getTimer().getTime(); } public String toString() { String s = " gave back "; if (rented) s = " has rented "; return ("The user " + user_ID + s + video_name); } public Date getLogDate() { return date; } }
Die Methode toString
liefert die Beschreibung des zu protokollierenden Ereignisses, getLogDate()
die Zeit.
Wie bereits im Kapitel Der Ausleihprozess angesprochen, werden Protokolldateien durch die Klasse Log
repräsentiert. Die Protokolleinträge können aber nicht direkt an ein solches Log
-Objekt übergeben werden. Es existiert jedoch eine Methode log(Loggable l)
, mit der indirekt über ein Loggable
-Objekt Protokolleinträge erzeugt und dem Protokolldateistrom zugefügt werden können. Loggable
ist ein Interface, dessen einzige Methode den Protokolleintrag zurückgeben muss, der hinzugefügt werden soll. Entsprechend wird das Interface wie folgt implementiert.
package videoautomat; public class LoggableImpl implements Loggable, Serializable { private static final long serialVersionUID = 1859861011358753928L; private String user_ID; private String video_name; private boolean rented; public LoggableImpl(String user_ID, String video, boolean rented) { this.user_ID = user_ID; this.video_name = video; this.rented = rented; } public LogEntry getLogData() { return new LogEntryVideo(user_ID, video_name, rented); } }
Ein Zuhörer schreibt mit
Mit Hilfe der neuen Klassen kann die Protokollierung erfolgen. Die Frage ist jedoch, an welcher Stelle des Programms in die Datei geschrieben werden soll. Eine naheliegende Antwort wäre im Ausleih- bzw. Rückgabeprozess. Allerdings dürfte erst dann protokolliert werden, wenn der Vorgang wirklich abgeschlossen ist und keine Möglichkeit eines Abbruchs besteht. Der einfachere Weg führt wieder einmal zum Zuhörer-Schema. Ein StockChangeListener
der auf endgültige Hinzufügen- und Entfernen-Ereignisse eines Kundenbestands reagiert, kann die Protokollierung problemlos durchführen.
Es wird eine neue Klasse als Ableitung von StockChangeAdapter
implementiert, wobei die Methoden, die in Folge des endgültigen Hinzufügens bzw. Entfernens von Elementen angesprochen werden, überschrieben werden müssen.
package videoautomat; public class StockChangeLogger extends StockChangeAdapter { private static final long serialVersionUID = -6031309005059652445L; private String user_ID; public StockChangeLogger(String user_ID) { this.user_ID = user_ID; } public void commitAddStockItems(StockChangeEvent event) { Iterator it = event.getAffectedItems(); while (it.hasNext()) { try { Log.getGlobalLog().log( new LoggableImpl( user_ID, ((StockItem) it.next()).getName(), true)); } catch (LogNoOutputStreamException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } public void commitRemoveStockItems(StockChangeEvent event) { Iterator it = event.getAffectedItems(); while (it.hasNext()) { try { Log.getGlobalLog().log( new LoggableImpl( user_ID, ((StockItem) it.next()).getName(), false)); } catch (LogNoOutputStreamException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } }
Der Zuhörer muss noch dem Bestand des Kunden bekannt gemacht werden. Der Konstruktor der Klasse AutomatUser
wird dafür um folgende Zeile ergänzt.
public class AutomatUser extends User { . . . public AutomatUser(String user_ID, char[] passWd, boolean admin) { super(user_ID); setPassWd(garblePassWD(passWd)); ss_videos = new UserVideoStock(user_ID, VideoShop.getVideoCatalog()); ss_videos.addStockChangeListener(new StockChangeLogger(user_ID)); } . . . }
Die Protokollierung ist damit vollständig implementiert. Im letzten Kapitel soll gezeigt werden, wie man sich den Inhalt der Protokolldatei anzeigen lassen kann.
Der Ausleihprozess | Das Protokoll ansehen |