package cmpt213.assignment4.packagedeliveries.client.control; import cmpt213.assignment4.packagedeliveries.client.gson.extras.RuntimeTypeAdapterFactory; import cmpt213.assignment4.packagedeliveries.client.model.BookPackage; import cmpt213.assignment4.packagedeliveries.client.model.ElectronicPackage; import cmpt213.assignment4.packagedeliveries.client.model.PackageInfo; import cmpt213.assignment4.packagedeliveries.client.model.PerishablePackage; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.TypeAdapter; import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import java.io.*; import java.lang.reflect.Type; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.nio.file.Paths; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; /** * It's a class that contains a main method that creates a TextMenu object, loads a list of packages * from a file, and then loops through a menu of options until the user chooses to quit */ public class PackageDeliveriesTracker { private static final String fileName = "list.json"; private static final RuntimeTypeAdapterFactory r = RuntimeTypeAdapterFactory.of(PackageInfo.class, "type") .registerSubtype(BookPackage.class, "book") .registerSubtype(PerishablePackage.class, "perishable") .registerSubtype(ElectronicPackage.class, "electronic"); private static final Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new TypeAdapter() { @Override public void write(JsonWriter jsonWriter, LocalDateTime localDateTime) throws IOException { jsonWriter.value(localDateTime.toString()); } @Override public LocalDateTime read(JsonReader jsonReader) throws IOException { return LocalDateTime.parse(jsonReader.nextString()); } }).registerTypeAdapterFactory(r).create(); private static ArrayList packageList = new ArrayList<>(); private static PackageDeliveriesTracker instance; public static PackageDeliveriesTracker getInstance() { if (instance == null) { instance = new PackageDeliveriesTracker(); } return instance; } public void addPackage(PackageInfo p) { packageList.add(p); Collections.sort(packageList); } /** * It saves the packageList to a file. */ public void save() { try { Writer w = new FileWriter(fileName); gson.toJson(packageList, w); w.flush(); w.close(); } catch (IOException e) { e.printStackTrace(); } } /** * It reads the json file, converts it to a list of PackageInfo objects, and then sets the type of * each object to the appropriate type */ public void load() { //File file = new File(fileName); try { String json = Files.readString(Paths.get(fileName)); Type lType = new TypeToken>() { }.getType(); packageList = gson.fromJson(json, lType); for (PackageInfo p : packageList) { if (p instanceof BookPackage) { p.setType("book"); } else if (p instanceof PerishablePackage) { p.setType("perishable"); } else if (p instanceof ElectronicPackage) { p.setType("electronic"); } } System.out.println("packages loaded"); } catch (FileNotFoundException e) { System.out.println("no packages to load"); } catch (NoSuchFileException e) { createFile(); //throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } private void createFile() { System.out.println("CreateFile"); try { File packages = new File(fileName); if(packages.createNewFile()) { System.out.println("New file list.json created"); } } catch (IOException e) { System.out.println("No file exists, creating a new file"); e.printStackTrace(); } } public ArrayList getAllPackages() { ArrayList b = new ArrayList<>(); if (packageList.size() == 0) { b.add("No packages to show"); } else { Collections.sort(packageList); for (int i = 0; i < packageList.size(); i++) { String bString = ("Package #" + (i + 1)) + "\n" + packageList.get(i) + "\n\n"; b.add(bString); } } return b; } /** * This function takes in a list of packages, a boolean for whether or not the user wants to see * packages that are due, and a boolean for whether or not the user wants to see all packages. It * then returns a list of packages that are sorted by their expected delivery date * * @param pList the list of packages to be sorted * @param due true if you want to sort the list by due date, false if you want to sort the list by * expected date * @return An ArrayList of PackageInfo objects. */ //due=true returns overdue packages, else upcoming packages public ArrayList sortList(ArrayList pList, boolean due) { ArrayList sortedList = new ArrayList<>(); LocalDateTime today = LocalDateTime.now(); DateTimeFormatter format = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm"); today.format(format); for (int i = 0; i < pList.size(); i++) { PackageInfo p = pList.get(i); if (!p.getDelivered()) { if (due && today.isAfter(p.getExpectedDate())) { sortedList.add(p); } else if (!due && today.isBefore(p.getExpectedDate())) { sortedList.add(p); } } } Collections.sort(sortedList); return sortedList; } public ArrayList overDuePackages() { ArrayList b = new ArrayList<>(); ArrayList overdue = sortList(packageList, true); if (overdue.size() == 0) { b.add("no overdue packages to show"); } for (int i = 0; i < overdue.size(); i++) { String bString = ("Package #" + (i + 1)) + "\n" + overdue.get(i) + "\n\n"; b.add(bString); } return b; } public ArrayList upcomingPackages() { ArrayList b = new ArrayList<>(); ArrayList upcoming = sortList(packageList, false); if (upcoming.size() == 0) { b.add("no upcoming packages to show"); } for (int i = 0; i < upcoming.size(); i++) { String bString = ("Package #" + (i + 1)) + "\n" + upcoming.get(i) + "\n\n"; b.add(bString); } return b; } public void removePcakage(int i) { packageList.remove(i); } public boolean isDelivered(int i) { return packageList.get(i).getDelivered(); } public void setDelivered(int i) { packageList.get(i).setDelivered(true); } }