This commit is contained in:
louiscklaw
2025-02-01 01:58:47 +08:00
parent b3da7aaef5
commit 04dbefcbaf
1259 changed files with 280657 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
# ITP4507-Assignment
Contemporary Topics in Software Engineering

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="ITP4507Assignment" default="default" basedir=".">
<description>Builds, tests, and runs the project ITP4507Assignment.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar: JAR building
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="ITP4507Assignment-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
</project>

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
build.xml.data.CRC32=90b39c8c
build.xml.script.CRC32=f79e556f
build.xml.stylesheet.CRC32=8064a381@1.80.1.48
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=90b39c8c
nbproject/build-impl.xml.script.CRC32=144b22ed
nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48

View File

@@ -0,0 +1,7 @@
application.args=19 55 56 63 37 75 55
compile.on.save=true
do.depend=false
do.jar=true
javac.debug=true
javadoc.preview=true
user.properties.file=C:\\Users\\jerry\\AppData\\Roaming\\NetBeans\\8.2\\build.properties

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
<group/>
</open-files>
</project-private>

View File

@@ -0,0 +1,76 @@
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.processors.list=
annotation.processing.run.all.processors=true
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.title=ITP4507Assignment
application.vendor=JerryKwok
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.test.classpath=\
${run.test.classpath}
# Files in build.classes.dir which should be excluded from distribution jar
dist.archive.excludes=
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/ITP4507Assignment.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
includes=**
jar.compress=false
javac.classpath=
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.external.vm=true
javac.processorpath=\
${javac.classpath}
javac.source=1.8
javac.target=1.8
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
javac.test.processorpath=\
${javac.test.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
main.class=Assignment
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
platform.active=default_platform
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project.
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
# To set system properties for unit tests define test-sys-prop.name=value:
run.jvmargs=
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
source.encoding=UTF-8
src.dir=src
test.src.dir=test

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>ITP4507Assignment</name>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots>
<root id="test.src.dir"/>
</test-roots>
</data>
</configuration>
</project>

View File

@@ -0,0 +1,61 @@
import java.util.ArrayList;
import java.util.Scanner;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author jerrykwok
*/
public class Assignment {
private static Scanner input;
private static ArrayList<CoffeeProduct> productList;
private static StateManager stateMang;
private static CommandHandler ch;
public static void main(String[] args) {
input = new Scanner(System.in);
productList = createList();
stateMang = createStateManager();
ch = createCommand();
run();
}
public static void run(){
while (true) {
System.out.println("Coffee Inventory Management System");
ch.printCommandList();
String cmd = input.nextLine();
boolean result = ch.run(cmd);
if (!result) {
System.out.println("No Command Match");
}
System.out.println("");
}
}
public static CommandHandler createCommand() {
CommandHandler ch = new CommandHandler(stateMang);
ch.regCommand("a", new AddProductCommandFactory(input, productList));
ch.regCommand("v", new ViewProductCommandFactory(input, productList));
ch.regCommand("c", new CollectProductCommandFactory(input, productList, stateMang));
ch.regCommand("s", new SendCoffeeProductCommandFactory(input, productList, stateMang));
ch.regCommand("u", new UndoLastCommandFactory(stateMang));
ch.regCommand("r", new RedoLastCommandFactory(stateMang));
ch.regCommand("sl", new ViewUndoRedoListCommandFactory(stateMang));
ch.regCommand("x", new ExitCommandFactory());
return ch;
}
public static StateManager createStateManager() {
return new StateManager();
}
private static ArrayList<CoffeeProduct> createList(){
return new ArrayList<CoffeeProduct>();
}
}

View File

@@ -0,0 +1,51 @@
import java.util.Stack;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author jerrykwok
*/
public class Caretaker {
private Stack<CoffeeProductMemento> undoList;
private Stack<CoffeeProductMemento> redoList;
public Caretaker() {
undoList = new Stack();
redoList = new Stack();
}
public void saveCoffeeProduct(CoffeeProductMemento xcoffeeProd) {
redoList.clear();
undoList.push(xcoffeeProd);
}
public void undo() {
if (undoList.isEmpty()) {
System.out.println("UndoList is Empty");
return;
}
CoffeeProductMemento obj = undoList.pop();
redoList.push(obj.getOrig().saveMemento());
obj.restore();
}
public void redo() {
if (redoList.isEmpty()) {
System.out.println("RedoList is Empty");
return;
}
CoffeeProductMemento obj = redoList.pop();
undoList.push(obj.getOrig().saveMemento());
obj.restore();
}
}

View File

@@ -0,0 +1,51 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author jerrykwok
*/
public class CoffeeCandy extends CoffeeProduct {
private int noOfCandy;
private int caloriesPerCandy;
public CoffeeCandy(String name, int productID, int noOfCandy, int caloriesPerCandy) {
super(name, productID);
this.noOfCandy = noOfCandy;
this.caloriesPerCandy = caloriesPerCandy;
}
public int getNoOfCandy() {
return noOfCandy;
}
public int getCaloriesPerCandy() {
return caloriesPerCandy;
}
public void setNoOfCandy(int noOfCandy) {
this.noOfCandy = noOfCandy;
}
public void setCaloriesPerCandy(int caloriesPerCandy) {
this.caloriesPerCandy = caloriesPerCandy;
}
@Override
public String toString() {
return super.toString() + "Number of candies per package: " + getNoOfCandy() + "\n" + "Calories Per candy: " + getCaloriesPerCandy();
}
public String printList() {
return super.printList() +"\t"+ getQty()+ "\t\t" + getNoOfCandy() + " candy per package (" + getCaloriesPerCandy() + " calories each)";
}
public CoffeeProductMemento saveMemento(){
return new CoffeeCandyMemento(this);
}
}

View File

@@ -0,0 +1,57 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author jerrykwok
*/
public abstract class CoffeeProduct {
private String name;
private int productID;
private int qty;
public CoffeeProduct(String name, int productID) {
this.name = name;
this.productID = productID;
}
public String getName() {
return name;
}
public int getProductID() {
return productID;
}
public int getQty() {
return qty;
}
public void setName(String name) {
this.name = name;
}
public void setProductID(int productID) {
this.productID = productID;
}
public void setQty(int qty) {
this.qty = qty;
}
@Override
public String toString() {
return "ID: " + getProductID() + "\nName: " + getName() + "\nQuantity: " + getQty() + "\n";
}
public String printList() {
return getProductID() + "\t" + getName() + "\t" ;
}
public abstract CoffeeProductMemento saveMemento();
}

View File

@@ -0,0 +1,75 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author jerrykwok
*/
public interface CoffeeProductMemento {
public CoffeeProduct getOrig();
public void restore();
}
class CoffeeCandyMemento implements CoffeeProductMemento{
private int noOfCandy;
private int caloriesPerCandy;
private int qty;
private CoffeeCandy mcoffeeCandy;
public CoffeeCandyMemento(CoffeeCandy mcoffeeCandy) {
this.noOfCandy = mcoffeeCandy.getNoOfCandy();
this.caloriesPerCandy = mcoffeeCandy.getCaloriesPerCandy();
this.qty = mcoffeeCandy.getQty();
this.mcoffeeCandy = mcoffeeCandy;
}
@Override
public CoffeeProduct getOrig() {
return mcoffeeCandy;
}
@Override
public void restore() {
mcoffeeCandy.setCaloriesPerCandy(caloriesPerCandy);
mcoffeeCandy.setNoOfCandy(noOfCandy);
mcoffeeCandy.setQty(qty);
}
public String print() {
return "CoffeeCandyMemento{" + "noOfCandy=" + noOfCandy + ", caloriesPerCandy=" + caloriesPerCandy + ", mcoffeeCandy=" + mcoffeeCandy + '}';
}
}
class CoffeeProwderMemento implements CoffeeProductMemento{
private double wegiht;
private int qty;
private CoffeeProwder mcoffeeProwder;
public CoffeeProwderMemento(CoffeeProwder mcoffeeProwder) {
this.wegiht = mcoffeeProwder.getWegiht();
this.qty = mcoffeeProwder.getQty();
this.mcoffeeProwder = mcoffeeProwder;
}
@Override
public CoffeeProduct getOrig() {
return mcoffeeProwder;
}
@Override
public void restore() {
mcoffeeProwder.setWegiht(this.wegiht);
mcoffeeProwder.setQty(qty);
}
}

View File

@@ -0,0 +1,41 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author jerrykwok
*/
public class CoffeeProwder extends CoffeeProduct {
private double wegiht;
public CoffeeProwder(String name, int productID, double wegiht) {
super(name, productID);
this.wegiht = wegiht;
}
public double getWegiht() {
return wegiht;
}
public void setWegiht(double wegiht) {
this.wegiht = wegiht;
}
public String toString() {
return super.toString() + "Wegiht: " + getWegiht() + "\n";
}
public String printList() {
return super.printList() + "\t\t" + getQty() + "\t\t" + (int)(getWegiht()) + "g";
}
public CoffeeProductMemento saveMemento(){
return new CoffeeProwderMemento(this);
}
}

View File

@@ -0,0 +1,423 @@
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author jerrykwok
*/
public abstract class Command {
public abstract boolean execute();
}
interface UndoAllowCommand {
public void redo();
public void undo();
}
class AddProductCommand extends Command implements UndoAllowCommand {
private ArrayList productList;
private Scanner input;
CoffeeProduct coffeeProduct;
public AddProductCommand(Scanner input, ArrayList productList) {
this.input = input;
this.productList = productList;
}
@Override
public boolean execute() {
System.out.println("Enter Coffee type (cc=Coffee Candy/cp=Coffee Powder):");
String type = input.nextLine();
switch (type) {
case "cc":
System.out.println("Enter product id, name, number of candy and calories per candy:");
String ccValue = input.nextLine();
String[] ccParameters = ccValue.split(", ");
if(ccParameters.length==1)
ccParameters = ccValue.split(",");
if (ccParameters.length != 4) {
System.out.println("Invalid parameter length");
return false;
}
try {
System.out.println();
int productId = Integer.parseInt(ccParameters[0]);
String name = ccParameters[1];
int noOfCandy = Integer.parseInt(ccParameters[2]);
int caloriesPerCandy = Integer.parseInt(ccParameters[3]);
if (checkProducrID(productList, productId)) {
System.out.println("The id: " + productId + "is already exist");
return false;
}
coffeeProduct = creatCoffeeProduct(name, productId, noOfCandy, caloriesPerCandy);
} catch (NumberFormatException e) {
System.out.println("Invalid parameter: productID, Number of candy and Calories must be Integer");
return false;
}
break;
case "cp":
System.out.println("Enter product Id , name and weight(g):");
String cpValue = input.nextLine();
String[] cpParameters = cpValue.split(", ");
if(cpParameters.length==1)
cpParameters = cpValue.split(",");
if (cpParameters.length != 3) {
System.out.println("Invalid parameter length");
return false;
}
try {
int productId = Integer.parseInt(cpParameters[0]);
String name = cpParameters[1];
int wegiht = Integer.parseInt(cpParameters[2]);
if (checkProducrID(productList, productId)) {
System.out.println("The id: " + productId + "is already exist");
return false;
}
coffeeProduct = creatCoffeeProduct(name, productId, wegiht);
} catch (NumberFormatException e) {
System.out.println("Invalid parameter: productID, Number of candy and Calories must be Integer");
return false;
}
break;
default:
System.out.println("Invalid Coffee Prodcut Type");
return false;
}
productList.add(coffeeProduct);
System.out.println("New product record created.\n");
return true;
}
@Override
public void redo() {
productList.add(coffeeProduct);
}
@Override
public void undo() {
productList.remove(coffeeProduct);
}
public static CoffeeProduct creatCoffeeProduct(String name, int productID, int noOfCandy, int caloriesPerCandy) {
return new CoffeeCandy(name, productID, noOfCandy, caloriesPerCandy);
}
public static CoffeeProduct creatCoffeeProduct(String name, int productID, int wegiht) {
return new CoffeeProwder(name, productID, wegiht);
}
public boolean checkProducrID(ArrayList<CoffeeProduct> productList, int id) {
boolean invalid = false;
for (CoffeeProduct product : productList) {
if (product.getProductID() == id) {
return true;
}
}
return false;
}
@Override
public String toString() {
return "Add " + coffeeProduct.getProductID() +" " + coffeeProduct.getName();
}
}
class ViewProductCommand extends Command {
private ArrayList<CoffeeProduct> productList;
private Scanner input;
public ViewProductCommand(Scanner input, ArrayList productList) {
this.input = input;
this.productList = productList;
}
@Override
public boolean execute() {
System.out.println("Enter product Id. (* to show all):");
String id = input.nextLine();
System.out.println("");
if (id.equals("*")) {
System.out.println("Coffee Product information");
System.out.println("ID\tName\t\t\t\tQuantity\tOther Info");
for (CoffeeProduct product : productList) {
System.out.println(product.printList());
}
} else {
try {
int productId = Integer.parseInt(id);
System.out.println("Product information");
boolean succe = false;
for (CoffeeProduct product : productList) {
if (product.getProductID() == productId) {
System.out.println(product);
succe = true;
break;
}
}
if (!succe) {
System.out.println("Not this ID: " + productId + " Product");
}
} catch (NumberFormatException e) {
System.out.println("Invalid id, id must be integer only");
return false;
}
}
return true;
}
}
class CollectProductCommand extends Command implements UndoAllowCommand {
private ArrayList<CoffeeProduct> productList;
private Scanner input;
private StateManager state;
private CoffeeProduct coffeeProduct;
private int productQty;
public CollectProductCommand(Scanner input, ArrayList<CoffeeProduct> productList, StateManager state) {
this.productList = productList;
this.input = input;
this.state = state;
}
@Override
public boolean execute() {
int productId;
try {
System.out.println("Enter product id:");
String id = input.nextLine();
productId = Integer.parseInt(id);
} catch (NumberFormatException e) {
System.out.println("Invalid id, id must be integer only");
return false;
}
try {
System.out.println("Quantity to receive:");
String qty = input.nextLine();
productQty = Integer.parseInt(qty);
} catch (NumberFormatException e) {
System.out.println("Invalid Quantity, Quantity must be integer only");
return false;
}
boolean invalid = true;
for (CoffeeProduct product : productList) {
if (product.getProductID() == productId) {
coffeeProduct = product;
state.getCaretaker().saveCoffeeProduct(product.saveMemento());
product.setQty(product.getQty() + productQty);
System.out.println("Received " + productQty + " packs of " + product.getName() + ". Current quantity is " + product.getQty() + ".");
invalid = false;
break;
}
}
if (invalid) {
System.out.println("No such Coffee Product");
return false;
}
return true;
}
@Override
public void redo() {
state.getCaretaker().redo();
}
@Override
public void undo() {
state.getCaretaker().undo();
}
public String toString(){
return "Received " + productQty + " " +coffeeProduct.getName() + " ("+coffeeProduct.getProductID()+")";
}
}
class SendCoffeeProductCommand extends Command implements UndoAllowCommand {
private ArrayList<CoffeeProduct> productList;
private Scanner input;
private StateManager state;
private CoffeeProduct coffeeProduct;
private int shipQty;
public SendCoffeeProductCommand(Scanner input, ArrayList<CoffeeProduct> productList, StateManager state) {
this.productList = productList;
this.input = input;
this.state = state;
}
@Override
public boolean execute() {
int productId;
try {
System.out.println("Enter product id:");
String id = input.nextLine();
productId = Integer.parseInt(id);
} catch (NumberFormatException e) {
System.out.println("Invalid id, id must be integer only");
return false;
}
try {
System.out.println("Quantity to ship:");
String qty = input.nextLine();
shipQty = Integer.parseInt(qty);
} catch (NumberFormatException e) {
System.out.println("Invalid Quantity, Quantity must be integer only");
return false;
}
boolean succe = true;
for (CoffeeProduct product : productList) {
if (product.getProductID() == productId) {
if ((product.getQty() - shipQty) < 0) {
System.out.println("Invalid quantity (current balance is less than required quantity). Try again!!!");
return false;
}
coffeeProduct = product;
state.getCaretaker().saveCoffeeProduct(product.saveMemento());
product.setQty(product.getQty() - shipQty);
System.out.println("Shipped " + shipQty +" packs of Premium Coffee Candy. Current quantity is "+ product.getQty()+".");
succe = false;
break;
}
}
if (succe) {
System.out.println("No such Coffee Product");
return false;
}
return true;
}
@Override
public void redo() {
state.getCaretaker().redo();
}
@Override
public void undo() {
state.getCaretaker().undo();
}
public String toString(){
return "Shipped " + shipQty + " " + coffeeProduct.getName() + " (" + coffeeProduct.getProductID()+ ")";
}
}
class UndoLastCommand extends Command {
private StateManager state;
public UndoLastCommand(StateManager state) {
this.state = state;
}
@Override
public boolean execute() {
if (state.getUndoList().isEmpty()) {
System.out.println("Nothing to undo");
} else {
Stack<UndoAllowCommand> UndoList = state.getUndoList();
UndoAllowCommand undoCmd = UndoList.pop();
state.getRedoList().push(undoCmd);
undoCmd.undo();
System.out.println("undo completed.");
}
return true;
}
}
class RedoLastCommand extends Command {
private StateManager state;
public RedoLastCommand(StateManager state) {
this.state = state;
}
@Override
public boolean execute() {
if (state.getRedoList().isEmpty()) {
System.out.println("Nothing to Redo");
} else {
Stack<UndoAllowCommand> redoList = state.getRedoList();
UndoAllowCommand redoCmd = redoList.pop();
state.getUndoList().push(redoCmd);
redoCmd.redo();
System.out.println("Redo completed.");
}
return true;
}
}
class ViewUndoRedoListCommand extends Command {
private StateManager state;
public ViewUndoRedoListCommand(StateManager state) {
this.state = state;
}
@Override
public boolean execute() {
System.out.println("Undo List:");
if (state.getUndoList().isEmpty()) {
System.out.println("Empty");
} else {
state.getUndoList().forEach(System.out::println);
}
System.out.println();
System.out.println("Redo List:");
if (state.getRedoList().isEmpty()) {
System.out.println("Empty");
} else {
state.getRedoList().forEach(System.out::println);
}
return true;
}
}
class ExitCommand extends Command {
@Override
public boolean execute() {
System.out.println("Thanks for using Coffee Inventory Management System!!");
System.exit(0);
return true;
}
}

View File

@@ -0,0 +1,181 @@
import java.util.ArrayList;
import java.util.Scanner;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author jerrykwok
*/
public interface CommandFactory {
public String getCommandName();
public Command createCommand();
}
class AddProductCommandFactory implements CommandFactory {
private Scanner sc;
private ArrayList productList;
public AddProductCommandFactory(Scanner sc, ArrayList productList) {
this.sc = sc;
this.productList = productList;
}
public String getCommandName() {
return "add product, ";
}
public Command createCommand() {
return new AddProductCommand(sc, productList);
}
}
class ViewProductCommandFactory implements CommandFactory {
private Scanner sc;
private ArrayList productList;
public ViewProductCommandFactory(Scanner sc, ArrayList productList) {
this.sc = sc;
this.productList = productList;
}
@Override
public String getCommandName() {
return "view products, ";
}
@Override
public Command createCommand() {
return new ViewProductCommand(sc, productList);
}
}
class CollectProductCommandFactory implements CommandFactory {
private Scanner sc;
private ArrayList productList;
private StateManager state;
public CollectProductCommandFactory(Scanner sc, ArrayList productList, StateManager state) {
this.sc = sc;
this.productList = productList;
this.state = state;
}
@Override
public String getCommandName() {
return "collect product, ";
}
@Override
public Command createCommand() {
return new CollectProductCommand(sc, productList, state);
}
}
class SendCoffeeProductCommandFactory implements CommandFactory {
private Scanner sc;
private ArrayList productList;
private StateManager state;
public SendCoffeeProductCommandFactory(Scanner sc, ArrayList productList, StateManager state) {
this.sc = sc;
this.productList = productList;
this.state = state;
}
@Override
public String getCommandName() {
return "ship product, \n";
}
@Override
public Command createCommand() {
return new SendCoffeeProductCommand(sc, productList, state);
}
}
class UndoLastCommandFactory implements CommandFactory {
private StateManager state;
public UndoLastCommandFactory(StateManager state) {
this.state = state;
}
@Override
public String getCommandName() {
return "undo, ";
}
@Override
public Command createCommand() {
return new UndoLastCommand(state);
}
}
class ViewUndoRedoListCommandFactory implements CommandFactory {
private StateManager state;
public ViewUndoRedoListCommandFactory(StateManager state) {
this.state = state;
}
@Override
public String getCommandName() {
return "show list undo/redo, ";
}
@Override
public Command createCommand() {
return new ViewUndoRedoListCommand(state);
}
}
class RedoLastCommandFactory implements CommandFactory {
private StateManager state;
public RedoLastCommandFactory(StateManager state) {
this.state = state;
}
@Override
public String getCommandName() {
return "redo, ";
}
@Override
public Command createCommand() {
return new RedoLastCommand(state);
}
}
class ExitCommandFactory implements CommandFactory {
@Override
public String getCommandName() {
return "exit system";
}
@Override
public Command createCommand() {
return new ExitCommand();
}
}

View File

@@ -0,0 +1,59 @@
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author jerrykwok
*/
public class CommandHandler {
private LinkedHashMap<String, CommandFactory> mapCmds;
private StateManager state;
public CommandHandler(StateManager state) {
this.mapCmds = new LinkedHashMap<String, CommandFactory>();
this.state = state;
}
public void regCommand(String key, CommandFactory cmdFactory) {
mapCmds.put(key, cmdFactory);
}
public void printCommandList() {
System.out.print("Please enter command: [");
System.out.print(String.join(" | ", mapCmds.keySet()));
System.out.println("]");
for (Map.Entry<String, CommandFactory> mapCmd : mapCmds.entrySet()) {
System.out.print(mapCmd.getKey() + " = " + mapCmd.getValue().getCommandName());
}
System.out.println("\n");
}
public boolean run(String cmd) {
CommandFactory commandFactory = mapCmds.get(cmd);
if (commandFactory != null) {
Command command = commandFactory.createCommand();
boolean result = command.execute();
if (result) {
switch (cmd) {
case "a":
case "c":
case "s":
state.getUndoList().add(command);
state.getRedoList().clear();
}
}
return true;
}
return false;
}
}

View File

@@ -0,0 +1,36 @@
import java.util.Stack;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author jerrykwok
*/
public class StateManager {
private Stack redoList;
private Stack undoList;
private Caretaker caretaker;
public StateManager() {
undoList = new Stack<>();
redoList = new Stack<>();
caretaker = new Caretaker();
}
public Caretaker getCaretaker(){
return caretaker;
}
public Stack getUndoList() {
return undoList;
}
public Stack getRedoList() {
return redoList;
}
}