package model; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import main.error.VideothekException; import model.data.exceptions.RecordNotFoundException; import model.events.EventManager; import model.events.VideoUnitCreatedEvent; import model.events.VideoUnitDeletedEvent; import model.exceptions.EmptyFieldException; import model.exceptions.FalseIDException; /** * VideoUnit.java * * @author Christopher Bertels (chbertel@uos.de) * @date 15.09.2008 * * Klasse für alle VideoUnits (Video-Exemplare). */ public class VideoUnit { private int uID; private int videoID; private boolean deleted = false; private static Map<Integer, VideoUnit> videoUnitList; private static Map<Integer, Collection<VideoUnit>> unitToVideoMap; private static int minuID; /** * Öffentlicher Konstruktor für VideoUnits (VideoExemplare). * * @param video Das Video, zu dem das Exemplar gehört. */ public VideoUnit(Video video) { this(minuID, video.getID()); minuID++; videoUnitList.put(this.uID, this); addToUnitToVideoMap(this); // Event feuern EventManager.fireEvent(new VideoUnitCreatedEvent(this)); } /** * Privater Konstruktor für VideoUnits. * * @param uID Die UnitID. * @param videoID Die VideoID des Videos, zu dem das VideoUnit gehört. */ private VideoUnit(int uID, int videoID) { this.uID = uID; this.videoID = videoID; } /** * Gibt die ID des VideoUnit zurück. * * @return Die ID des VideoUnit. */ public int getID() { return this.uID; } /** * Gibt an, ob das VideoExemplar ausgeliehen werden kann. Ist dann der Fall, wenn * es nicht ausgeliehen und nicht gelöscht wurde. * * @return True, falls ja, sonst False. */ public boolean canBeRented() { return !isRented() && !isDeleted(); } /** * Gibt an, ob dieses VideoExemplar von einem angegebenen Kunden ausgeliehen * werden kann. Das ist dann der Fall, wenn das VideoExemplar ausleihbar ist * (canBeRented()) und der Kunde die Altersbeschränkung erfüllt. * * @param customer Der Kunde, der den Film ausleihen möchte. * @return True, falls der Kunde den Film ausleihen kann, False sonst. */ public boolean canBeRentedBy(Customer customer) { return (canBeRented() && customer.getAge() >= this.getVideo() .getRatedAge()); } /** * Gibt zurück, ob das VideoUnit ausgeliehen ist oder nicht. * * @return True, falls ausgeliehen, False sonst.y */ public boolean isRented() { try { InRent ir = InRent.findByVideoUnit(this); if (ir != null) { return true; } } catch (RecordNotFoundException ex) { return false; } return false; } /** * Gibt das InRent Objekt zu diesem VideoUnit zurück, falls ausgeliehen. * * @return Das InRent Objekt (falls vorhanden/VideoUnit ausgeliehen) oder * null (sonst) zurück. */ public InRent getInRent() { InRent ir; try { ir = InRent.findByVideoUnit(this); } catch (RecordNotFoundException e) { return null; } return ir; } /** * Gibt die VideoID des Videos des VideoUnits zurück. * * @return Die VideoID des zugehörigen Videos. */ public int getVideoID() { return this.videoID; } /** * Gibt das zugehörige Video zurück. * * @return Das Video des VideoUnits. */ public Video getVideo() { try { return Video.findByID(this.videoID); } catch (RecordNotFoundException e) { return null; } } /** * Entfernt VideoUnit aus globaler VideoUnit-Liste. Wird beim nächsten * Speichern nicht mehr mitgespeichert und geht somit verloren. * Falls dieses VideoUnit das letzte des zugehörigen Videos ist, * wird das Video mitgelöscht. * * @throws VideothekException */ public void delete() throws VideothekException { if (!this.isRented()) { videoUnitList.remove(this.getID()); unitToVideoMap.get(this.videoID).remove(this); this.deleted = true; // falls dieses exemplar das letzte ist, // kann auch der gesamte film gelöscht werden... if(this.getVideo().getVideoUnits().size() == 0) { this.getVideo().delete(); } // Event feuern EventManager.fireEvent(new VideoUnitDeletedEvent(this)); } else throw new VideothekException( "Videoexemplar ist noch verliehen. Löschen nicht möglich!"); } /** * Gibt an, ob das Objekt gelöscht wurde (via delete()) * * @return True, falls gelöscht, False sonst. */ public boolean isDeleted() { return this.deleted; } /** * Gibt eine String-Repräsentation des VideoUnits zurück. */ public String toString() { String rented = isRented() ? "ausgeliehen" : "verfügbar"; return this.uID + " (" + rented + ")"; } /** * Gibt das zur übergebenen VideoUnitID zugehörige VideoUnit zurück, falls * vorhanden. * * @param videoUnitID Die ID des zu suchenden VideoUnit. * @return Das VideoUnit Objekt, das zur angegebenen ID gehört. * @throws RecordNotFoundException Wird geworfen, falls kein solches * VideoUnit Objekt existiert. */ public static VideoUnit findByID(int videoUnitID) throws RecordNotFoundException { if (videoUnitList.containsKey(videoUnitID)) { return videoUnitList.get(videoUnitID); } else { throw new RecordNotFoundException("VideoExemplar", "ExemplarNummer", videoUnitID); } } /** * Gibt die Menge aller VideoUnits in der Datenbasis zurück. * * @return Die Menge aller VideoUnits. */ public static Collection<VideoUnit> findAll() { return videoUnitList.values(); } /** * Gibt die Menge der VideoUnits zurück, deren Rented-Wert dem übergebenen * entspricht. * * @param isRented Die Angabe, ob nach VideoUnits gesucht werden soll, die * entweder ausgeliehen (true) oder nicht (false) sind. * @return Die Menge der VideoUnits, die dem Kriterium entsprechen. */ public static Collection<VideoUnit> findByRented(boolean isRented) { Collection<VideoUnit> foundVideoUnits = new LinkedList<VideoUnit>(); for (VideoUnit unit : videoUnitList.values()) { if (unit.isRented() == isRented) { foundVideoUnits.add(unit); } } return foundVideoUnits; } /** * Gibt die Menge der VideoUnits zurück, die zu einem angegebenen Video * geören. * * @param video Das Video, deren VideoUnits gesucht werden. * @return Die Menge der VideoUnits, die zu dem Video gehören. */ public static Collection<VideoUnit> findByVideo(Video video) { if (unitToVideoMap.containsKey(video.getID())) { return unitToVideoMap.get(video.getID()); } else { // falls keine VideoUnits vorhanden, leere Liste zurückgeben return new LinkedList<VideoUnit>(); } } /** * Gibt eine Menge von VideoUnits zurück, die zu einem angegebenen InRent * gehören. * * @param inRent Das InRent (die Ausleihe), deren VideoUnits gesucht werden. * @return Die Menge der VideoUnits, die zu diesem InRent gehören. */ public static Collection<VideoUnit> findByInRent(InRent inRent) { Collection<VideoUnit> foundVideoUnits = new LinkedList<VideoUnit>(); for (VideoUnit unit : findAll()) { if (unit.getInRent() == inRent) { foundVideoUnits.add(unit); } } return foundVideoUnits; } /** * Setzt die MinID für VideoUnits. * * @param newMinuID Die neue MinID für VideoUnits. * @throws FalseIDException */ public static void setMinID(int newMinuID) throws FalseIDException { if (newMinuID > 0) { minuID = newMinuID; } else { throw new FalseIDException( "Übergebene MinID für VideoUnit ist kleiner 0!!!"); } } /** * Soll gespeicherte VideoUnits aus der xml-Datei erzeugen * @param uID Filmexemplarnummer * @param videoID Nummer des zugehörigen Films * @return */ public static VideoUnit reCreate(int uID, int videoID) { return new VideoUnit(uID, videoID); } /** * Setzt die VideoUnit Liste, sodass sie global verfügbar wird. * * @param newVideoUnitList Die Liste der geladenen VideoUnits. * @throws EmptyFieldException wird geworfen, wenn Paramter null */ public static void setVideoUnitList(Map<Integer, VideoUnit> newVideoUnitList) throws EmptyFieldException { if (newVideoUnitList != null) { videoUnitList = newVideoUnitList; unitToVideoMap = new HashMap<Integer, Collection<VideoUnit>>(); for (VideoUnit unit : newVideoUnitList.values()) { addToUnitToVideoMap(unit); } } else throw new EmptyFieldException("VideoUnitList ist null!!"); } /** * Gibt die aktuelle MinID für VideoUnits zurück. * * @return Die aktuelle MinID für VideoUnits. */ public static int getMinID() { return minuID; } /** * Fügt ein VideoUnit zur unitToVideoMap hinzu. * * @param unit Die VideoUnit, die hinzugefügt werden soll. */ private static void addToUnitToVideoMap(VideoUnit unit) { if (unitToVideoMap == null) unitToVideoMap = new HashMap<Integer, Collection<VideoUnit>>(); if (unitToVideoMap.containsKey(unit.videoID)) { unitToVideoMap.get(unit.videoID).add(unit); } else { LinkedList<VideoUnit> newList = new LinkedList<VideoUnit>(); newList.add(unit); unitToVideoMap.put(unit.videoID, newList); } } }