diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$1.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$1.class index 10a309b..dbd67a7 100644 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$1.class and b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$1.class differ diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$2.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$2.class index 2180129..7e7cd00 100644 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$2.class and b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$2.class differ diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$3.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$3.class index 5b0f9be..e675e2a 100644 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$3.class and b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$3.class differ diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$4.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$4.class deleted file mode 100644 index 3f09450..0000000 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker$4.class and /dev/null differ diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker.class index 55f081e..f239d14 100644 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker.class and b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker.class differ diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/model/PackageInfo.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/model/PackageInfo.class index 474d288..952eff4 100644 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/model/PackageInfo.class and b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/model/PackageInfo.class differ diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/Input.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/Input.class index fae1899..066b71a 100644 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/Input.class and b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/Input.class differ diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$1.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$1.class index 2d3e7c3..3153f6e 100644 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$1.class and b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$1.class differ diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$2.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$2.class index 3020277..cb2c77c 100644 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$2.class and b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$2.class differ diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$3.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$3.class index ef71f85..9357aa2 100644 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$3.class and b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$3.class differ diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$4.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$4.class index e10a20c..d070237 100644 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$4.class and b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$4.class differ diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$PACKAGE_FILTER_OPTION.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$PACKAGE_FILTER_OPTION.class index 9b28a3b..06d5c9d 100644 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$PACKAGE_FILTER_OPTION.class and b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI$PACKAGE_FILTER_OPTION.class differ diff --git a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI.class b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI.class index 203df94..bad31c4 100644 Binary files a/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI.class and b/assignment4/out/production/assignment4/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI.class differ diff --git a/assignment4/src/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker.java b/assignment4/src/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker.java index 1318249..0c41906 100644 --- a/assignment4/src/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker.java +++ b/assignment4/src/cmpt213/assignment4/packagedeliveries/client/control/PackageDeliveriesTracker.java @@ -13,15 +13,10 @@ import com.google.gson.reflect.TypeToken; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; -import java.io.*; +import java.io.IOException; 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 @@ -47,7 +42,6 @@ public class PackageDeliveriesTracker { } }).registerTypeAdapterFactory(r).create(); private static ArrayList packageList = new ArrayList<>(); - private static PackageDeliveriesTracker instance; public static PackageDeliveriesTracker getInstance() { @@ -57,171 +51,32 @@ public class 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(); - } + public String serializePackage(PackageInfo p) { + Type pType = new TypeToken() { + }.getType(); + return gson.toJson(p); } - /** - * 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); + public ArrayList deserializePackageString(String gsonString) { try { - String json = Files.readString(Paths.get(fileName)); - Type lType = new TypeToken>() { + System.out.println(gsonString + "deserializePackageString gsonString"); + Type pType = 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); - } - - public String serializePackage(PackageInfo p){ - Type pType=new TypeToken(){}.getType(); - return gson.toJson(p); - } - - public void deserializePackageString(String gsonString){ - try{ - Type pType=new TypeToken>(){}.getType(); - packageList=gson.fromJson(gsonString, pType); + if (!(packageList == null)) packageList.clear(); + packageList = gson.fromJson(gsonString, pType); System.out.println(packageList + " --> packageList"); - 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"); + if (packageList != null) { + 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"); + } } - } - catch (JsonSyntaxException e){ + } catch (JsonSyntaxException e) { e.printStackTrace(); } + return packageList; } } + diff --git a/assignment4/src/cmpt213/assignment4/packagedeliveries/client/model/PackageInfo.java b/assignment4/src/cmpt213/assignment4/packagedeliveries/client/model/PackageInfo.java index 682abf1..188c74b 100644 --- a/assignment4/src/cmpt213/assignment4/packagedeliveries/client/model/PackageInfo.java +++ b/assignment4/src/cmpt213/assignment4/packagedeliveries/client/model/PackageInfo.java @@ -80,6 +80,9 @@ public class PackageInfo implements Comparable { today.format(format); long diff = ChronoUnit.DAYS.between(today, expectedDate); String isDelivered = delivered ? "yes" : "no"; - return "Name: " + name + "\n" + "Notes: " + note + "\n" + "Price: $" + price + "\n" + "Weight: " + weight + " kg" + "\n" + "Expected Delivery Date: " + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(expectedDate) + "\n" + "Delivered? " + isDelivered + "\n" + ((diff > 0 && !delivered) ? diff + " days remaining" : abs(diff) + " days overdue"); + String remainingDays = ((diff > 0 && !delivered) ? diff + " days remaining" : abs(diff) + " days overdue"); + remainingDays = (delivered ? "" : remainingDays); + return "Name: " + name + "\n" + "Notes: " + note + "\n" + "Price: $" + price + "\n" + "Weight: " + weight + " kg" + "\n" + "Expected Delivery Date: " + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(expectedDate) + "\n" + "Delivered? " + isDelivered + "\n" + remainingDays; } } + diff --git a/assignment4/src/cmpt213/assignment4/packagedeliveries/client/view/Input.java b/assignment4/src/cmpt213/assignment4/packagedeliveries/client/view/Input.java index c29ed35..ac434bd 100644 --- a/assignment4/src/cmpt213/assignment4/packagedeliveries/client/view/Input.java +++ b/assignment4/src/cmpt213/assignment4/packagedeliveries/client/view/Input.java @@ -7,6 +7,7 @@ import cmpt213.assignment4.packagedeliveries.client.model.PackageInfo; import com.github.lgooddatepicker.components.DateTimePicker; import com.github.lgooddatepicker.optionalusertools.DateTimeChangeListener; import com.github.lgooddatepicker.zinternaltools.DateTimeChangeEvent; +import com.privatejgoodies.common.base.SystemUtils; import javax.swing.*; import java.awt.*; @@ -18,7 +19,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; -import java.util.ArrayList; import java.util.stream.Collectors; public class Input extends JDialog implements ActionListener, DateTimeChangeListener { @@ -28,12 +28,12 @@ public class Input extends JDialog implements ActionListener, DateTimeChangeList private final JTextField typeTf; private final DateTimePicker dd; private final DateTimePicker ed; - private LocalDateTime deliveryDate, expiryDate; private final JTextField nameField; private final JTextField noteField; private final JTextField priceField; private final JTextField weightField; private final JTextField dateField; + private LocalDateTime deliveryDate, expiryDate; private int pType; public Input(Frame main) { @@ -186,7 +186,7 @@ public class Input extends JDialog implements ActionListener, DateTimeChangeList PackageFactory.PackageType type = PackageFactory.PackageType.Book; String pName = nameField.getText(); String pNote = noteField.getText(); - String pEndPoint = "addBook"; + String pEndPoint = "/addBook"; double pPrice = 0.0; pPrice = Double.parseDouble(priceField.getText()); if (pPrice < 0) { @@ -207,18 +207,11 @@ public class Input extends JDialog implements ActionListener, DateTimeChangeList double pHandlingFee = 0.0; if (pType == 0) { pAuthor = typeTf.getText(); - if (pAuthor.equals("")) { - JOptionPane.showMessageDialog(this, - "author name can not be empty", - "error", - JOptionPane.WARNING_MESSAGE); - return; - } } else if (pType == 1) { - pEndPoint = "addPerishable"; + pEndPoint = "/addPerishable"; type = PackageFactory.PackageType.Perishable; } else { - pEndPoint = "addElectronic"; + pEndPoint = "/addElectronic"; type = PackageFactory.PackageType.Electronic; pHandlingFee = Double.parseDouble(typeTf.getText()); if (pHandlingFee < 0) { @@ -236,12 +229,17 @@ public class Input extends JDialog implements ActionListener, DateTimeChangeList return; } PackageInfo p = PackageFactory.create(type, pName, pNote, pPrice, pWeight, false, deliveryDate, pAuthor, expiryDate, pHandlingFee); - String packageString=pInstance.serializePackage(p); - System.out.println(packageString + " packageString before"); -packageString=packageString.replace("\"","\\\""); -System.out.println(packageString + " packageString"); -String postcmd="curl -i -H \"Content-Type: application/json\" -X " +"POST -d " + packageString +" localhost:8080/"; -invokeCmd(postcmd, pEndPoint); + String packageString = pInstance.serializePackage(p); + String postcmd = null; + if (SystemUtils.IS_OS_WINDOWS) { + packageString=packageString.replace("\"","\\\""); + postcmd = "curl -i -H \"Content-Type: application/json\" -X " + "POST -d " + packageString + " localhost:8080"; // for Windows + System.out.println(postcmd + " --> postcmd"); + } + else if(SystemUtils.IS_OS_MAC) { + postcmd = "curl -i -H Content-Type: application/json -X POST -d " + packageString + " localhost:8080"; // works on MacBook + } + invokeCmd(postcmd, pEndPoint); dispose(); } catch (Exception e) { JOptionPane.showMessageDialog(this, @@ -251,19 +249,21 @@ invokeCmd(postcmd, pEndPoint); } } - private void invokeCmd(String curlcmd, String endPoint){ + private void invokeCmd(String curlcmd, String endPoint) { try { - System.out.println(curlcmd+endPoint + " curlCmd"); - Process p=Runtime.getRuntime().exec(curlcmd+endPoint); - InputStream output=p.getInputStream(); - String allP =new BufferedReader(new InputStreamReader(output, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n")); - System.out.println(allP+" allP"); - pInstance.deserializePackageString(allP); + System.out.println(curlcmd + endPoint + " invokeCmd"); + Process p = Runtime.getRuntime().exec(curlcmd + endPoint); + InputStream output = p.getInputStream(); + String allP = new BufferedReader(new InputStreamReader(output, StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n")); +// System.out.println(allP + " allP"); +// pInstance.deserializePackageString(allP); } catch (IOException e) { - throw new RuntimeException(e); + e.printStackTrace(); + //throw new RuntimeException(e); } } } + diff --git a/assignment4/src/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI.java b/assignment4/src/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI.java index 112b4ff..f10b548 100644 --- a/assignment4/src/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI.java +++ b/assignment4/src/cmpt213/assignment4/packagedeliveries/client/view/JavaSwingUI.java @@ -1,6 +1,8 @@ package cmpt213.assignment4.packagedeliveries.client.view; import cmpt213.assignment4.packagedeliveries.client.control.PackageDeliveriesTracker; +import cmpt213.assignment4.packagedeliveries.client.model.PackageInfo; +import com.privatejgoodies.common.base.SystemUtils; import javax.swing.*; import java.awt.*; @@ -8,7 +10,13 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.stream.Collectors; public class JavaSwingUI implements ActionListener { private final PackageDeliveriesTracker pTracker = PackageDeliveriesTracker.getInstance(); @@ -17,10 +25,9 @@ public class JavaSwingUI implements ActionListener { JScrollPane scrollView; PACKAGE_FILTER_OPTION option = PACKAGE_FILTER_OPTION.ALL; - ; - public void displayMainPage() { //pTracker.load(); +// curlGetCommand("/load"); uiFrame = new JFrame("Package deliveries tracker"); uiFrame.setSize(500, 500); uiFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); @@ -28,7 +35,8 @@ public class JavaSwingUI implements ActionListener { uiFrame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { - //pTracker.save(); // TODO: replace with save endpoint + //trigger the save operation at the webserver + curlGetCommand("/exit"); super.windowClosing(e); uiFrame.dispose(); } @@ -51,48 +59,67 @@ public class JavaSwingUI implements ActionListener { uiFrame.pack(); } - private void displayPackages(ArrayList packages) { + private void displayPackages(ArrayList packages) { + ArrayList packageString = new ArrayList<>(); + if (packages != null) { + for (PackageInfo p : packages) { +// System.out.println(p.toString() + "----> p"); + packageString.add(p.toString()); + } + } else packageString.add("No packages to show"); uiPanel.removeAll(); uiPanel.setLayout(new BoxLayout(uiPanel, BoxLayout.Y_AXIS)); scrollView.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); uiPanel.add(Box.createVerticalGlue()); uiFrame.getContentPane().add(scrollView); - System.out.println(packages); - for (int i = 0; i < packages.size(); i++) { + if (packageString.size() > 0 && packageString.get(0) != "No packages to show") { + for (int i = 0; i < packages.size(); i++) { + JPanel p = new JPanel(); + JTextPane pkgPane = new JTextPane(); + pkgPane.setEditable(false); + pkgPane.setText(packageString.get(i)); + p.add(pkgPane); + if (option == PACKAGE_FILTER_OPTION.ALL) { + JButton remove = new JButton(); + int finalI = i; + int finalI2 = i; + remove.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + //pTracker.removePcakage(finalI); + curlPostCommand("/removePackage", packages.get(finalI2)); + refreshPackageList(); + } + }); + remove.setText("Remove"); + p.add(remove); + + JCheckBox delivered = new JCheckBox("Delivered?"); + delivered.setBounds(100, 100, 50, 50); + Boolean deliveredStatus = packageString.get(i).contains("Delivered? yes"); + delivered.setSelected(deliveredStatus); + int finalI1 = i; + delivered.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + delivered.setSelected(true); + curlPostCommand("/markPackageAsDelivered", packages.get(finalI2)); + refreshPackageList(); + } + }); + p.add(delivered); + } + uiPanel.add(p); + } + } else { JPanel p = new JPanel(); JTextPane pkgPane = new JTextPane(); pkgPane.setEditable(false); - pkgPane.setText(packages.get(i)); + pkgPane.setText("No packages to show"); p.add(pkgPane); - if (option == PACKAGE_FILTER_OPTION.ALL) { - JButton remove = new JButton(); - int finalI = i; - remove.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - pTracker.removePcakage(finalI); - refreshPackageList(); - } - }); - remove.setText("Remove"); - p.add(remove); - - JCheckBox delivered = new JCheckBox("Delivered?"); - delivered.setBounds(100, 100, 50, 50); - delivered.setSelected(false); // TODO: retrieve package's delivery status - int finalI1 = i; - delivered.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - delivered.setSelected(true); - //pTracker.setDelivered(finalI1); // TODO: call setDelivered endPoint - refreshPackageList(); - } - }); - p.add(delivered); - } uiPanel.add(p); } + uiFrame.validate(); uiFrame.pack(); } @@ -156,19 +183,65 @@ public class JavaSwingUI implements ActionListener { private void refreshPackageList() { switch (option) { case ALL: - ArrayList allPackages = pTracker.getAllPackages(); + ArrayList allPackages = curlGetCommand("/listAll"); +// System.out.println(allPackages + " allPackages -> refreshPackageList ALL"); displayPackages(allPackages); break; case OVERDUE: - ArrayList overDuePkg = pTracker.overDuePackages(); + ArrayList overDuePkg = curlGetCommand("/listOverduePackage"); +// System.out.println(overDuePkg + " overDuePkg -> refreshPackageList OVERDUE"); displayPackages(overDuePkg); break; case UPCOMING: - ArrayList upcomingPkg = pTracker.upcomingPackages(); + ArrayList upcomingPkg = curlGetCommand("/listUpcomingPackage"); +// System.out.println(upcomingPkg + " upcomingPkg -> refreshPackageList UPCOMING"); displayPackages(upcomingPkg); break; } } + private ArrayList curlGetCommand(String operation) { + String command = "curl -X " + "GET" + " localhost:8080" + operation; + System.out.println(command + " ==> curlGetCommand"); + try { + Process process = Runtime.getRuntime().exec(command); + InputStream stdOutput = process.getInputStream(); + String allPkg = new BufferedReader( + new InputStreamReader(stdOutput, StandardCharsets.UTF_8)) + .lines() + .collect(Collectors.joining("\n")); + return pTracker.deserializePackageString(allPkg); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void curlPostCommand(String operation, PackageInfo packageInfo) { + String packageString = pTracker.serializePackage(packageInfo); + String command = null; + if (SystemUtils.IS_OS_WINDOWS) { + System.out.println(System.getProperty("os.name").toLowerCase()); + packageString=packageString.replace("\"","\\\""); + command = "curl -i -H \"Content-Type: application/json\" -X " + "POST -d " + packageString + " localhost:8080" + operation; + System.out.println(command + " ==> curlPostCommand"); + } + else if(SystemUtils.IS_OS_MAC) { + System.out.println(System.getProperty("os.name").toLowerCase()); + command = "curl -i -H Content-Type: application/json -X POST -d " + packageString + " localhost:8080" + operation; + } + try { + Process process = Runtime.getRuntime().exec(command); + InputStream stdOutput = process.getInputStream(); + String allPkg = new BufferedReader( + new InputStreamReader(stdOutput, StandardCharsets.UTF_8)) + .lines() + .collect(Collectors.joining("\n")); + return; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + enum PACKAGE_FILTER_OPTION {ALL, OVERDUE, UPCOMING} } + diff --git a/webappserver/docs/curlCommands.txt b/webappserver/docs/curlCommands.txt index b1a54f1..d11e151 100644 --- a/webappserver/docs/curlCommands.txt +++ b/webappserver/docs/curlCommands.txt @@ -5,7 +5,82 @@ command : curl -i -X GET localhost:8080 Returns a message "system is up". GET /listAll +command : curl -X GET localhost:8080/listAll +Returns a serialized list of all packages as a JSON object +POST /addBook +example command (Windows): curl -i -H "Content-Type: application/json" -X POST -d {\"author\":\"test\",\"name\":\"testBook\",\"note\":\"\",\"price\":12.0,\"weight\":5.0,\"expectedDate\":\"2022-08-27T11:59\",\"delivered\":false,\"type\":\"book\"} localhost:8080/addBook +The body of the POST command represents the serialized PackageInfo object of Book type. -Test commands: -curl -i -H "Content-Type: application/json" -X POST -d '{\"author\":\"test\",\"name\":\"n\",\"note\":\"a\",\"price\":1,\"weight\":3,\"expectedDate\":\"2022-07-29T12:00\",\"delivered\":false,\"type\":\"book\"}' localhost:8080/addBook \ No newline at end of file +The type of fields are: +author: String +name: String +note: String +price: Double +weight: Double +expectedDate: YYYY-MM-DDTHH:MM (LocalDateTime) +delivered: Boolean +type: String + +Based on the type of the package, the first field has to be author, expiryDate or handlingFee +Returns the updated packageList as a JSON object. + +POST /addPerishable +example command: curl -i -H "Content-Type: application/json" -X POST -d {\"expiryDate\":\"2022-08-31T11:59\",\"name\":\"testPerishable\",\"note\":\"test\",\"price\":15.0,\"weight\":5.0,\"expectedDate\":\"2022-08-27T12:01\",\"delivered\":false,\"type\":\"perishable\"} localhost:8080/addPerishable + +The body of the POST command represents the serialized PackageInfo object of Perishable type. + +The type of fields are: +expiryDate: YYYY-MM-DDTHH:MM (LocalDateTime) +name: String +note: String +price: Double +weight: Double +expectedDate:YYYY-MM-DDTHH:MM (LocalDateTime) +delivered: Boolean +type: String + +Returns the updated packageList as a JSON object. + +POST /addElectronic +example command: curl -i -H "Content-Type: application/json" -X POST -d {\"handlingFee\":10.0,\"name\":\"testElectronic\",\"note\":\"none\",\"price\":100.0,\"weight\":10.0,\"expectedDate\":\"2022-08-20T08:30\",\"delivered\":false,\"type\":\"electronic\"} localhost:8080/addElectronic + +The body of the POST command represents the serialized PackageInfo object of Electronic type. + +The type of fields are: +handlingFee: Double +name: String +note: String +price: Double +weight: Double +expectedDate:YYYY-MM-DDTHH:MM (LocalDateTime) +delivered: Boolean +type: String + +Returns the updated packageList as a JSON object. + +POST /removePackage +example command: curl -i -H "Content-Type: application/json" -X POST -d {\"author\":\"test\",\"name\":\"testBook\",\"note\":\"\",\"price\":12.0,\"weight\":5.0,\"expectedDate\":\"2022-08-27T11:59\",\"delivered\":false,\"type\":\"book\"} localhost:8080/addBook + +User has to ensure the POST command data fields match one of the packages in the packageList. My system allows for removing only the packages in the list, so it acts as an error checking mechanism in itself. +It takes a serialized version of the object to be removed and returns the updated package-list as a JSON object. + +POST /markPackageAsDelivered +example command: curl -i -H "Content-Type: application/json" -X POST -d {\"handlingFee\":10.0,\"name\":\"testElectronic\",\"note\":\"none\",\"price\":100.0,\"weight\":10.0,\"expectedDate\":\"2022-08-20T08:30\",\"delivered\":false,\"type\":\"electronic\"} localhost:8080/markPackageAsDelivered + +User has to ensure the POST command data fields match one of the packages in the packageList. My system allows for marking as "delivered" only the packages in the list, so it acts as an error checking mechanism in itself. +It takes a serialized version of the object to be marked as "delivered" and returns the updated package-list as a JSON object. + +GET /listOverduePackage +command: curl -X GET localhost:8080/listOverduePackage +Returns all undelivered packages with expected delivery data before the current date and time, ordered by their expected delivery dates(oldest first) +It is returned as a list of JSON objects. + +GET /listUpcomingPackage +command: curl -X GET localhost:8080/listUpcomingPackage +Returns all upcoming packages with expected delivery data before the current date and time, ordered by their expected delivery dates(oldest first) +It is returned as a list of JSON objects. + +GET /exit +command: curl -X GET localhost:8080/exit +Triggers the server to save the current packageList into a JSON file (list.json) diff --git a/webappserver/list.json b/webappserver/list.json index e69de29..0951b7b 100644 --- a/webappserver/list.json +++ b/webappserver/list.json @@ -0,0 +1 @@ +[{"handlingFee":45.0,"name":"e","note":"n","price":35.0,"weight":3.0,"expectedDate":"2022-08-19T00:30","delivered":false,"type":"electronic"},{"handlingFee":10.0,"name":"testElectronic","note":"none","price":100.0,"weight":10.0,"expectedDate":"2022-08-20T08:30","delivered":true,"type":"electronic"},{"expiryDate":"2022-08-31T11:59","name":"testPerishable","note":"test","price":15.0,"weight":5.0,"expectedDate":"2022-08-27T12:01","delivered":false,"type":"perishable"}] \ No newline at end of file diff --git a/webappserver/src/main/java/cmpt213/assignment4/packagedeliveries/webappserver/control/PackageManager.java b/webappserver/src/main/java/cmpt213/assignment4/packagedeliveries/webappserver/control/PackageManager.java index 5df178a..6bab37b 100644 --- a/webappserver/src/main/java/cmpt213/assignment4/packagedeliveries/webappserver/control/PackageManager.java +++ b/webappserver/src/main/java/cmpt213/assignment4/packagedeliveries/webappserver/control/PackageManager.java @@ -22,6 +22,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; /** * It's a class that contains a main method that creates a TextMenu object, loads a list of packages @@ -53,13 +54,14 @@ public class PackageManager { public static PackageManager getInstance() { if (instance == null) { instance = new PackageManager(); + instance.load(); } return instance; } public void addPackage(PackageInfo p) { packageList.add(p); - //Collections.sort(packageList); + Collections.sort(packageList); } /** @@ -122,8 +124,7 @@ public class PackageManager { } public String getAllPackages() { - //Collections.sort(packageList); TODO: sorting raises error; check again - System.out.println(packageList + " packageList - server"); + Collections.sort(packageList); return gson.toJson(packageList); } @@ -164,19 +165,38 @@ public class PackageManager { public String upcomingPackages() { ArrayList upcoming = sortList(packageList, false); - return gson.toJson(packageList); +// System.out.println(upcoming + " --> upcoming packages"); + return gson.toJson(upcoming); } - public void removePcakage(int i) { - packageList.remove(i); + public void removePackage(PackageInfo p) { + Iterator itr = packageList.iterator(); + int index = 0; + while (itr.hasNext()) { + PackageInfo pkg = itr.next(); + if (pkg.toString().hashCode() == p.toString().hashCode()) { + break; + } + index += 1; + } + packageList.remove(index); } public boolean isDelivered(int i) { return packageList.get(i).getDelivered(); } - public void setDelivered(int i) { - packageList.get(i).setDelivered(true); + public void setDelivered(PackageInfo p) { + Iterator itr = packageList.iterator(); + int index = 0; + while (itr.hasNext()) { + PackageInfo pkg = itr.next(); + if (pkg.toString().hashCode() == p.toString().hashCode()) { + break; + } + index += 1; + } + packageList.get(index).setDelivered(true); } public PackageInfo deserializePackage(String packageGson){ @@ -204,3 +224,4 @@ public PackageInfo deserializePackage(String packageGson){ return newPackage; } } + diff --git a/webappserver/src/main/java/cmpt213/assignment4/packagedeliveries/webappserver/controllers/PackageController.java b/webappserver/src/main/java/cmpt213/assignment4/packagedeliveries/webappserver/controllers/PackageController.java index bc2cf69..55e374a 100644 --- a/webappserver/src/main/java/cmpt213/assignment4/packagedeliveries/webappserver/controllers/PackageController.java +++ b/webappserver/src/main/java/cmpt213/assignment4/packagedeliveries/webappserver/controllers/PackageController.java @@ -22,6 +22,18 @@ public class PackageController { return manager.getAllPackages(); } + @GetMapping("/listOverduePackage") + @ResponseStatus(HttpStatus.OK) + public String getOverduePackages() { + return manager.overDuePackages(); + } + + @GetMapping("/listUpcomingPackage") + @ResponseStatus(HttpStatus.OK) + public String getUpcomingPackages() { + return manager.upcomingPackages(); + } + @PostMapping("/addBook") @ResponseStatus(HttpStatus.CREATED) public String addBook(@RequestBody String bookString){ @@ -49,4 +61,28 @@ public class PackageController { manager.addPackage(p); return manager.getAllPackages(); } + + @PostMapping("/removePackage") + @ResponseStatus(HttpStatus.CREATED) + public String removePackage(@RequestBody String pkg) { + PackageInfo p = manager.deserializePackage(pkg); + manager.removePackage(p); + return manager.getAllPackages(); + } + + @PostMapping("/markPackageAsDelivered") + @ResponseStatus(HttpStatus.CREATED) + public String markPackageAsDelivered(@RequestBody String pkg) { + PackageInfo p = manager.deserializePackage(pkg); + manager.setDelivered(p); + return manager.getAllPackages(); + } + + @GetMapping("/exit") + @ResponseStatus(HttpStatus.OK) + public void savePackages() { + manager.save(); + } + } + diff --git a/webappserver/src/main/java/cmpt213/assignment4/packagedeliveries/webappserver/model/PackageInfo.java b/webappserver/src/main/java/cmpt213/assignment4/packagedeliveries/webappserver/model/PackageInfo.java index 8012b74..c6b8a43 100644 --- a/webappserver/src/main/java/cmpt213/assignment4/packagedeliveries/webappserver/model/PackageInfo.java +++ b/webappserver/src/main/java/cmpt213/assignment4/packagedeliveries/webappserver/model/PackageInfo.java @@ -85,6 +85,9 @@ public class PackageInfo implements Comparable { today.format(format); long diff = ChronoUnit.DAYS.between(today, expectedDate); String isDelivered = delivered ? "yes" : "no"; - return "Name: " + name + "\n" + "Notes: " + note + "\n" + "Price: $" + price + "\n" + "Weight: " + weight + " kg" + "\n" + "Expected Delivery Date: " + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(expectedDate) + "\n" + "Delivered? " + isDelivered + "\n" + ((diff > 0 && !delivered) ? diff + " days remaining" : abs(diff) + " days overdue"); + String remainingDays = ((diff > 0 && !delivered) ? diff + " days remaining" : abs(diff) + " days overdue"); + remainingDays = (delivered ? "" : remainingDays); + return "Name: " + name + "\n" + "Notes: " + note + "\n" + "Price: $" + price + "\n" + "Weight: " + weight + " kg" + "\n" + "Expected Delivery Date: " + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(expectedDate) + "\n" + "Delivered? " + isDelivered + "\n" + remainingDays; } } +