The goals of this assignment are to:
Cloud platforms that allow users to rent / use machines are become very famous. These rentable machines are maintained by the cloud provider. Cloudlab is an example of one such service; UW-Madison is one of the cloud providers for cloudlab. As the user, you will have a set of machines in your list, you can rent them if they are available. You will be using multiple linked lists to track the users of such a system, the machines that are available for renting, current list of machines that a user wants to rent and so on.
Your program will simulate the basic user experience allowing users to select what they'd like to add to their machinelist. Following are description of components of the program that will be initialized at program start up and will not be modified further:
Users are then allowed to add and remove machines from their list. The items in a users machinelist are ordered by price from highest to lowest. The program enables a users to login to their account, view all the items in the cloud, add items to or remove items from their machinelists, and rent items on their machinelists that are in stock.
The main class Cloud prompts the user to login. It then enables the user to enter the required operation that can manipulate the machinelist of machines. Machinelists will be represented using a DLinkedList class that you will also write. Your DLinkedList class implements the ListADT interface using a doubly-linked chain of nodes. You will also implement a checked exception - InsufficientCreditException class which will be used to signal and handle problems when a user doesn't have enough credit to rent a machine. You will also be writing the User and Machine classes that track users and machines.
A ListADT<E> interface, provided to you (see ListADT.java), is a generic interface that you will implement in your DLinkedList class. The interface describes the following methods:
Note: If a method throws two exceptions, follow the order as given in this specification and in the interface method header.Method | Description |
---|---|
void add(E item) | Adds item to the end of the List. Throws IllegalArgumentException if item is null. |
void add(int pos,E item) | Adds item at position pos in the List, moving the items originally in
positions pos through size() - 1 one place to the right to make room.
Throws IllegalArgumentException if item is null and IndexOutOfBoundsException if pos is less than 0 or greater than size(). |
boolean contains(E item) | Returns true iff item is in the List (i.e., there is an item x in the List
such that x.equals(item)) Throws IllegalArgumentException if item is null or list is null. |
E get(int pos) | Returns the item at position pos in the List. Throws IllegalArgumentException if list is null and IndexOutOfBoundsException if pos is less than 0 or greater than or equal to size(). |
boolean isEmpty() | Returns true iff the List is empty. |
E remove(int pos) | Removes and returns the item at position pos in the List, moving the items
originally in positions pos+1 through size() - 1 one place to the left to
fill in the gap. Throws IllegalArgumentException if list is null and IndexOutOfBoundsException if pos is less than 0 or greater than or equal to size() |
int size() | Return the number of items in the List. |
Do not modify the ListADT interface in any way.
The DLinkedList<E> Class
Following are some specifications about the DLinkedList class that implements ListADT interface:
The DblListnode<E> class represents one node of a DLinkedList. This class is also provided to you (see DblListnode.java). It has the following methods and constructors:
Constructor | Description |
---|---|
Listnode<E>(E data) | Constructs a Listnode<E> with data and anull reference to its previous and next nodes. |
Listnode<E>(E data, Listnode<E> next, Listnode<E> prev) | Constructs a Listnode<E> with data and references to prev and next nodes. |
Method | Description |
E getData() | Returns the data cloudd in this node. |
Listnode<E> getNext() | Returns the Listnode<E> that comes after this Listnode<E>. Returns null if this node does not have a next node. |
Listnode<E> getPrev() | Returns the Listnode<E> that comes before this Listnode<E>. Returns null if this node does not have a previous node. |
void setData(E data) | Sets the data cloudd in this node to data. |
void setNext(Listnode<E> next) | Sets the next node to reference next Listnode<E>. |
void setPrev(Listnode<E> prev) | Sets the previous node to reference prev Listnode<E>. |
Do not modify the Listnode class in any way.
The Machine class represents a single Machine in the cloud platform. A shell of this class is also provided for you (see Machine.java). It has the following methods and constructor:
Constructor | Description |
---|---|
Machine(String machineName, int numCPUs, int memorySize, int diskSize, double price) | Constructs a Machine with a machineName, numCPUs, memorySize, diskSize and price. |
Method | Description |
String getName() | Returns the name of the machine. |
int getCPUs() | Returns the number of CPU's of the machine. |
int getMemorySize() | Returns the RAM size in GB's. |
int getDiskSize() | Returns the hard disk size in GB's. |
double getPrice() | Returns the price of the machine. |
String toString() |
Returns a String of this Machine's information in the following format:<NAME> [Number of CPU's: <CPUs>, RAM size: <RAM>, Disk size: <DISK>] [Price: $<PRICE>] For example, "Ubuntu1 [Number of CPU's: 16, RAM size: 8, Disk size: 200] [Price: $2000.0]" |
Do not add any public methods or fields to the Machine class.
The User class should use your DLinkedList class to build a machinelist of machines ordered by price from highest to lowest. A shell of this class is also provided for you (see User.java), you must implement all the methods.
User has the following methods and constructor:
Constructor | Description |
---|---|
User(String name, String password, int credit) | Constructs a User instance with a name, password, credit and an empty machinelist. |
Method | Description |
boolean checkLogin(String username, String passwd) | Checks if the credentials provided match this user's credentials. Return true if credentials correct, false otherwise Throws IllegalArgumentException if arguments are null. |
void addToMachineList(Machine machine) | Adds the machine to the user's machinelist.
Maintains the order of the machinelist from highest priced to lowest priced machines. Throws IllegalArgumentException if arguments are null. |
Machine removeFromMachineList(String machineName) | Removes a machine from the user's machinelist.
Do not charge the user for the price of this machine.
Return the machine on success, null if no such machine found. Throws IllegalArgumentException if arguments are null. |
void printMachineList() | Print each machine in the user's machineList in its own line by using the machine's toString function. |
boolean rent(String machineName) | Rents the specified machine in the user's machinelist. Charge the user according to the price of the machine by updating the credit and removing the machine from the machinelist.
Throws an InsufficientCreditException if the price of the machine is greater than the credit available. Throw the exception with a message using this format: Insufficient credit for <username>! Available credit is $<credit>. Returns true if successfully bought, false if machine not found |
double getCredit() | Returns the credit of the user. |
ListADT<Machine> generateMachineStock() |
Declare the first N items in the currentUser's machinelist to be in stock
N is generated randomly between 0 and size of the machinelist This method has already been implemented for you returns list of machines in stock |
Do not add any public methods or fields to the User class.
Below are the specifications for this class:
The application program, Cloud contains a list of machines, a list of users and keeps track of the current user logged in. A shell of this class is also provided for you (see Cloud.java). The static methods are outlined below which you need to implement in order for the Cloud to work correctly.
User login(String username, String passwd) | Tries to login for the given credentials. Updates the currentUser if login successful.
Returns the currentUser |
void loadMachines(String fileName) | Reads the specified file to create and load machines into the cloud.
Every line in the file has the format: <MACHINE NAME>#<NUMBER OF CPU's>#<MEMORY SIZE>#<DISK SIZE>#<PRICE> Create new machines based on the attributes specified in each line and insert them into the machines list Order of machines list should be the same as the machines in the file For any problem in reading the file print: 'Error: Cannot access file' |
void loadUser(String fileName) | Reads the specified file to create and load a user into the cloud.
The first line in the file has the format:<NAME>#<PASSWORD>#<CREDIT> Every other line after that is the same format as the machines file: <MACHINE NAME>#<NUMBER OF CPU's>#<MEMORY SIZE>#<DISK SIZE>#<PRICE> For any problem in reading the file print: 'Error: Cannot access file' |
void printMachines() | The order of the machines should be the same as in input machines file. The output format should be the consolidated String format mentioned in Machine class. |
Loading the Data:
The Cloud application commands are:
Command format | Description |
---|---|
v:all | Print all machines in the cloud. See printMachines() method of cloud. |
v:machinelist | For the current user print all machines in their machinelist. The order is the same as the machinelist. |
v:instock | Print all machines in the inStock list. |
s:string | Search for the String string in all of the machine names in the cloud and print out all the matching machines.
Print format for each machine is the same as specified in the toString method of Machine For no matching machines, print nothing. |
a:machineName | Add the Machine whose name is specified by machineName to the user's machinelist. Print "Machine not found" if no such machine. |
r:machineName | Remove the Machine whose name is specified by machineName from the user's machinelist. Print "Machine not found" if no such machine. |
b | Rent the Machines shown to be in stock by the list inStock. This removes them from the user's machinelist and charges the user for it. While doing the rent operation, check whether the machine in inStock is actually there in the user's machine list. If the user has insufficient credit, print out: "For renting <MACHINE-NAME>: Insufficient credit for <PRODUCT-NAME>! Available credit is $<credit>" and proceed with processing the user input for the commands again. If rent operation was not successful because of machine not being on machinelist, then print "Machine not needed: <MACHINE-NAME>" If rent operation was successful, then print "Rented <MACHINE-NAME>" |
c | Shows the credit of the current user as $<CREDIT>. | l | Logs out the current user and goes back to the login screen. |
Items in stock:
Implement each command listed above. Your code uses your DLinkedList, User , Machine, and InsufficientCreditException classes, where appropriate. In addition to the command descriptions listed above, if the program user inputs an invalid command display the error message "Invalid Command" and allow them to enter a new command.
After you have read this program page and given thought to the problem we suggest the following steps: