Created
March 18, 2024 13:21
-
-
Save Cubik65536/7b03a283623110daaa62fd218811b0c1 to your computer and use it in GitHub Desktop.
AirlineManagementSystem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.qianq; | |
import java.io.File; | |
import java.io.FileWriter; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.Scanner; | |
/** | |
* A company that has a name and a balance. | |
*/ | |
class Company { | |
/** | |
* The name of the company. | |
*/ | |
private String name; | |
/** | |
* The directory of the log file. | |
*/ | |
private File log; | |
/** | |
* The balance of the company. | |
*/ | |
private int balance; | |
/** | |
* Construct a company with a name. | |
* The log file object will be automatically created with the file following the format of "{name}.log". | |
* The initial balance will be set to 100000. | |
* @param name The name of the company. | |
* @throws IOException If an I/O error occurs while creating the log file. | |
*/ | |
public Company(String name) throws IOException { | |
this.name = name; | |
this.log = new File(name + ".log"); | |
if (log.exists()) { | |
if (!log.delete()) { | |
throw new IOException("The log file already exists and cannot be deleted."); | |
} | |
} | |
if (!log.createNewFile()) { | |
throw new IOException("The log file cannot be created."); | |
} | |
this.balance = 100000; | |
} | |
/** | |
* Gain some money for the company. | |
* (Add the amount to the balance) | |
* @param amount The amount of money to gain. | |
* @throws IOException If an I/O error occurs while writing to the log file. | |
*/ | |
public void gain(int amount) throws IOException { | |
this.balance += amount; | |
FileWriter writer = null; | |
// No catch block is here because we can remove it | |
// if we know it that the exception is going to be thrown again immediately. | |
try { | |
writer = new FileWriter(log, true); | |
writer.write(String.format("+%d\n", amount)); | |
} finally { | |
if (writer != null) { | |
writer.close(); | |
} | |
} | |
} | |
/** | |
* Spend some money for the company. | |
* (Subtract the amount from the balance) | |
* @param amount The amount of money to spend. | |
* @throws IOException If an I/O error occurs while writing to the log file. | |
*/ | |
public void spend(int amount) throws IOException { | |
this.balance -= amount; | |
FileWriter writer = null; | |
try { | |
writer = new FileWriter(log, true); | |
writer.write(String.format("-%d\n", amount)); | |
} finally { | |
if (writer != null) { | |
writer.close(); | |
} | |
} | |
} | |
/** | |
* Get the balance of the company. | |
* @return The balance of the company. | |
*/ | |
public int getBalance() { | |
return balance; | |
} | |
} | |
/** | |
* An enum storing the possible brands of a plane.<br> | |
* Which are:<br> | |
* - AIRBUS<br> | |
* - BOEING<br> | |
* - COMAC<br> | |
* - BOMBARDIER<br> | |
* - GULFSTREAM | |
*/ | |
enum PlaneBrand { | |
AIRBUS, BOEING, COMAC, BOMBARDIER, GULFSTREAM | |
} | |
/** | |
* The exception thrown when the number of passengers exceeds the capacity of the plane. | |
*/ | |
class CapacityExceededException extends Exception { | |
/** | |
* Construct a CapacityExceededException with the number of passengers and the capacity of the plane. | |
* The message will be automatically generated. | |
* @param number The number of passengers. | |
* @param capacity The capacity of the plane. | |
*/ | |
public CapacityExceededException(int number, int capacity) { | |
super(String.format( | |
"The number of passengers (%d) exceeds the capacity (%d) of the plane.", | |
number, capacity | |
)); | |
} | |
} | |
interface Vehicle { | |
/** | |
* Get the ID of the vehicle. | |
* @return The ID of the vehicle. | |
*/ | |
String getId(); | |
/** | |
* Get the name of the vehicle. | |
* @return The name of the vehicle. | |
*/ | |
String getName(); | |
/** | |
* Get the capacity of the vehicle. | |
* @return The capacity of the vehicle. | |
*/ | |
int getCapacity(); | |
/** | |
* Transport some people from one place to another. | |
* The transportation info will be printed. | |
* @param peopleNumber The number of people to transport. | |
* @param from The place to transport from. | |
* @param to The place to transport to. | |
* @throws CapacityExceededException If the number of people exceeds the capacity of the vehicle. | |
*/ | |
void transport(int peopleNumber, String from, String to) throws CapacityExceededException; | |
/** | |
* Get the info of the vehicle. | |
* The info will be formatted as "Vehicle {ID}: {name} (capacity: {capacity})". | |
* @return The info of the vehicle in the specified format. | |
*/ | |
default String getInfo() { | |
return String.format( | |
"Vehicle %s: %s (capacity: %d)", | |
getId(), getName(), getCapacity() | |
); | |
} | |
} | |
/** | |
* The exception thrown when the capacity of the vehicle is illegal. | |
*/ | |
class CapacityIllegalException extends Exception { | |
/** | |
* Construct a CapacityIllegalException with a custom message. | |
* @param message The message of the exception. | |
*/ | |
public CapacityIllegalException(String message) { | |
super(message); | |
} | |
} | |
/** | |
* A plane that can transport people from one place to another. | |
* It has an ID, a name, a capacity, a brand, a cost and a ticket price. | |
*/ | |
class Plane implements Vehicle { | |
private final static int MIN_CAPACITY_AIRBUS_BOEING_COMAC = 100; | |
private final static int MAX_CAPACITY_BOMBARDIER_GULFSTREAM = 50; | |
/** | |
* The index of the planes. | |
*/ | |
private static int idIndex = 0; | |
/** | |
* The ID of the plane. | |
*/ | |
private String id; | |
/** | |
* The name of the plane. | |
*/ | |
private String name; | |
/** | |
* The capacity of the plane. | |
*/ | |
private int capacity; | |
/** | |
* The brand of the plane. | |
*/ | |
private PlaneBrand brand; | |
/** | |
* The cost of the plane to fly for one time. | |
*/ | |
private int cost; | |
/** | |
* The ticket price per person. | |
*/ | |
private int ticket; | |
/** | |
* Construct a plane with a name, a capacity, a brand, a cost and a ticket price. | |
* The ID will be automatically generated from the current index of the planes and the brand of the plane. | |
* The generated ID will follow the format of "P{index}-{brand suffix}". | |
* @param name The name of the plane. | |
* @param capacity The capacity of the plane. | |
* @param brand The brand of the plane. | |
* @param cost The cost of the plane to fly for one time. | |
* @param ticket The ticket price per person. | |
* @throws CapacityIllegalException If the capacity is less or equal to 0, | |
* or the plane manufactured by AIRBUS, BOEING or COMAC has a capacity less than 100, | |
* or the plane manufactured by BOMBARDIER or GULFSTREAM has a capacity more than 50. | |
*/ | |
public Plane(String name, int capacity, PlaneBrand brand, int cost, int ticket) throws CapacityIllegalException { | |
this.id = switch (brand) { | |
case AIRBUS -> String.format("P%03d-A", ++idIndex); | |
case BOEING -> String.format("P%03d-B", ++idIndex); | |
case COMAC -> String.format("P%03d-C", ++idIndex); | |
case BOMBARDIER -> String.format("P%03d-BDR", ++idIndex); | |
case GULFSTREAM -> String.format("P%03d-GFS", ++idIndex); | |
}; | |
this.name = name; | |
if (capacity <= 0) { | |
throw new CapacityIllegalException("The capacity of the plane cannot be less or equal to 0."); | |
} else if ((brand == PlaneBrand.AIRBUS || brand == PlaneBrand.BOEING || brand == PlaneBrand.COMAC) && capacity < MIN_CAPACITY_AIRBUS_BOEING_COMAC) { | |
throw new CapacityIllegalException("The capacity of the plane manufactured by AIRBUS, BOEING or COMAC cannot be less than 100."); | |
} else if ((brand == PlaneBrand.BOMBARDIER || brand == PlaneBrand.GULFSTREAM) && capacity > MAX_CAPACITY_BOMBARDIER_GULFSTREAM) { | |
throw new CapacityIllegalException("The capacity of the plane manufactured by BOMBARDIER or GULFSTREAM cannot be more than 50."); | |
} else { | |
this.capacity = capacity; | |
} | |
this.brand = brand; | |
this.cost = cost; | |
this.ticket = ticket; | |
} | |
/** | |
* @see Vehicle#getId() | |
*/ | |
public String getId() { | |
return id; | |
} | |
/** | |
* @see Vehicle#getName() | |
*/ | |
public String getName() { | |
return name; | |
} | |
/** | |
* @see Vehicle#getCapacity() | |
*/ | |
public int getCapacity() { | |
return capacity; | |
} | |
/** | |
* @throws CapacityExceededException If the number of people exceeds the capacity of the vehicle. | |
* @see Vehicle#transport(int, String, String) | |
*/ | |
public void transport(int peopleNumber, String from, String to) throws CapacityExceededException { | |
if (peopleNumber > capacity) { | |
throw new CapacityExceededException(peopleNumber, capacity); | |
} | |
System.out.printf( | |
"fly %d person from %s to %s", | |
peopleNumber, from, to | |
); | |
} | |
/** | |
* Get the cost of the plane to fly for one time. | |
* @return The cost of the plane to fly for one time. | |
*/ | |
public int getCost() { | |
return cost; | |
} | |
/** | |
* Get the ticket price per person for a flight. | |
* @return The ticket price per person. | |
*/ | |
public int getTicket() { | |
return ticket; | |
} | |
} | |
/** | |
* A single flight from one place to another. | |
*/ | |
class Flight { | |
/** | |
* The index of the flights. | |
*/ | |
private static int idIndex = 0; | |
/** | |
* The ID of the flight. | |
*/ | |
private String id; | |
/** | |
* Departure place. | |
*/ | |
private String from; | |
/** | |
* Arrival place. | |
*/ | |
private String to; | |
/** | |
* Construct a flight from one place to another. | |
* The iD will be automatically generated from the current index of the flights. | |
* The generated ID will follow the format of "F{index}". | |
* @param from The departure place. | |
* @param to The arrival place. | |
*/ | |
public Flight(String from, String to) { | |
this.id = String.format("F%03d", ++idIndex); | |
this.from = from; | |
this.to = to; | |
} | |
/** | |
* Execute the flight on the plane with the specified number of people. | |
* @param plane The plane to execute the flight. | |
* @param peopleNumber The number of people to transport. | |
* @throws CapacityExceededException If the number of people exceeds the capacity of the plane. | |
*/ | |
public void execute(Plane plane, int peopleNumber) throws CapacityExceededException { | |
plane.transport(peopleNumber, from, to); | |
} | |
/** | |
* Get the info of the flight. | |
* The info will be formatted as "Flight {ID}: {from} to {to}". | |
* @return The info of the flight in the specified format. | |
*/ | |
public String getInfo() { | |
return String.format( | |
"Flight %s: %s to %s", | |
id, from, to | |
); | |
} | |
/** | |
* Get the ID of the flight. | |
* @return The ID of the flight. | |
*/ | |
public String getId() { | |
return id; | |
} | |
} | |
class Airline extends Company { | |
/** | |
* The planes of the airline. | |
*/ | |
private ArrayList<Plane> planes; | |
/** | |
* The flights of the airline. | |
*/ | |
private ArrayList<Flight> flights; | |
/** | |
* Construct an airline with a name. | |
* ArrayLists of planes and flights will be created. | |
* The other properties will be set to the default values of the super class Company. | |
* @param name The name of the airline. | |
* @see Company#Company(String) | |
*/ | |
public Airline(String name) throws IOException { | |
super(name); | |
this.planes = new ArrayList<>(); | |
this.flights = new ArrayList<>(); | |
} | |
/** | |
* Show all the planes' info of the airline. | |
*/ | |
public void showPlanes() { | |
for (Plane plane : planes) { | |
System.out.println(plane.getInfo()); | |
} | |
} | |
/** | |
* Show all the flights' info of the airline. | |
*/ | |
public void showFlights() { | |
for (Flight flight : flights) { | |
System.out.println(flight.getInfo()); | |
} | |
} | |
/** | |
* Add a plane to the airline. | |
* @param plane The plane to add. | |
*/ | |
public void addPlane(Plane plane) { | |
planes.add(plane); | |
} | |
/** | |
* Add a flight to the airline. | |
* @param flight The flight to add. | |
*/ | |
public void addFlight(Flight flight) { | |
flights.add(flight); | |
} | |
/** | |
* Remove a plane from the airline. | |
* @param plane The ID of the plane to remove. | |
*/ | |
public void removePlane(String plane) { | |
for (Plane pl : planes) { | |
if (pl.getId().equals(plane)) { | |
planes.remove(pl); | |
break; | |
} | |
} | |
} | |
/** | |
* Remove a flight from the airline. | |
* @param flight The ID of the flight to remove. | |
*/ | |
public void removeFlight(String flight) { | |
for (Flight fl : flights) { | |
if (fl.getId().equals(flight)) { | |
flights.remove(fl); | |
break; | |
} | |
} | |
} | |
/** | |
* Execute a flight on the plane with the specified number of people. | |
* @param plane The ID of the plane to execute the flight. | |
* @param flight The ID of the flight to execute. | |
* @param peopleNumber The number of people to transport. | |
*/ | |
public void fly(String plane, String flight, int peopleNumber) throws CapacityExceededException, IOException { | |
Plane p = null; | |
for (Plane pl : planes) { | |
if (pl.getId().equals(plane)) { | |
p = pl; | |
break; | |
} | |
} | |
if (p == null) { | |
System.out.println("The plane does not exist."); | |
return; | |
} | |
Flight f = null; | |
for (Flight fl : flights) { | |
if (fl.getId().equals(flight)) { | |
f = fl; | |
break; | |
} | |
} | |
if (f == null) { | |
System.out.println("The flight does not exist."); | |
return; | |
} | |
f.execute(p, peopleNumber); | |
super.spend(p.getCost()); | |
// same effect as: spend(p.getCost()); | |
gain(peopleNumber * p.getTicket()); | |
// same effect as: super.gain(peopleNumber * p.getTicket()); | |
} | |
} | |
public class Main { | |
public static void main(String[] args) { | |
try { | |
Scanner console = new Scanner(System.in); | |
System.out.print("Enter the name of the airline: "); | |
String name = console.nextLine(); | |
Airline airline = new Airline(name); | |
boolean running = true; | |
while (running) { | |
System.out.println("Menu:"); | |
System.out.println("1. Show planes"); | |
System.out.println("2. Show flights"); | |
System.out.println("3. Add plane"); | |
System.out.println("4. Add flight"); | |
System.out.println("5. Remove plane"); | |
System.out.println("6. Remove flight"); | |
System.out.println("7. Fly"); | |
System.out.println("8. Show balance"); | |
System.out.println("9. Exit"); | |
System.out.print("Enter your choice: "); | |
char c = console.nextLine().charAt(0); | |
switch (c) { | |
case '1' -> airline.showPlanes(); | |
case '2' -> airline.showFlights(); | |
case '3' -> { | |
boolean retry; | |
do { | |
retry = false; | |
System.out.print("Enter the name of the plane: "); | |
String planeName = console.nextLine(); | |
System.out.print("Enter the capacity of the plane: "); | |
int capacity; | |
try { | |
capacity = Integer.parseInt(console.nextLine()); | |
} catch (NumberFormatException numberFormatException) { | |
System.out.println("The capacity must be an integer. Please try again."); | |
retry = true; | |
continue; | |
} | |
PlaneBrand brand; | |
try { | |
System.out.print("Enter the brand of the plane (AIRBUS, BOEING, COMAC, BOMBARDIER, GULFSTREAM): "); | |
brand = PlaneBrand.valueOf(console.nextLine()); | |
} catch (IllegalArgumentException illegalArgumentException) { | |
System.out.println("The brand is invalid. Please try again."); | |
retry = true; | |
continue; | |
} | |
int cost, ticket; | |
try { | |
System.out.print("Enter the cost of the plane to fly for one time: "); | |
cost = Integer.parseInt(console.nextLine()); | |
System.out.print("Enter the ticket price per person: "); | |
ticket = Integer.parseInt(console.nextLine()); | |
} catch (NumberFormatException numberFormatException) { | |
System.out.println("The cost and/ the ticket price must be integers. Please try again."); | |
retry = true; | |
continue; | |
} | |
try { | |
airline.addPlane(new Plane(planeName, capacity, brand, cost, ticket)); | |
} catch (CapacityIllegalException capacityIllegalException) { | |
System.out.println(capacityIllegalException.getMessage() + " Please try again."); | |
} | |
} while (retry); | |
} | |
case '4' -> { | |
boolean retry; | |
do { | |
retry = false; | |
System.out.print("Enter the directory containing flight information: "); | |
String path = console.nextLine(); | |
File file = new File(path); | |
if (!file.exists() || file.isDirectory()) { | |
System.out.println("The file does not exist or is a directory. Please try again."); | |
retry = true; | |
continue; | |
} | |
Scanner scanner = new Scanner(file); | |
while (scanner.hasNextLine()) { | |
String[] info = scanner.nextLine().split(" -> "); | |
airline.addFlight(new Flight(info[0], info[1])); | |
} | |
scanner.close(); | |
System.out.println("The flights have been added."); | |
} while (retry); | |
} | |
case '5' -> { | |
System.out.print("Enter the ID of the plane to remove: "); | |
String id = console.nextLine(); | |
airline.removePlane(id); | |
} | |
case '6' -> { | |
System.out.print("Enter the ID of the flight to remove: "); | |
String id = console.nextLine(); | |
airline.removeFlight(id); | |
} | |
case '7' -> { | |
boolean retry; | |
do { | |
retry = false; | |
System.out.print("Enter the ID of the plane: "); | |
String plane = console.nextLine(); | |
System.out.print("Enter the ID of the flight: "); | |
String flight = console.nextLine(); | |
int peopleNumber; | |
try { | |
System.out.print("Enter the number of people: "); | |
peopleNumber = Integer.parseInt(console.nextLine()); | |
} catch (NumberFormatException numberFormatException) { | |
System.out.println("The number of people must be an integer. Please try again."); | |
retry = true; | |
continue; | |
} | |
try { | |
airline.fly(plane, flight, peopleNumber); | |
} catch (CapacityExceededException capacityExceededException) { | |
System.out.println(capacityExceededException.getMessage() + " Please try again."); | |
} | |
} while (retry); | |
} | |
case '8' -> System.out.println("The balance of the airline is " + airline.getBalance()); | |
case '9' -> running = false; | |
default -> System.out.println("Invalid choice, please try again."); | |
} | |
} | |
} catch (IOException ioException) { | |
System.out.println("An IO Exception occurred."); | |
ioException.printStackTrace(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment