Program Specifications This is to implement an application to be used by Custome
ID: 3907452 • Letter: P
Question
Program Specifications
This is to implement an application to be used by Customer Service representatives at a Wireless Phone Carrier to keep track of customers’ SmartPhone message usages/charges and to provide account disconnect service.
Messages can be sent from one SmartPhone account to another SmartPhone account. They can be one of the following types: Text message, Voice message, or Media message. Each message will be charged at different rates. Note: for simplicity we only care about outgoing messages.
The assignment assignment basically illustrates the following concepts:
· Generic programming
· Wildcards with <?> and <? extends T>
· Java Collections Framework
· Exception handling (try/catch blocks)
Upon start up your program should show the below menu:
FOOTHILL WIRELESS at Santa Clara
MESSAGE UTILIZATION AND ACCOUNT ADMIN
1. List all accounts
2. Erase the first media message
3. Disconnect an account
4. Quit
Data structures Specs
Since searching an account will be done frequently the ideal data structure for this application will be a TreeMap of SmartPhone accounts with phone numbers as the keys and the ArrayList of Message<something> (Message<Text> or Message<Voice> or Message<Media>) as their values. Note that the Message<something> are sub classes of Item so the ArrayList in essence is ArrayList<Item>
Class Design
· class SmartCarrier
o Private instance fields: a TreeMap with key=String and value=ArrayList of Item referenes (which are references to Message <something>) and location (county such as Santa Clara)
o Constructors (default and non-default): must instantiate an empty TreeMap object
o Public instance methods:
§ init: Read a text file to build the TreeMap's entries. Each line in the text file is a Message. For example if the message is a Text message (indicated by message type "T") instantiate a Text message object. Then instantiate a Message<Text> object before assigning it to an Item reference variable. In order to insert the Item (which is a reference to the Message<Text>) to the TreeMap you must:
§ Check if the TreeMap already contains the key. If so get the value of that key (which is an ArrayList) then add Item (Message<Text>) to the ArrayList.
§ If the TreeMap does not contain the key (new map entry) then instantiate an empty ArrayList object. Add the Message<Text> to the ArrayList. Finally invoke "put" from TreeMap to add the new entry.
§ The process can be repeated for other types of Message (Voice and Media).
§ run
§ Use a do while loop that shows the menu and a switch statement that invokes one of the below methods (the ones in bold-face below must be implemented as private instance methods in SmartCarrier class) based on user choice:
o List all accounts (option 1): iterate thru all accounts in the TreeMap using entrySet to get each entry (key and ArrayList). For ArrayList use ListIterator to iterate thru all messages to display their information (via toString).
o Erase the first media message from an account (option 2): iterate thru the entire TreeMap to get the ArrayList<Item> value for each entry. Pass this ArrayList value to the eraseHelper method as specified below:
o the method will take a List<? extends Item> parameter
o the method will use the new for loop syntax to iterate thru the entire List<? extends Item> to exam each element: If the element is an instance of Message<?> then type cast it to Message<?> type. Get the object inside the Message<?> and verify if it's a Media object. If so remove it and break out of the for loop. That's all.
o Disconnect account (option 4): ask user to input an account (phone number). Verify if the account exists. If not throw an exception (do not terminate the program. The caller of this method (run) will handle it by displaying an error "Account 123-456-7890 does not exist!") or you may have a try/catch block in this method to handle the exception itself. Otherwise show the total charge, and then delete the account from the map.
NOTE: In case you want the run method to handle "Account not found" exception it should have a try/catch block for the switch statement to handle the potential exceptions thrown by eraseMediaMessage, and disconnectAccount.
· class Item
o Private instance fields
§ time (int): time the item is created – number of seconds after 1/1/1970
§ from (String): an account phone number
§ to (String): an account phone number
§ charge (double): charge to this Item
o Constructors
o Accessors/mutators
o Public instance methods:
§ toString: to return a String of all instance fields
· class Message: a generic class that derives from the non-generic class Item
o Private data: a T object (Note: T can be Text or Voice or Media object)
o Constructors: The default constructor should set T to null. The non-default constructor will take a T object. It also requires additional parameters that are needed by the super class Item's non-default constructor. You must explicitly invoke super class constructors as necessary.
o Accessor/mutators: getMessage and setMessage for T object
o toString: build the combined String from Item (super class) and T object and return it
· class Text, class Media, class Voice: (minimal code will be given at the end of the assignment - You're free to modify them as needed such as providing getters/setters methods)
Basically the classes are described as below:
o Private instance fields:
o class Text: a String (content)
o class Media: a double (size) such as 2.2MB or 0.256M and a String (format) such as JPEG, PNG, GIF, JPG.
o class Voice: an integer (duration in seconds) such as 35s, 151s, 200s and a String (format) such as MP4, MPE, MOV, VOB, WMV
Implementation Requirements
· Use TreeMap and ArrayList to store accounts and their messages
· Use entrySet and ListIterator and to iterate TreeMap and ArrayList respectively
· No message type instance field is allowed in the generic Message class. To determine a particular Message<T> you will need to use instanceof
Main Program
· Instantiate a SmartCarrier object
· Invoke init
· Invoke run
Assignment submission and late policy: similar to previous assignments. Note that you must submit your program by the due date 11:59pm on Monday, June 25 complete or incomplete. Late submission will not be accepted as I need to do grading by end of the week before Summer starts. Sorry.
Testing
· Option 1: May need to run several times when the other options are selected
· Option 2:
o Erase a non-existing media message from some account: Some of the account's message list should contain no media message
o Erase a message at beginning and at the end of the list: this should be broken into three test cases:
§ Erase a media message that appears at the beginning of the list (the message list should have 2 or more media messages in which the first media message is the first message in the list)
§ Erase a media message that appears in the middle of the list (the message list should have 2 or more media messages in which the first media message must be in the middle of the list)
§ Erase a media message that appears at the end of the list (the message list should have only one media message whose position is the last message in the list)
· Option 3: Disconnect accounts at the beginning, at the end, and in the middle
Text/Voice/Media classes (minimal code)
class Text {
private String content;
public Text () { content = ""; }
public Text (String text) { content = text; }
public String toString () {
return " TEXT: " + content;
}
}
class Media {
private double size ;
private String format;
public Media () {
size = 0;
format = "";
}
public Media (double size, String format) {
this.size = size;
this.format = format;
}
public String toString () {
return new String (" MEDIA: Size:" + size + " MB, Format: " + format);
}
}
class Voice {
private int duration;
private String format;
public Voice () {
duration = 0;
format = "";
}
public Voice (int duration, String format) {
this.duration = duration;
this.format = format;
}
public String toString () {
return new String (" VOICE: Duration:" + duration + " (sec), Format: " + format);
}
}
Sample Text file
Format:
message type,time,from,to,<message-specific data)
// -----------------------------------------------------------------
Possible message type values:
T: Text message
M: Media message
V: Voice message
// -----------------------------------------------------------------
T,144840960,1-408-111-0222,1-650-111-0000,Are you going to the movie tonight?,0.50
V,144840960,1-408-111-0222,1-650-222-5555,120,MPE,3.25
T,144840960,1-408-222-0222,1-650-333-6666,Happy birhday!!!,1.25
T,144840960,1-408-666-0333,1-650-555-4444,I'm tired today.,0.45
T,144840960,1-408-111-0222,1-650-666-9999,Mom said you go home by 11pm,0.20
M,144840960,1-408-333-0222,1-650-123-2000,2.5,JPEG,1.25
M,144840960,1-408-444-0222,1-650-567-2003,3.8,JPG,.90
T,144840960,1-408-555-0222,1-650-321-3131,Can you close the backdoor?,0.25
T,144840960,1-408-333-0222,1-650-213-4444,Java is fun to learn right,0.25
V,144840960,1-408-222-0222,1-650-812-0011,670,MOV,5.75
V,144840960,1-408-111-0222,1-650-852-4774,231,MP4,0.25
T,144840960,1-408-555-0222,1-650-991-7801,I got to go now Sorry,0.55
M,144840960,1-408-555-0222,1-650-287-2203,3.05,PNG,3.20
T,144840960,1-408-555-0222,1-650-991-7801,Will come to your house this afternoon,0.55
T,144840960,1-408-555-0222,1-650-991-7801,Yeah.,0.55
M,144840960,1-408-111-0222,1-650-217-2003,2.75,GIF,1.20
V,144840960,1-408-555-0222,1-650-000-2828,172,MOV,2.45
M,144840960,1-408-111-0222,1-650-333-8888,1.75,GIF,3.80
M,144840960,1-408-333-0222,1-650-444-6666,5.5,GIF,4.25
M,144840960,1-408-666-0333,1-650-123-2000,3.5,GIF,5.25
Sample program run
FOOTHILL WIRELESS at Santa Clara
MESSAGE UTILIZATION AND ACCOUNT ADMIN
1. List all accounts
2. Erase a media message
3. Disconnect account
4. Quit
Enter a choice (1-4): 1
Explanation / Answer
if you want to send SMS messages from your C++ application, first you need to connect your software and an SMS gateway to each other. Why? Because your application let you compose the SMS messages (including the text, the recipient’s phone number, etc.), but if you want to send out the SMS, you need to connect to the SMSC (Short Message Service Center that stores, forwards, converts and delivers SMS messages). An SMS gateway is able to connect to the SMSC of the Mobile Service Provider via SMPP IP SMS connection or a GSM modem, so actually the SMS gateway can send out your message. To establish connection between the SMS gateway and the C++ application, I used HTTP requests and responses. For sending SMS messages through HTTP, your SMS gateway should have a built-in webserver .
#include<iostream>
#include<sstream>
#include<windows.h>
#include<wininet.h>
using namespace std;
string encode(string url);
int main(int argc, char** argv)
{
// the SMS gateway's host
// and port
string host = "localhost";
int port = 9502;
// username
// and password
string username = "admin";
string password = "abc123";
// message
string message = "This is a test SMS.";
// originator's phone number
string originator = "+44555555555";
// recipient's phone number.
// to send the SMS to multiple recipients, separate them by using commas without spaces
string recipient = "+44333333333";
// preparing the HTTPRequest URL
stringstream url;
url << "/api?action=sendmessage&username=" << encode(username);
url << "&password=" << encode(password);
url << "&recipient=" << encode(recipient);
url << "&messagetype=SMS:TEXT&messagedata=" << encode(message);
url << "&originator=" << encode(originator);
url << "&responseformat=xml";
// create socket
HINTERNET inet = InternetOpen("Ozeki", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
// open connection and bind it to the socket
HINTERNET conn = InternetConnect(inet, host.c_str() , port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
// open the HTTP request
HINTERNET sess = HttpOpenRequest(conn, "GET", url.str().c_str(), "HTTP/1.1", NULL, NULL, INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD, 0);
// check errors
int error = GetLastError();
if(error == NO_ERROR)
{
// send HTTP request
HttpSendRequest(sess, NULL, 0, NULL,0);
// receive HTTP response
int size = 1024;
char *buffer = new char[size + 1];
DWORD read;
int rsize = InternetReadFile(sess, (void *)buffer, size, &read);
string s = buffer;
s = s.substr(0, read);
// check status code
int pos = s.find("<statuscode>0</statuscode>");
// if statuscode is 0, write "Message sent." to output
// else write "Error."
if(pos > 0) cout << "Message sent." << endl;
else cout << "Error." << endl;
}
system("pause");
}
// encoding converts characters that are not allowed in a URL into character-entity equivalent
string encode(string url)
{
char *hex = "0123456789abcdef";
stringstream s;
for(unsigned int i = 0; i < url.length(); i++)
{
byte c = (char)url.c_str()[i];
if( ('a' <= c && c <= 'z')
|| ('A' <= c && c <= 'Z')
|| ('0' <= c && c <= '9') ){
s << c;
} else {
if(c == ' ') s << "%20";
else
s << '%' << (hex[c >> 4]) << (hex[c & 15]);
}
}
return s.str();
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.