/** Beispiel fuer die sofortige Umsetzung eines Analysemodells in ein  lauffaehiges Java-Programm.  "TerminvTreeSeterwaltung" zur Vorlesung  "Softwaretechnologie".  (c) Heinrich Hussmann, TU Dresden 1997-2000 */      /** Die Klasse Hour dient dazu, in relativ einfacher Weise Datumsangaben zu * benutzen. Es gibt vordefinierte Klassen in Java, die bei fortgeschrittener * Programmierung geeigneter waeren!  Hier besteht eine Stundenangabe aus * zwei int-Zahlen fuer den Tag und die Stunde.  * @author Heinrich Hussmann * @date 1997-2000 */ class Hour {    private int tag;    private int std;	    public Hour (int tag, int std) {	this.tag = tag;	this.std = std;    }	    /** Die Operation inKonflikt() wird weiter unten benoetigt, um die     * Ueberschneidung zwischen zwei Terminen festzustellen, die jeweils     * durch eine "Hour" und eine Dauer gegeben sind. */    static public boolean inKonflikt (Hour aBeginn, int aDauer, Hour bBeginn, int bDauer) {	if (aBeginn.tag != bBeginn.tag)	    return false;	else 	    if (aBeginn.std == bBeginn.std)		return true;	    else		if (aBeginn.std < bBeginn.std)		    return (aBeginn.std+aDauer > bBeginn.std);		else		    return (bBeginn.std+bDauer > aBeginn.std);    }	    public String toString() {	return "[Tag "+tag+" Std "+std+"]";    }}/** Die Material-Klasse Termin aus dem Analyse-Modell der Vorlesung. */abstract class Termin {    protected String titel;    protected Hour beginn;    protected int dauer; 	    public abstract boolean verschieben (Hour neu);	    public boolean inKonflikt (Hour angDatum, int angDauer) {	return Hour.inKonflikt(beginn, dauer, angDatum, angDauer);    }	    public Termin (String titel, Hour beginn) {	this.titel = titel;	this.beginn = beginn;    }	    public Termin (String titel, Hour beginn, int dauer) {	this(titel, beginn);	this.dauer = dauer;    }	    public String toString() {	return "titel = "+titel+", beginn = "+beginn+", dauer = "+dauer;    }}/** Die Klasse Privater Termin aus dem Analyse-Modell der Vorlesung */class PrivTermin extends Termin {    private String ort;    private int wegzeit;    private Teammitglied fuer;	    /** Fuer private Termine wird hier die Operation verschieben() der Oberklasse Termin	so ueberdefiniert, dass keinerlei Ueberpruefungen durchgefuehrt werden. */    public boolean verschieben (Hour neu) {	this.beginn = neu;	return true;    }	    public PrivTermin (String titel, Hour beginn, int dauer, String ort, int wegzeit) {	super(titel, beginn, dauer);	this.ort = ort;	this.wegzeit = wegzeit;    }}/** Die Klasse Teambesprechung aus dem Analyse-Modell der Vorlesung */class Teambesprechung extends Termin {    private Teammitglied[] teilnahme; // Assoziation aufgeloest mittels Array    private Besprechungsraum veranstOrt; 	    /** Die private Operation abstimmen() dient dazu, Terminkonflikte	mit anderen fuer die Teilnehmer bestehenden Terminen	festzustellen.  Zu Testzwecken wird bei Auftreten eines	Terminkonflikts eine Meldung ausgegeben. */    private boolean abstimmen (Hour beginn, int dauer) {	boolean ok = true;	for (int i=0; i<teilnahme.length; i++) {	    ok = ok && teilnahme[i].terminBestaetigen(beginn, dauer);	    if (!ok)		System.out.println("Terminkonflikt fuer "+titel+" bei "+teilnahme[i]+" !");	};	return ok;    }	    void raumFestlegen () {	int teilnAnz = teilnahme.length;	Besprechungsraum r = Raumverwaltung.freienRaumSuchen(teilnAnz, beginn, dauer);	if (r != null) {	    r.reservieren(this); // Hierdurch wird die Referenz beim Raum r auf this gesetzt.	    veranstOrt = r; // Hier wird die lokale Referenz auf r gesetzt. 	}	else	    System.out.println("Kein passender Raum gefunden fuer Besprechung am: "+beginn);    }	    /** Fuer Teambesprechung wird die Operation verschieben() der	Oberklasse Termin so ueberdefiniert, dass eine Verschiebung	nur stattfindet, wenn kein Terminkonflikt vorliegt. */    public boolean verschieben (Hour neu) {	boolean ok = abstimmen(neu, dauer);	if (ok) {	    beginn = neu;	    raumFestlegen();	};	return ok;    }	    public Teambesprechung (String titel, Hour beginn, int dauer, Teammitglied[] teilnehmer) {	super(titel, beginn, dauer);	this.teilnahme = teilnehmer;	if (! abstimmen(beginn, dauer))	    System.out.println("Termin bitte verschieben!");	else	    for (int i=0; i<teilnahme.length; i++)		teilnahme[i].teilnahmeSetzen(this);    }	    public String toString() {	return "Teambesprechung ("+super.toString()+", Anzahl Teiln. = "+teilnahme.length+", "+	    (veranstOrt!=null?"Raum ="+veranstOrt.toString():"Kein Raum festgelegt")+")";    }}/** Die Material-Klasse Besprechungsraum aus dem Analysemodell der Vorlesung */class Besprechungsraum {    private static final int maxReserv = 100; // Vereinfachung:maximal 100 Reservierungen    // In diesem Fall sind Arrays relativ unguenstig, bessere    // Realisierungen sh. Kapitel Collections !    private String raumNr;    private int kapazitaet;    private Teambesprechung[] reserv; // Assoziation zu den Teambesprechungen, fuer die der Raum reserviert wurde	    private int numReserv = 0; // Anzahl derzeit eingetragener Reservierungen in fuer-Array	    boolean grossGenug (int persAnz) {	return persAnz <= kapazitaet;    }    /** Die Operation frei() wird von der Raumverwaltung benoetigt, um einen gegebenen Besprechungsraum	abfragen zu koennen, ob er zu einem bestimmten zeitraum frei ist. */    public boolean frei (Hour angDatum, int angDauer) {	boolean konflikt = false;	int i = 0;	while (i < numReserv && !konflikt) {	    if (reserv[i].inKonflikt(angDatum, angDauer)) 		konflikt = true;	    else		i++;	};	return !konflikt;    }		    public void reservieren (Teambesprechung fuer) {	reserv[numReserv] = fuer;	numReserv++;    }	    public Besprechungsraum (String raumNr, int kapazitaet) {	this.raumNr = raumNr;	this.kapazitaet = kapazitaet;	this.reserv = new Teambesprechung[maxReserv];	Raumverwaltung.anmelden(this);    };	    public String toString() {	return "Besprechungsraum (Nr = "+raumNr+", Kapazitaet = "+kapazitaet+")";    }}		/** Raumverwaltung ist eine zusaetzliche Klasse zum Analysemodell der Vorlesung    zur Realisierung der Funktionen, die alle Raeume kennen muessen */class Raumverwaltung {    private static final int maxRaeume = 10;    private static Besprechungsraum[] vorhandeneRaeume; // Vereinfachung: maximal 10 Raeume    private static int anzRaeume = 0;	    public static Besprechungsraum freienRaumSuchen (int groesse, Hour beginn, int dauer) {	boolean found = false;	int i = 0;	while (!found && i<anzRaeume) {	    if (vorhandeneRaeume[i].grossGenug(groesse) && vorhandeneRaeume[i].frei(beginn, dauer)) 		found = true;	    else 		i++;	};	if (found)	    return vorhandeneRaeume[i];	else	    return null;    }	    public static void anmelden (Besprechungsraum r) {	if (anzRaeume == maxRaeume)	    System.out.println("Fehler: zu viele Raeume!");	else	    if (vorhandeneRaeume == null)		vorhandeneRaeume = new Besprechungsraum[maxRaeume];	vorhandeneRaeume[anzRaeume] = r;	anzRaeume++;    }}				/** Die Klasse Teammitglied aus dem Analysemodell der Vorlesung */class Teammitglied {    private static final int maxTeilnahme = 10; // Vereinfachung: Max. 10 Besprechungsteilnahmen    // Vereinfachung noetig, um mit Arrays arbeiten zu koennen, bessere Loesungen sh. spaeter !	    private String name;    private String abteilung;    private Teambesprechung[] teilnahme; // Assoziation realisiert als Array    private PrivTermin[] privateTermine; // Nicht weiter ausgefuehrt	    private int anzahlBesprechungen = 0;		    public boolean terminBestaetigen (Hour beginn,int dauer) {	boolean konflikt = false;	int i = 0;	while (i < anzahlBesprechungen && !konflikt) {	    if (teilnahme[i].inKonflikt(beginn, dauer))		konflikt = true;	    else		i++;	};	return !konflikt;    }		    /** Die Operation teilnahmeSetzen() wird von Teambesprechung benoetigt,	um eine korrekte Realisierung der bidirektionalen	Teilnahme-Assoziation sicherzustellen. */    public void teilnahmeSetzen (Teambesprechung b) {	teilnahme[anzahlBesprechungen] = b;	anzahlBesprechungen++;    }	    public Teammitglied (String name, String abteilung) {	this.name = name;	this.abteilung = abteilung;	this.teilnahme = new Teambesprechung[maxTeilnahme];    }	    public String toString() {	return "Teammitglied (Name = "+name+", Abt. = "+abteilung+")";    }}/** Das Hauptprogramm des kleinen Informationssystems besteht aus einer Reihe    typischer Testfaelle fuer die Funktionen der TerminvTreeSeterwaltung. */class TerminvTreeSet {    public static void main (String argv[]) {			Besprechungsraum r1 = new Besprechungsraum("R1", 10);	System.out.println(r1);	Besprechungsraum r2 = new Besprechungsraum("R2", 20);	System.out.println(r2);	Teammitglied mm = new Teammitglied("Max Mueller", "Abt. A");	System.out.println(mm);	Teammitglied es = new Teammitglied("Eva Schmidt", "Abt. B");	System.out.println(es);	Teammitglied fm = new Teammitglied("Fritz Maier", "Abt. B");	System.out.println(fm);	Teammitglied hb = new Teammitglied("Hans Bauer", "Abt. A");	System.out.println(hb);	Hour t1s5 = new Hour(1,5);	Hour t2s3 = new Hour(2,3);	Hour t2s4 = new Hour(2,4);	Teammitglied[] teilnTb1 = {mm, es};	Teambesprechung tb1 = new Teambesprechung("Besprechung 1", t1s5, 2, teilnTb1);	System.out.println(tb1);	tb1.raumFestlegen();	System.out.println(tb1);	Teammitglied[] teilnTb2 = {mm, fm};	Teambesprechung tb2 = new Teambesprechung("Besprechung 2", t2s3, 2, teilnTb2);	System.out.println(tb2);	tb2.raumFestlegen();	System.out.println(tb2);	Teammitglied[] teilnTb3 = {es, fm};	Teambesprechung tb3 = new Teambesprechung("Besprechung 3", t2s4, 2, teilnTb3);	System.out.println(tb3);	tb3.raumFestlegen();	System.out.println(tb3);	Teammitglied[] teilnTb4 = {es, hb};	Teambesprechung tb4 = new Teambesprechung("Besprechung 4", t2s4, 1, teilnTb4);	System.out.println(tb4);	tb4.raumFestlegen();	System.out.println(tb4);    }}