This commit is contained in:
JunkJumper 2020-10-14 13:59:30 +02:00
parent 5ad90deb63
commit 5da7508ac7
20 changed files with 1275 additions and 53 deletions

View File

@ -3,6 +3,7 @@ package TD2;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ForumManager { public class ForumManager {
private List<Forum> l; private List<Forum> l;
@ -33,4 +34,6 @@ public class ForumManager {
return this.l; return this.l;
} }
} }

View File

@ -64,118 +64,186 @@
<operations public="true" package="true" protected="true" private="true" static="true"/> <operations public="true" package="true" protected="true" private="true" static="true"/>
</display> </display>
</class> </class>
<association id="8"> <class id="8" language="java" name="TD2.interactions.Memory" project="M315"
<end type="SOURCE" refId="4" navigable="false"> file="/M315/src/TD2/interactions/Memory.java" binary="false" corner="BOTTOM_RIGHT">
<attribute id="9" name="author"> <position height="-1" width="-1" x="107" y="91"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="9" language="java" name="TD2.interactions.UserConsole" project="M315"
file="/M315/src/TD2/interactions/UserConsole.java" binary="false" corner="BOTTOM_RIGHT">
<position height="466" width="311" x="1004" y="463"/>
<display autosize="false" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="10" language="java" name="TD2.interactions.App" project="M315" file="/M315/src/TD2/interactions/App.java"
binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="268" y="82"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="11" language="java" name="TD2.interactions.Controleur" project="M315"
file="/M315/src/TD2/interactions/Controleur.java" binary="false" corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="961" y="1101"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<association id="12">
<bendpoint x="977" y="547"/>
<bendpoint x="977" y="846"/>
<end type="SOURCE" refId="2" navigable="false">
<attribute id="13" name="member">
<position height="0" width="0" x="-97" y="-84"/> <position height="0" width="0" x="-97" y="-84"/>
</attribute> </attribute>
<multiplicity id="10" minimum="0" maximum="1"> <multiplicity id="14" minimum="0" maximum="2147483647">
<position height="0" width="0" x="-97" y="-84"/> <position height="0" width="0" x="-97" y="-84"/>
</multiplicity> </multiplicity>
</end> </end>
<end type="TARGET" refId="1" navigable="true"/> <end type="TARGET" refId="1" navigable="true"/>
<display labels="true" multiplicity="true"/> <display labels="true" multiplicity="true"/>
</association> </association>
<association id="11"> <association id="15">
<end type="SOURCE" refId="2" navigable="false"> <end type="SOURCE" refId="2" navigable="false">
<attribute id="12" name="admin"> <attribute id="16" name="mg">
<position height="0" width="0" x="0" y="0"/>
</attribute>
<multiplicity id="13" minimum="0" maximum="1">
<position height="0" width="0" x="0" y="0"/>
</multiplicity>
</end>
<end type="TARGET" refId="3" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="14">
<end type="SOURCE" refId="2" navigable="false">
<attribute id="15" name="mg">
<position height="0" width="0" x="-7" y="-58"/> <position height="0" width="0" x="-7" y="-58"/>
</attribute> </attribute>
<multiplicity id="16" minimum="0" maximum="1"> <multiplicity id="17" minimum="0" maximum="1">
<position height="0" width="0" x="-7" y="-58"/> <position height="0" width="0" x="-7" y="-58"/>
</multiplicity> </multiplicity>
</end> </end>
<end type="TARGET" refId="5" navigable="true"/> <end type="TARGET" refId="5" navigable="true"/>
<display labels="true" multiplicity="true"/> <display labels="true" multiplicity="true"/>
</association> </association>
<association id="17"> <association id="18">
<end type="SOURCE" refId="3" navigable="false"> <end type="SOURCE" refId="6" navigable="false">
<attribute id="18" name="forum"> <attribute id="19" name="l">
<position height="0" width="0" x="0" y="0"/> <position height="0" width="0" x="0" y="0"/>
</attribute> </attribute>
<multiplicity id="19" minimum="0" maximum="1"> <multiplicity id="20" minimum="0" maximum="2147483647">
<position height="0" width="0" x="0" y="0"/> <position height="0" width="0" x="0" y="0"/>
</multiplicity> </multiplicity>
</end> </end>
<end type="TARGET" refId="2" navigable="true"/> <end type="TARGET" refId="2" navigable="true"/>
<display labels="true" multiplicity="true"/> <display labels="true" multiplicity="true"/>
</association> </association>
<association id="20"> <association id="21">
<end type="SOURCE" refId="7" navigable="false"> <end type="SOURCE" refId="2" navigable="false">
<attribute id="21" name="lmsg"/> <attribute id="22" name="admin">
<multiplicity id="22" minimum="0" maximum="2147483647"/> <position height="0" width="0" x="0" y="0"/>
</attribute>
<multiplicity id="23" minimum="0" maximum="1">
<position height="0" width="0" x="0" y="0"/>
</multiplicity>
</end> </end>
<end type="TARGET" refId="4" navigable="true"/> <end type="TARGET" refId="3" navigable="true"/>
<display labels="true" multiplicity="true"/> <display labels="true" multiplicity="true"/>
</association> </association>
<association id="23"> <association id="24">
<bendpoint x="977" y="547"/> <end type="SOURCE" refId="11" navigable="false">
<bendpoint x="977" y="846"/> <attribute id="25" name="ui"/>
<end type="SOURCE" refId="2" navigable="false"> <multiplicity id="26" minimum="0" maximum="1"/>
<attribute id="24" name="member"> </end>
<end type="TARGET" refId="9" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="27">
<end type="SOURCE" refId="4" navigable="false">
<attribute id="28" name="author">
<position height="0" width="0" x="-97" y="-84"/> <position height="0" width="0" x="-97" y="-84"/>
</attribute> </attribute>
<multiplicity id="25" minimum="0" maximum="2147483647"> <multiplicity id="29" minimum="0" maximum="1">
<position height="0" width="0" x="-97" y="-84"/> <position height="0" width="0" x="-97" y="-84"/>
</multiplicity> </multiplicity>
</end> </end>
<end type="TARGET" refId="1" navigable="true"/> <end type="TARGET" refId="1" navigable="true"/>
<display labels="true" multiplicity="true"/> <display labels="true" multiplicity="true"/>
</association> </association>
<association id="26"> <association id="30">
<end type="SOURCE" refId="3" navigable="false">
<attribute id="31" name="forum">
<position height="0" width="0" x="0" y="0"/>
</attribute>
<multiplicity id="32" minimum="0" maximum="1">
<position height="0" width="0" x="0" y="0"/>
</multiplicity>
</end>
<end type="TARGET" refId="2" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="33">
<end type="SOURCE" refId="7" navigable="false">
<attribute id="34" name="lmsg">
<position height="0" width="0" x="0" y="0"/>
</attribute>
<multiplicity id="35" minimum="0" maximum="2147483647">
<position height="0" width="0" x="0" y="0"/>
</multiplicity>
</end>
<end type="TARGET" refId="4" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="36">
<end type="SOURCE" refId="2" navigable="false"> <end type="SOURCE" refId="2" navigable="false">
<attribute id="27" name="canaux"/> <attribute id="37" name="canaux">
<multiplicity id="28" minimum="0" maximum="2147483647"/> <position height="0" width="0" x="0" y="0"/>
</attribute>
<multiplicity id="38" minimum="0" maximum="2147483647">
<position height="0" width="0" x="0" y="0"/>
</multiplicity>
</end> </end>
<end type="TARGET" refId="7" navigable="true"/> <end type="TARGET" refId="7" navigable="true"/>
<display labels="true" multiplicity="true"/> <display labels="true" multiplicity="true"/>
</association> </association>
<association id="29"> <association id="39">
<end type="SOURCE" refId="2" navigable="false"> <end type="SOURCE" refId="11" navigable="false">
<attribute id="30" name="fm"> <attribute id="40" name="registre"/>
<position height="0" width="0" x="0" y="0"/> <multiplicity id="41" minimum="0" maximum="1"/>
</attribute>
<multiplicity id="31" minimum="0" maximum="1">
<position height="0" width="0" x="0" y="0"/>
</multiplicity>
</end> </end>
<end type="TARGET" refId="6" navigable="true"/> <end type="TARGET" refId="6" navigable="true"/>
<display labels="true" multiplicity="true"/> <display labels="true" multiplicity="true"/>
</association> </association>
<association id="32"> <association id="42">
<end type="SOURCE" refId="1" navigable="false"> <end type="SOURCE" refId="1" navigable="false">
<attribute id="33" name="msg"> <attribute id="43" name="msg">
<position height="0" width="0" x="-197" y="-90"/> <position height="0" width="0" x="-197" y="-90"/>
</attribute> </attribute>
<multiplicity id="34" minimum="0" maximum="2147483647"> <multiplicity id="44" minimum="0" maximum="2147483647">
<position height="0" width="0" x="-197" y="-90"/> <position height="0" width="0" x="-197" y="-90"/>
</multiplicity> </multiplicity>
</end> </end>
<end type="TARGET" refId="4" navigable="true"/> <end type="TARGET" refId="4" navigable="true"/>
<display labels="true" multiplicity="true"/> <display labels="true" multiplicity="true"/>
</association> </association>
<association id="35"> <association id="45">
<end type="SOURCE" refId="6" navigable="false"> <end type="SOURCE" refId="11" navigable="false">
<attribute id="36" name="l"> <attribute id="46" name="currentMember"/>
<multiplicity id="47" minimum="0" maximum="1"/>
</end>
<end type="TARGET" refId="1" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<association id="48">
<end type="SOURCE" refId="2" navigable="false">
<attribute id="49" name="fm">
<position height="0" width="0" x="0" y="0"/> <position height="0" width="0" x="0" y="0"/>
</attribute> </attribute>
<multiplicity id="37" minimum="0" maximum="2147483647"> <multiplicity id="50" minimum="0" maximum="1">
<position height="0" width="0" x="0" y="0"/> <position height="0" width="0" x="0" y="0"/>
</multiplicity> </multiplicity>
</end> </end>
<end type="TARGET" refId="2" navigable="true"/> <end type="TARGET" refId="6" navigable="true"/>
<display labels="true" multiplicity="true"/> <display labels="true" multiplicity="true"/>
</association> </association>
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" <classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"

View File

@ -0,0 +1,20 @@
package TD2.interactions;
/**
* Main Application
*
*/
public class App
{
public static void main( String[] args ) throws Exception
{
Controleur controleur;
try {
controleur = new Controleur();
controleur.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,180 @@
package TD2.interactions;
import static java.lang.System.exit;
import static java.lang.Thread.sleep;
import java.io.IOException;
import java.util.Set;
import TD2.Member;
import TD2.Canal;
import TD2.Forum;
import TD2.ForumManager;
import TD2.Message;
import TD2.interactions.Memory;
public class Controleur {
/*
private ForumManager registre = new ForumManager();
private UserConsole ui = new UserConsole();
private Member currentMember;
public Controleur() throws ClassNotFoundException, IOException{
String nom = ui.getNomMembre();
currentMember = new Member(nom);
Object o = Memory.read("sauvegarde.txt");
if (o instanceof ForumManager){
registre = (ForumManager) o;}
}
public void start() throws Exception {
String commande = ui.lireCommande();
switch (commande.charAt(0)) {
case UserConsole.COM_CREER_FORUM:
creerForum();
start();
break;
case UserConsole.COM_CREER_CANAL :
creerCanal();
start();
break;
case UserConsole.COM_CREER_CANAL_DE_BREVES :
creerCanalDeBreves();
start();
break;
case UserConsole.COM_POSTER_MESSAGES:
posterMessage();
start();
break;
case UserConsole.COM_LIRE_MESSAGES:
lireMessage();
start();
break;
case UserConsole.COM_CHANGER_MEMBRE:
currentMember = new Member(ui.getNomMembre());
start();
break;
case UserConsole.COM_INSCRIRE:
inscrireMembreSurForum();
start();
break;
case UserConsole.COM_STOP:
ui.afficher("Au revoir ");
Memory.save(registre, "sauvegarde.txt");
exit(0);
break;
default :
ui.afficher("La commande spécifiée n'existe pas\n");
sleep(1000);
start();
}}
private void inscrireMembreSurForum() {
currentMember = new Member(ui.getNomMembre());
Forum currentForum = registre.getForum(ui.getNomDuForum(registre.getListeForum()));
currentForum.addMember(currentMember);
}
//Méthode utilitaire
private Forum getForum() {
String nomDuForum = ui.getNomDuForum(registre.getNomForums());
if(!registre.exist(nomDuForum)){
ui.afficher("Ce Forum n'existe pas");
return null;
}
return registre.getForum(nomDuForum);
}
private void creerForum() {
//Récupérer la liste des noms des forums
Set<String> ensembleDesNomsDeForumsExistants = registre.getNomForums();
String nomDuForum =
ui.getNomDuForum(ensembleDesNomsDeForumsExistants);
Forum forumNouveau = registre.creerForum(nomDuForum);
if (forumNouveau != null)
ui.afficher("Forum " + nomDuForum + ":"+ forumNouveau);
else
ui.afficher("Pbme de creation Forum " + nomDuForum);
}
private void creerCanal(){
Forum forum = getForum();
if (forum != null) {
//Récupérer les noms des canaux pré-existants
Set <String> nomDesCanaux = forum.getChannelNames();
String nomDeCanal = ui.getNomCanal(nomDesCanaux);
if (forum.addChannel(nomDeCanal))
ui.afficher("Canal créé : "+ nomDeCanal);
else
ui.afficher("Canal non créé : "+ nomDeCanal);
}
}
private void creerCanalDeBreves() {
Forum forum = getForum();
if (forum != null) {
//Récupérer les noms des canaux pré-existants
Set <String> nomDesCanaux = forum.getChannelNames();
String nomDeCanal = ui.getNomCanal(nomDesCanaux);
int maxSize = ui.getSize();
if (forum.addChannelOfBriefs(nomDeCanal,maxSize ))
ui.afficher("Canal de brève créé : "+ nomDeCanal);
else
ui.afficher("Canal de brève non créé : "+ nomDeCanal);
}
}
private void posterMessage() {
Forum forum = getForum();
if (forum == null) {
return;
}
String nomDeCanal = ui.getNomCanal(forum.getChannelNames());
String msg = ui.getValeur("saisir le message : ");
Message message = new Message(msg,currentMember );
if(nomDeCanal.equals("*")){
for(Channel c : forum.getChannels()){
c.addMessage(message);
}
return;
}
Channel canal = forum.getChannel(nomDeCanal);
if (canal == null)
ui.afficher("Ce Canal n'existe pas");
else {
if (canal.addMessage(message))
ui.afficher("Message envoyé");
else
ui.afficher("Probleme a l'envoi");
ui.afficher("Messages dans " + nomDeCanal);
ui.afficherMessages(canal.getMessages());
}
}
private void lireMessage() {
Forum forum = getForum();
if (forum == null) {
return;
}
String nomDeCanal = ui.getNomCanal(forum.getChannelNames());
Channel canal = forum.getChannel(nomDeCanal);
if (canal == null)
ui.afficher("Ce Canal "+ nomDeCanal + " n'existe pas");
else {
ui.afficherMessages(canal.getNewMessages(currentMember));
}
}
*/
}

View File

@ -0,0 +1,62 @@
package TD2.interactions;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Based on http://www.jmdoudoux.fr/java/dej/chap-serialisation.htm
*
* @author Mireille Blay
*
*/
public class Memory {
static Logger monLog = Logger.getLogger(Memory.class.getName());
private Memory() {
super();
}
/**
* @param Object to save in a file, it must be serializable
* @param file Name where to write the "object"
* @throws IOException
*/
public static void save (Object o, String fileName) throws IOException{
ObjectOutputStream oos = null;
try (FileOutputStream fichier = new FileOutputStream(fileName)){
oos = new ObjectOutputStream(fichier);
oos.writeObject(o);
oos.flush();
}
}
/**
* @param fileName
* @return an object corresponding to the serialization written in the file.
* @throws IOException
* @throws ClassNotFoundException
*/
public static Object read (String fileName) throws IOException, ClassNotFoundException{
ObjectInputStream ois = null;
Object o = null;
File f = new File(fileName);
if(!(f.isFile()))
{
return null;
}
try (FileInputStream fichier = new FileInputStream(fileName)){
ois = new ObjectInputStream(fichier);
o = ois.readObject();
}
return o;
}
}

View File

@ -0,0 +1,102 @@
package TD2.interactions;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import TD2.Message;
public class UserConsole {
Scanner sc = new Scanner(System.in);
public static final char COM_CREER_FORUM = 'f';
public static final char COM_CREER_CANAL = 'c';
public static final char COM_LIRE_MESSAGES = 'l';
public static final char COM_POSTER_MESSAGES = 'p';
public static final char COM_STOP = 's';
public static final char COM_CHANGER_MEMBRE = 'm';
public static final char COM_INSCRIRE = 'i';
public static final char COM_CREER_CANAL_DE_BREVES = 'b';
//On pourra modifier facilement pour par exemple utiliser des logger.
private final void sop(String s) {
System.out.println(s);
}
public String lireCommande() {
sop("------- COMMANDES ----------");
sop("creer Forum : " + COM_CREER_FORUM ) ;
sop("creer Canal : " + COM_CREER_CANAL);
sop("creer Canal de brèves: " + COM_CREER_CANAL_DE_BREVES);
sop("lire messages : " + COM_LIRE_MESSAGES);
sop("poster un nouveau message : " + COM_POSTER_MESSAGES);
sop("changer de membre : " + COM_CHANGER_MEMBRE ) ;
sop("s'inscrire : " + COM_INSCRIRE ) ;
sop("stop : " + COM_STOP);
sop("Que voulez-vous faire ?");
String str = sc.nextLine().toLowerCase();
sop("Vous avez saisi la commande: " + str);
return str;
}
public void afficher(String str) {
sop(str);
}
public String getNomMembre() {
sop("quel est votre nom ?");
return sc.nextLine();
}
public void afficherMessages(List<Message> arrayList) {
int i = 1;
sop("\t messages : ");
if (arrayList == null) {
sop("\t Pas de messages ");
}
else
for (Message m : arrayList) {
sop("\t" + i + "-\t" + m);
i++;
}
}
public String getNomDuForum(Set<String> nomsForum) {
sop("--- Forum disponibles --- ");
afficheListe(nomsForum);
sop("==> Nom du Forum ?");
return sc.nextLine();
}
public void afficheListe(Set<String> noms) {
for (String nom : noms)
sop("\t"+ nom);
}
public String getNomCanal(Set<String> nomsCanaux) {
sop("--- Canals disponibles --- ");
afficheListe(nomsCanaux);
sop("==> Nom du Canal ?");
return sc.nextLine();
}
public String getValeur(String message) {
sop(message);
return sc.nextLine();
}
public String write(){
return sc.nextLine();
}
public int getSize() {
sop("===> quelle taille ? ");
int i = sc.nextInt();
sc.nextLine();
return i;
}
}

View File

@ -0,0 +1,43 @@
package TD4.cars;
/**
* This class defines the notion of a car to be rented by associating it with a price per day.
*
* @author Mireille Blay-Fornarino
*
* @version 1.0
*/
public class Car {
private String numberPlate;
private double dayPrice;
public Car(String numberPlate, double dayPrice) {
this.numberPlate = numberPlate;
this.dayPrice = dayPrice;
}
public String getNumberPlate() {
return numberPlate;
}
public void setNumberPlate(String numberPlate) {
this.numberPlate = numberPlate;
}
public double getDayPrice() {
return dayPrice;
}
public void setDayPrice(double dayPrice) {
this.dayPrice = dayPrice;
}
@Override
public String toString() {
return "Car [numberPlate=" + numberPlate + // ", rentals=" + rentals +
", dayPrice=" + dayPrice + "]";
}
}

View File

@ -0,0 +1,96 @@
package TD4.cars;
import java.time.LocalDate;
/**
*
* The Car Rental class represents the rental of a car, for a given duration and start date.
*
* @author Mireille Blay-Fornarino
*
* 6
*/
/**
* @author blay
*
*/
public class CarRental {
private Car car;
private double dayPrice;
private int duration;
private LocalDate beginDate;
private CarRental(Car car, double dayPrice, int duration, LocalDate beginDate) {
super();
this.car = car;
this.dayPrice = dayPrice;
this.duration = duration;
this.beginDate = beginDate;
}
/**
* the price of the rental should not change even if the price of the car changes.
* @param c : the car to rent
* @param beginDate : the date from which the car is rented out
* @param duration : rental duration in days
*/
public CarRental(Car c, LocalDate beginDate, int duration) {
this(c,c.getDayPrice(),duration,beginDate);
}
public String getCarNumber() {
return car.getNumberPlate();
}
public Car getCar() {
return car;
}
/**
* When we change the car assigned to a rental, the price does not change.
* @param aCar
*/
public void setCar(Car aCar) {
this.car = aCar;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public LocalDate getBeginDate() {
return beginDate;
}
public void setBeginDate(LocalDate beginDate) {
this.beginDate = beginDate;
}
public double getPrice() {
return dayPrice*duration;
}
/**
*
* @param dates : an array of dates
* @return true when one of the dates in the parameter is included in the duration of the car rental
*/
public boolean includeADate(LocalDate[] dates) {
for (LocalDate d : dates) {
if (d.equals(beginDate))
return true;
if ( (d.isAfter(beginDate)) &&
(d.isBefore(beginDate.plusDays(duration) ) ) )
return true;
}
return false;
}
}

View File

@ -0,0 +1,91 @@
package TD4.cars;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import TD4.util.DateTools;
import TD4.util.NotPossibleCarRentalException;
/**
*
* This class allows the management of a set of car rentals
*
*
* @author Mireille Blay-Fornarino
*
*
*/
public class CarRentalService {
//Set of cars for rent
private List<Car> cars;
//All registered car rentals
private List<CarRental> carRentals = new ArrayList<>();
//To create a car rental service, you need to have cars.
public CarRentalService(List<Car> cars) {
super();
this.cars = cars;
}
/**
* @param d : first day
* @param nbDays : number of days
* @return the available cars from the first day during {@code nbDays} days
*/
public List<Car> getAvailableCars(LocalDate d, int nbDays) {
ArrayList<Car> availableCars = new ArrayList<>();
LocalDate[] dates = DateTools.getDays(d, nbDays);
for (Car c : cars) {
if (isAvailable(c, dates)) {
availableCars.add(c);
}
}
return availableCars;
}
private boolean isAvailable(Car c, LocalDate[] dates) {
for (CarRental carRental : carRentals) {
if (c.equals(carRental.getCar()) &&
(carRental.includeADate(dates)) ) {
return false;
}
}
return true;
}
/**
* It books the car rental and returns the created {@code CarRental}
* @param c : {@code Car} for rent
* @param fromDate : {@code LocalDate} first day for rental
* @param numberOfDays
* @return the rental of {@code Car} {@code c} from the first day {@code fromDate} during {@code numberOfDays}
* @throws NotPossibleCarRentalException
*/
public CarRental book(Car c, LocalDate fromDate, int numberOfDays) throws NotPossibleCarRentalException {
CarRental carRental = null;
if (cars == null || !(cars.contains(c)) )
throw new NotPossibleCarRentalException("Not known car");
LocalDate[] dates = DateTools.getDays(fromDate, numberOfDays);
if (isAvailable(c, dates)) {
carRental = new CarRental(c, fromDate, numberOfDays);
carRentals.add(carRental);
}
return carRental;
}
}

View File

@ -0,0 +1,5 @@
package TD4.core;
public interface PayingItem {
public double getPrice();
}

View File

@ -0,0 +1,37 @@
package TD4.core;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Service4PI<T extends PayingItem> {
protected List<T> payingItemList = new ArrayList<>();
public Service4PI(List<T> payingItemList) {
this.payingItemList = payingItemList;
}
protected List<T> getpayingItemList() {
return payingItemList;
}
public List<T> sortedByPrice() {
payingItemList.sort(Comparator.comparing(PayingItem::getPrice));
return new ArrayList<T>(payingItemList);
}
private void sortedByPriceInPlace() {
payingItemList.sort(Comparator.comparing(PayingItem::getPrice));
}
public T lessExpensiveItem() {
sortedByPriceInPlace();
return payingItemList.get(0);
}
public void add(T payingItem) {
payingItemList.add(payingItem);
}
}

View File

@ -0,0 +1,95 @@
package TD4.flights;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Random;
/**
*
*
* Simplified definition of a flight
* departing from a given airport on a given date.
* It is assumed that the flight arrives at the destination airport on the same day.
*
* @author Mireille Blay-Fornarino
*
*
*/
public class Flight {
private static final int NOT_ASSIGNED = -1;
private static final String DEFAULT_DESTINATION= "Paris";
private double price = NOT_ASSIGNED;
private LocalDate departDate;
private String departureAirport;
private String arrivalAirport;
private LocalTime departureTime;
public LocalTime getDepartTime() {
return departureTime;
}
public void setDepartureTime(LocalTime departTime) {
this.departureTime = departTime;
}
public Flight(String departureAirport) {
this(NOT_ASSIGNED, LocalDate.now(), LocalTime.now(), departureAirport, DEFAULT_DESTINATION);
}
public Flight(double price, LocalDate departDate, LocalTime departTime, String departAirport, String arrivalAirport) {
super();
this.price = price;
this.departDate = departDate;
this.departureAirport = departAirport;
this.arrivalAirport = arrivalAirport;
this.departureTime= departTime;
}
public LocalDate getDepartDate() {
return departDate;
}
public void setDepartDate(LocalDate departDate) {
this.departDate = departDate;
}
public String getDepartAirport() {
return departureAirport;
}
public void setDepartureAirport(String departureAirport) {
this.departureAirport = departureAirport;
}
public String getArrivalAirport() {
return arrivalAirport;
}
public void setArrivalAirport(String arrivalAirport) {
this.arrivalAirport = arrivalAirport;
}
public void setPrice(double price) {
this.price = price;
}
/**
* @return the price of the flight. If the price is not affected, the price is calculated randomly, almost as in reality
*/
public double getPrice() {
if (price == NOT_ASSIGNED) {
double start = 10;
double end = 1000;
double random = new Random().nextDouble();
price = start + (random * (end - start));
}
return price;
}
/**
* @param d date for the flight
* @param from name of the departure airport
* @param to name of the arrival airport
* @return true if the different parameters match with the current flight
*/
public boolean match(LocalDate d, String from, String to) {
return getDepartDate().equals(d) && getDepartAirport().equals(from) && getArrivalAirport().equals(to);
}
}

View File

@ -0,0 +1,62 @@
package TD4.flights;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* This class allows the management of a set of flights
*
* @author Mireille Blay-Fornarino
*
*
*/
public class FlightService {
private List<Flight> flights = new ArrayList<>();
public FlightService(List<Flight> flights) {
this.flights = flights;
}
/**
* @param aDate : {@code LocalDate}
* @return the list of flights available on a given date {@code LocalDate}
*/
public List<Flight> getFlights(LocalDate aDate) {
Stream<Flight> parallelStream = flights.parallelStream();
Stream<Flight> results = parallelStream.filter(f -> (f.getDepartDate().equals(aDate)));
return results.collect(Collectors.toCollection(ArrayList::new));
}
/**
* @param d : : {@code LocalDate}
* @param from : departure airport name
* @param to : arrival airport name
* @return the list of flights available on a given date {@code LocalDate} from
* a place to another place
*/
public List<Flight> getFlights(LocalDate d, String from, String to) {
Stream<Flight> parallelStream = flights.parallelStream();
Stream<Flight> results = parallelStream.filter(f -> f.match(d, from, to));
return results.collect(Collectors.toCollection(ArrayList::new));
}
/**
* @return a copy of the flight list sorted by price. The flights themselves are
* not cloned.
*/
public List<Flight> sortedByPrice() {
flights.sort(Comparator.comparing(Flight::getPrice));
return new ArrayList<>(flights);
}
public Flight getFlyWithBestPrice() {
return this.sortedByPrice().get(0);
}
}

View File

@ -0,0 +1,20 @@
package TD4.util;
/**
*
* This exception is raised when something is already rented and attempts are made to over-rent it.
* @author Mireille Blay-Fornarino
*
*/
public class AlreadyBooked extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public AlreadyBooked(String message) {
super(message);
}
}

View File

@ -0,0 +1,50 @@
package TD4.util;
import java.time.LocalDate;
/**
* Utility class to manage dates
*
*
* @author Mireille Blay-Fornarino
*
*
* 6 oct. 2018
*/
public final class DateTools {
private DateTools() {
throw new IllegalStateException("Utility class");
}
/**
* @param date
* @param nbDays number of days to be added
* @return the {@code LocalDate} corresponding to the {@code Date} to which {@code nbDays} days have been added
*/
public static LocalDate addDays(LocalDate date, int nbDays) {
return date.plusDays(nbDays);
}
/**
* @param date
* @param nbDays
* @return the {@code LocalDate} array containing the {@code date} and the following {@code nbDays}-1;
*/
public static LocalDate[] getDays(LocalDate date, int nbDays) {
if (nbDays == 0)
return new LocalDate[nbDays];
int i = 0;
LocalDate[] dates = new LocalDate[nbDays];
dates[i] = date;
i+=1;
while (i < nbDays) {
dates[i] = addDays(date,i);
i++;
}
return dates;
}
}

View File

@ -0,0 +1,19 @@
package TD4.util;
/**
* @author Mireille Blay-Fornarino
*
* 6 oct. 2018
*/
public class NotPossibleCarRentalException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public NotPossibleCarRentalException(String message) {
super(message);
}
}

View File

@ -0,0 +1,104 @@
package TD4.cars;
import static org.junit.Assert.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import TD4.util.NotPossibleCarRentalException;
public class CarRentalServiceTest {
CarRentalService service ;
Car myCar0 = new Car("1111 AB 06",50);
Car myCar1 = new Car("1111 AB 75",100);
Car myCar2 = new Car("1111 AB 83",75);
LocalDate currentDate;
@Before
public void setUp() {
myCar0 = new Car("1111 AB 06",50);
myCar1 = new Car("1111 AB 75",100);
myCar2 = new Car("1111 AB 83",75);
service = new CarRentalService( new ArrayList<>(Arrays.asList(myCar0, myCar1, myCar2) ) ) ;
}
@Test
public void testGetAvailableCars() throws NotPossibleCarRentalException {
LocalDate current = LocalDate.of(2020,9,11);
List<Car> possibleCars =
service.getAvailableCars(current, 2);
assertEquals(3, possibleCars.size());
CarRental carRental = service.book(myCar0,current,2);
assertTrue(carRental != null);
possibleCars =
service.getAvailableCars(current, 1);
assertEquals(2, possibleCars.size());
possibleCars =
service.getAvailableCars(current, 2);
assertEquals(2, possibleCars.size());
possibleCars =
service.getAvailableCars(LocalDate.of(2020,9,12), 1);
assertEquals(2, possibleCars.size());
possibleCars =
service.getAvailableCars(LocalDate.of(2020,9,13), 1);
assertEquals(3, possibleCars.size());
}
@Test
public void testBookAnAvalaibleCar() throws NotPossibleCarRentalException {
CarRental carRental = service.book(myCar0,LocalDate.of(2018,9,11), 2);
assertFalse(carRental==null);
List<Car> possibleCars = service.getAvailableCars(LocalDate.of(2018,9,11), 1);
assertEquals(2, possibleCars.size());
possibleCars = service.getAvailableCars(LocalDate.of(2018,9,12), 3);
assertEquals(2, possibleCars.size());
possibleCars = service.getAvailableCars(LocalDate.of(2018,9,13), 3);
assertEquals(3, possibleCars.size());
possibleCars = service.getAvailableCars(LocalDate.of(2018,9,9), 4);
assertEquals(2, possibleCars.size());
possibleCars = service.getAvailableCars(LocalDate.of(2018,9,19), 7);
assertEquals(3, possibleCars.size());
}
@Test
public void testBookANonAvalaibleCar() throws NotPossibleCarRentalException {
CarRental carRental = service.book(myCar0,LocalDate.of(2020,9,11), 2);
assertFalse(carRental==null);
carRental = service.book(myCar0,LocalDate.of(2020,9,12), 2);
assertTrue(carRental==null);
}
@Test
public void testGetNotAvailableCars() throws NotPossibleCarRentalException {
service.book(myCar0,LocalDate.of(2020,9,11), 2);
List<Car> possibleCars = service.getAvailableCars(LocalDate.of(2020,9,11), 2);
assertEquals(2, possibleCars.size());
possibleCars = service.getAvailableCars(LocalDate.of(2020,9,12), 2);
assertEquals(2, possibleCars.size());
possibleCars = service.getAvailableCars(LocalDate.of(2020,9,13), 2);
assertEquals(3, possibleCars.size());
}
}

View File

@ -0,0 +1,61 @@
package TD4.cars;
import static org.junit.jupiter.api.Assertions.*;
import java.time.LocalDate;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import TD4.util.DateTools;
class CarRentalTest {
Car myCar ;
CarRental carRental;
@BeforeEach
public void setUp() {
myCar = new Car("1111 AB 06",50);
}
@Test
public void testCarRentalCreation() {
carRental = new CarRental(myCar, LocalDate.of(2018, 8, 30), 3);
assertEquals( myCar.getDayPrice()*3, carRental.getPrice());
}
@Test
public void testCarRentalAvailability() {
carRental = new CarRental(myCar, LocalDate.of(2018, 8, 30), 3);
LocalDate[] dates = DateTools.getDays(LocalDate.of(2018, 8, 30), 3);
assertEquals(3, dates.length );
dates = DateTools.getDays(LocalDate.of(2018, 8, 30), 1);
assertTrue(carRental.includeADate(dates),"date de début OK");
dates = DateTools.getDays(LocalDate.of(2018, 8, 29), 1);
assertFalse(carRental.includeADate(dates),"date à un jour avant");
dates = DateTools.getDays(LocalDate.of(2018, 9, 2), 1);
assertFalse(carRental.includeADate(dates),"date à un jour après");
dates = DateTools.getDays(LocalDate.of(2018, 8, 25), 10);
assertTrue(carRental.includeADate(dates),"date incluse après");
dates = DateTools.getDays(LocalDate.of(2018, 9, 1), 1);
assertTrue(carRental.includeADate(dates),"date incluse sur la fin");
dates = DateTools.getDays(LocalDate.of(2018, 8, 31), 10);
assertTrue(carRental.includeADate(dates),"date incluse sur la fin");
}
@Test
public void testGetPrice() {
carRental = new CarRental(myCar, LocalDate.of(2017, 8, 31), 3);
assertEquals(50,myCar.getDayPrice());
assertEquals(50.0*3,carRental.getPrice());
}
}

View File

@ -0,0 +1,75 @@
package TD4.flights;
import static org.junit.Assert.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
public class FlightServiceTest {
private static final String PARIS = "Paris";
private static final String NICE = "Nice";
private static final LocalDate dateToTest = LocalDate.of(2017, 12, 24);
FlightService service ;
@Before
public void setUp() {
ArrayList<Flight> list = new ArrayList<>();
list.add(new Flight("Belfort"));
list.add(new Flight(NICE));
list.add(new Flight(100, dateToTest, LocalTime.of(7, 45),NICE, PARIS));
list.add(new Flight(20, dateToTest, LocalTime.of(9, 30), NICE, PARIS));
list.add(new Flight(150, dateToTest, LocalTime.of(18, 30), PARIS, NICE));
service = new FlightService(list);
}
@Test
public void testGetFlightsOnADivenDate() {
List<Flight> flights = service.getFlights(LocalDate.now());
assertEquals(2, flights.size());
flights = service.getFlights(dateToTest);
assertEquals(3, flights.size());
}
@Test
public void testGetFlights() {
List<Flight> flights = service.getFlights(LocalDate.now(),NICE,PARIS);
assertEquals(1, flights.size());
flights = service.getFlights(dateToTest,NICE,PARIS);
assertEquals(2, flights.size());
}
@Test
public void testSortedByPrice() {
ArrayList<Flight> list = new ArrayList<>();
list.add(new Flight(100, dateToTest, LocalTime.of(7, 45),NICE, PARIS));
list.add(new Flight(20, dateToTest, LocalTime.of(9, 30), NICE, PARIS));
list.add(new Flight(150, dateToTest, LocalTime.of(18, 30), PARIS, NICE));
service = new FlightService(list);
List<Flight> flights = service.sortedByPrice();
assertEquals(20,flights.get(0).getPrice(),0.01);
assertEquals(100,flights.get(1).getPrice(),0.01);
assertEquals(150,flights.get(2).getPrice(),0.01);
}
@Test
public void testGetBestPrice() {
ArrayList<Flight> list = new ArrayList<>();
list.add(new Flight(100, dateToTest, LocalTime.of(7, 45),NICE, PARIS));
list.add(new Flight(20, dateToTest, LocalTime.of(9, 30), NICE, PARIS));
list.add(new Flight(150, dateToTest, LocalTime.of(18, 30), PARIS, NICE));
service = new FlightService(list);
assertEquals(20, service.getFlyWithBestPrice().getPrice());
}
}

View File

@ -0,0 +1,29 @@
package TD4.flights;
import static org.junit.Assert.*;
import java.time.LocalDate;
import java.time.LocalTime;
import org.junit.Before;
import org.junit.Test;
public class FlightTest {
Flight f1 ;
@Before
public void setUp() {
f1 = new Flight(100, LocalDate.of(2017,11,11), LocalTime.of(7, 45),"Nice","Paris");
}
@Test
public void testGetPrice() {
assertEquals(100,f1.getPrice(),0);
f1.setPrice(-1);
assertTrue(f1.getPrice()>=10);
assertTrue(f1.getPrice()<=1000);
}
}