Laborator 8

Obiective

Intelegerea mecansimului de tratare a erorilor. Intelegerea modului in care in Java pot fi manipulate fluxurile de intrare\iesire.

Aspecte teoretice

Exercitii

Se da aplicatia Java de mai jos ce modeleaza un simulator de trafic feroviar simplificat

package tren;
 
import java.util.*;
 
public class Simulator {
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
 
		//construieste gara Cluj-Napoca
		Controler c1 = new Controler("Cluj-Napoca");
 
		Segment s1 = new Segment(1);
		Segment s2 = new Segment(2);
		Segment s3 = new Segment(3);
 
		c1.adaugaSegmentControlat(s1);
		c1.adaugaSegmentControlat(s2);
		c1.adaugaSegmentControlat(s3);
 
		//construieste gara Bucuresti
		Controler c2 = new Controler("Bucuresti");
 
		Segment s4 = new Segment(4);
		Segment s5 = new Segment(5);
		Segment s6 = new Segment(6);
 
		c2.adaugaSegmentControlat(s4);
		c2.adaugaSegmentControlat(s5);
		c2.adaugaSegmentControlat(s6);
 
		//conecteaza cele 2 controlere
 
		c1.seteazaControlerVecin(c2);
		c2.seteazaControlerVecin(c1);
 
		//testare
 
		Tren t1 = new Tren("Bucuresti", "IC-001");
		s1.adaugaTren(t1);
 
		Tren t2 = new Tren("Cluj-Napoca","R-002");
		s5.adaugaTren(t2);
 
 
		c1.afiseazaStareGara();
		c2.afiseazaStareGara();
 
		System.out.println("\nSTART CONTROL TRENURI\n");
 
 
		//exceuta de 3 ori algorimul de control pentru cele 2 gari. dupa fiecare executie afiseaza starea garilor
		for(int i = 0;i<3;i++){
			System.out.println("### Pas "+i+" ###");
			c1.controlTrenuri();
			c2.controlTrenuri();
 
			System.out.println();
 
			c1.afiseazaStareGara();
			c2.afiseazaStareGara();
		}		
	}
 
}
 
class Controler{
 
	String numeGara;
 
	Controler vecin;
 
	//lista de segmente controlate de acest controler (sunt liniile din gara)
	ArrayList<Segment> list = new ArrayList<Segment>(); 
 
	public Controler(String gara) {
		numeGara = gara;
	}
 
	void seteazaControlerVecin(Controler v){
		vecin = v;
	}
 
	void adaugaSegmentControlat(Segment s){
		list.add(s);
	}
 
	/**
	 * Verifica segmentele controlerului si returneaza id-ul primul segment liber sau -1 in cazul in care nu este nisi un segment liber.
	 * @return
	 */
	int citesteSegmentLiber(){
		for(Segment s:list){
			if(s.areTren()==false)
				return s.id;
		}
		return -1;
	}
 
	void controlTrenuri(){
			//verific ce tren trebuie sa trimit (caut pe segmente trenuri ce au ca destinatie gara vecina)
 
			for(Segment segment:list){
				if(segment.areTren()){
					Tren t = segment.citesteTren();
 
					//daca gara destinatie este aceiasi cu cea controlata de controlerul vecin tirmit trenul
					if(t.citesteGaraDestinatie().equals(vecin.numeGara)){
						//verific in controlerul vecin daca am segment liber
						int id = vecin.citesteSegmentLiber();
						if(id==-1){
							System.out.println("Trenul +"+t.nume+"din gara "+numeGara+" nu poate fi trimis catre "+vecin.numeGara+". Nici un segment disponibil!");
							return;
						}
						//trimit trenul
						System.out.println("Trenul "+t.nume+" pleaca din gara "+numeGara +" spre gara "+vecin.numeGara);
						segment.pleacaTren();
						vecin.sosesteTren(t,id);
					}
 
				}
			}//.for
 
		}//.meoda
 
 
	public void sosesteTren(Tren t, int idSegment){
		for(Segment segment:list){
			//cauta segmentul cu id-ul idSegment si adauga trenul
			if(segment.id == idSegment)
				if(segment.areTren()==true){
					System.out.println("ACCIDENT! Trenul "+t.nume+" A intrat in coliziune cu trenul "+segment.citesteTren().nume+" pe segmentul "+segment.id+" in gara "+numeGara);
					return;
				}else{
					System.out.println("Trenul "+t.nume+" a sosit pe segmentul "+segment.id+" in gara "+numeGara);
					segment.adaugaTren(t);
					return;
				}			
		}
 
		//daca am ajuns aici inseamna ca nu am putut adauga trenul din cauza unei erori de logica 
		System.out.println("Trenul "+t.nume+" nu a putut fi preluat pe nici un segment in gara "+numeGara+". Trenul este garat in depou!");
 
	}
 
 
	public void afiseazaStareGara(){
		System.out.println("=== GARA "+numeGara+" ===");
		for(Segment s:list){
			if(s.areTren())
				System.out.println("|----------ID="+s.id+"__Tren="+s.citesteTren().nume+" catre "+s.citesteTren().destinatie+"__----------|");
			else
				System.out.println("|----------ID="+s.id+"__TREN=______ catre ________----------|");
		}
	}
}
 
 
class Segment{
	int id;
	Tren tren;
 
	Segment(int id){
		this.id = id;
	}
 
	boolean areTren(){
		return tren!=null;
	}
 
	Tren pleacaTren(){
		Tren tmp = tren;
		this.tren = null;
		return tmp;
	}
 
	void adaugaTren(Tren t){
		tren = t;
	}
 
	Tren citesteTren(){
		return tren;
	}
}
 
class Tren{
	String destinatie;
	String nume;
 
	public Tren(String destinatie, String nume) {
		super();
		this.destinatie = destinatie;
		this.nume = nume;
	}
 
	String citesteGaraDestinatie(){
		return destinatie;
	}
 
}

English version of train controller is bellow:

import java.util.*;
 
public class Simulator {
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
 
		//build station Cluj-Napoca
		Controler c1 = new Controler("Cluj-Napoca");
 
		Segment s1 = new Segment(1);
		Segment s2 = new Segment(2);
		Segment s3 = new Segment(3);
 
		c1.addControlledSegment(s1);
		c1.addControlledSegment(s2);
		c1.addControlledSegment(s3);
 
		//build station Bucuresti
		Controler c2 = new Controler("Bucuresti");
 
		Segment s4 = new Segment(4);
		Segment s5 = new Segment(5);
		Segment s6 = new Segment(6);
 
		c2.addControlledSegment(s4);
		c2.addControlledSegment(s5);
		c2.addControlledSegment(s6);
 
		//connect the 2 controllers
 
		c1.setNeighbourController(c2);
		c2.setNeighbourController(c1);
 
		//testing
 
		Train t1 = new Train("Bucuresti", "IC-001");
		s1.arriveTrain(t1);
 
		Train t2 = new Train("Cluj-Napoca","R-002");
		s5.arriveTrain(t2);
 
 
		c1.displayStationState();
		c2.displayStationState();
 
		System.out.println("\nStart train control\n");
 
                //execute 3 times controller steps
		for(int i = 0;i<3;i++){
			System.out.println("### Step "+i+" ###");
			c1.controlStep();
			c2.controlStep();
 
			System.out.println();
 
			c1.displayStationState();
			c2.displayStationState();
		}		
	}
 
}
 
class Controler{
 
	String stationName;
 
	Controler neighbourController;
 
	//storing station train track segments
	ArrayList<Segment> list = new ArrayList<Segment>(); 
 
	public Controler(String gara) {
		stationName = gara;
	}
 
	void setNeighbourController(Controler v){
		neighbourController = v;
	}
 
	void addControlledSegment(Segment s){
		list.add(s);
	}
 
	/**
         * Check controlled segments and return the id of the first free segment or -1 in case there is no free segment in this station
         * 
	 * @return
	 */
	int getFreeSegmentId(){
		for(Segment s:list){
			if(s.hasTrain()==false)
				return s.id;
		}
		return -1;
	}
 
	void controlStep(){
			//check which train must be sent
 
			for(Segment segment:list){
				if(segment.hasTrain()){
					Train t = segment.getTrain();
 
					if(t.getDestination().equals(neighbourController.stationName)){
						//check if there is a free segment
						int id = neighbourController.getFreeSegmentId();
						if(id==-1){
							System.out.println("Trenul +"+t.name+"din gara "+stationName+" nu poate fi trimis catre "+neighbourController.stationName+". Nici un segment disponibil!");
							return;
						}
						//send train
						System.out.println("Trenul "+t.name+" pleaca din gara "+stationName +" spre gara "+neighbourController.stationName);
						segment.departTRain();
						neighbourController.arriveTrain(t,id);
					}
 
				}
			}//.for
 
		}//.
 
 
	public void arriveTrain(Train t, int idSegment){
		for(Segment segment:list){
			//search id segment and add train on it
			if(segment.id == idSegment)
				if(segment.hasTrain()==true){
					System.out.println("CRASH! Train "+t.name+" colided with "+segment.getTrain().name+" on segment "+segment.id+" in station "+stationName);
					return;
				}else{
					System.out.println("Train "+t.name+" arrived on segment "+segment.id+" in station "+stationName);
					segment.arriveTrain(t);
					return;
				}			
		}
 
		//this should not happen
		System.out.println("Train "+t.name+" cannot be received "+stationName+". Check controller logic algorithm!");
 
	}
 
 
	public void displayStationState(){
		System.out.println("=== STATION "+stationName+" ===");
		for(Segment s:list){
			if(s.hasTrain())
				System.out.println("|----------ID="+s.id+"__Train="+s.getTrain().name+" to "+s.getTrain().destination+"__----------|");
			else
				System.out.println("|----------ID="+s.id+"__Train=______ catre ________----------|");
		}
	}
}
 
 
class Segment{
	int id;
	Train train;
 
	Segment(int id){
		this.id = id;
	}
 
	boolean hasTrain(){
		return train!=null;
	}
 
	Train departTRain(){
		Train tmp = train;
		this.train = null;
		return tmp;
	}
 
	void arriveTrain(Train t){
		train = t;
	}
 
	Train getTrain(){
		return train;
	}
}
 
class Train{
	String destination;
	String name;
 
	public Train(String destinatie, String nume) {
		super();
		this.destination = destinatie;
		this.name = nume;
	}
 
	String getDestination(){
		return destination;
	}
 
}

1. Realizati diagrama UML de clase pentru aplicatia simulator de trafic feroviar.

2. Modificati aplicatia simulator de trafic feroviar pentru a permite unui controler de gara sa comunice cu oricate controlere de gara invecinate. Adaugat in clasa main o structura de gari care sa valideze modificarea realizate.

3. Testati aplicatia CofeeTest din sectiunea Tratarea erorilor. În varianta curentă clasa CofeeMaker este astfel construită încât permite generarea unui numar infinit de obiecte de tip Cofee. Modificaţi aplicaţia astfel încât un CofeeMaker să permită crearea unui număr limitat de obiecte de tip Cofee, şi în momentul în care acest număr limită a fost atins, metoda makeCofee() să returneze o excepţie specifică.

4. Testati aplicatiile din sectiunea Fluxuri de intrare\iesire

5. Realizati o aplicatie care citeste de la tastatura linii de text si le scrie intr-un fisier. Programul se termina in momentul in care utilizatorul introduce de la tastatura textul 'exit' urmat de caracterul de linie noua.

6. Realizati o aplicatie care citeste continutul unui fisier, linie cu linie, si il afiseaza pe ecran. Numele fisierului este introdus de utilizator de la tastatura.