This is the group project for CS 180(Project 4 and 5). Lab 001 - Team 2
This GitHub repository contains code for a marketplace messaging app. It has features include:
- Allow communication between buyers and sellers with an account
- Sellers can create stores
- Ability to create, edit, and delete messages
- Buyers can view a list of stores and select one to message, or they can choose to search for a seller's username to message directly
- Sellers can view a list of buyers and select one to message, or they can choose to search for a buyer's username
- Users can also send text files as messages and download their conversations as a csv file
- Buyers can view a dashboard of stores by number of messages they received or number of message they send
- Sellers can view a dashboard of their own stores and number of messages they have send and most common words in them for each stores
- Users can also block another user or become invisible to them
- Conversations with new messages will be marked and automatically put to the top
New features update from Project 5: - A server-client model implementation
- A server that's event-driven and capable of handling multiple clients
- A client that sends the requests to the server according to client needs(also event-driven)
- GUI class that renders the screen(Also event-driven)
- REAL TIME UPDATE (Woo Hoo!!!)
If you are using an IDE like Intellij, you can simply download the project, configure the Java JDK(recommend the newest Java JDK), add a run configuration for server (ServerCore.java) and client (Init.java) (PS: make sure to make the client configuration allows for multiple instances if you want to test real-time update in one machine), and, finally put it in your ide and run the Main class for console integration and run both the server and client config for server-client model and a GUI(It's BEAUTIFUL!)
server core is the main server code that handles IO between the server and the client. It uses Java.nio.channels package that provides a ServerSocketChannel and SocketChannel(for ServerSocket and Socket from java.net) and a multiplexer called Selector that allow for event-driven code for the channels. The channels have been configured into non-blocking mode(the server does not wait until a IO operation is complete, it moves on) that minimizes response time from the server
- MessageSystem as field
- DataPacket: uses its method
- import Java.nio package
- ArrayBlockingQueue for thread-safe queue and de-queue (write operation)
Basically an abstraction of the Message system (the core packages) so it's easier for server to process
- A LOT! Like the whole UserCore and MessageCore packets, but they are separated into several classes:
- UserProfile
- PublicInfo
- MessageFunctionalities
- NotificationFactory(uses its static method to tell the server to also send this packet to another client)
Spawns a thread which allows one client to send messages to another client or broadcast to all.
The way it does this is by looping through all the keys in the selector and find the desired one, or just send it to
everyone
- ServerCore (Complement ServerCore)
- import Thread
- ProtocolRequestTypes that contains all the types of request to the server
- ProtocolResponseTypes that contains all the types of normal response from the server
- ProtocolErrorType that contains all the exceptions caused by the client, each constant corresponding to a class of exception
The packet that client uses to send request to the server. It supplies a static method of serializing itself and another static method for deserializing itself
- ProtocolRequestTypes type
- String[] of parameters
- implements Externalizable to allow for custom serialization instead of using Reflection by default; way faster serialization
The packet by the server to send normal responses to the client. It supplies a static method of serializing itself
- ProtocolResponseTypes type
- String[] of responses
- implements Externalizable to allow for custom serialization instead of using Reflection by default; way faster serialization
The packet by the server to send abnormal responses(exceptions) to the client. It supplies a static method of serializing itself
- ProtocolErrorTypes error_type that corresponds to an exception
- ProtocolResponseTypes request_type that caused the error
- String of error message
- implements Externalizable to allow for custom serialization instead of using Reflection by default; way faster serialization
Used by client to deserialize the response packet or error packet. Uses ByteArrayInputStream and ObjectInputStream to deserialize the bytes and store the remaking bytes into a byte[] for the next deserialization
server core is the main client code that handles IO between the server and the client. Also uses all the Java.nio fun
stuff.
It also supplies method that allows listeners to read from read queue and allows client to add to the write queue
anytime
- PacketDeserializer as field
- import Java.nio package
- ArrayBlockingQueue for thread-safe queue and de-queue (both read and write)
Supply a static method to assemble the Request Packet and serialize it, so it's ready for the client to send to the server. (There's also a method that convert a array string to an array...I put it there because I am too lazy to create another class for it :> )
A basic Listener that listens for a specific response or an error caused by a specific request
- Protocol Package
- import Thread
- ClientCore as field
- ProtocolResponseType response
- ProtocolRequestType errorRequest
- ClientCore client
Basically renders the GUI for the client, send packet using PacketAssembler, and supplies methods for AsyncListener to call to rerender the screen once a response or an error is received
- Client and Protocol packet
- Javax.swing library
An Async Listener that runs in the background that listens for all packets received from client core and invoke the corresponding methods in the EDT to rerender the screen with new information
- extends Javax.swing.SwingWorker<T,V>
- Protocol Packet to access the infos
User and its children Buyer and Seller are served as a stand in class for classes other than UserCore to use. They only contain attributes the makes up a user - the username, password, email, and role - which constitute a unique identifier for other classes to use them, and status indicator login status and waiting for deletion status. User classes does not have any utility methods; it only has protected simple getters and setters for classes in UserCore and public static getters for username, roles, login status which are public information that can be shared. User also has a equal method and toString method to help aid other classes to identify the user. User and its children has protected constructors to prevent unauthorized instantiation.
Buyer and Seller inherit the User class, they are there to simplify user creation as they don't need to take Role as one of its parameter during creation and limit the fields that use them to only contain buyer/seller instances.
A class that represent store and contains attributes of a store include owner, store names, and number of message received by each customer
- testCreateStore
- testTakenStoreName
The message class represents the individual messages each user send in a conversation.
- Uses User class as field
- sender
- receiver
- content of the message
The message manipulation functionalities starts here and gets encapsulated by each class that depends on Message
- Message Creation, editing, and deletion
- Deletion will only delete the message for the user requesting the deletion
- If both sender and the participant delete the message, the deletion method will notify the caller that this instance can be destroyed to conserve memory.
- CSV export and string export
- Notify the target that this a new message
- Limit the access to all the functionalities to only the sender and the buyer
- This effort is also repeated in higher classes like conversation which again limit the access to the 2 participants and again in FullUser by not allowing messages to pass around to other user to use
- testEditMessage
- testDeleteMessage
- testMessagesAccess
The Conversation class represents a collection of messages between a seller and a buyer
- Uses Buyer class as a field
- Uses Seller class as a field
- Uses ArrayList of Messages as field
- buyer
- seller
- collection of messages
- a flag to indicate whether there's a new message for seller
- a flag to indicate whether there's a new message for buyer
The conversation encapsulate all messages functionalities plus additional include:
- a method that automatically puts a message when a participant deleted his/her account
- ability to notify the classes implement it there is a new message for seller/buyer
- automatically puts new messages to the top
- Limit the conversation to only be between a buyer and a seller
- testEditMessage
- testDeleteMessage
- testMessagesAccess
- testNewMessagesInConversation
- testMessageBuyerToSeller
- testMessageBuyerToBuyer
- testMessageSellerToSeller
FullUser and its children combine User classes attributes and message functionalities and provide an interface for user to interact.
Full User class represent common attributes and functionalities that each Buyer and Seller share like:
- Attributes in User - username, password, email, login status, waiting for deletion status
- message creation, edition, deletion
- Provide a way for user to interact with their profile
- Uses User class as field
- Uses Conversation class as field
- Uses Public Information class methods
- User
- list of conversations
- list of blocked user
- list of make invisible user
- list of filtered word
- censoring character
- flag for censoring mode
The Full User implement all conversation functionalities plus additional include:
- converting files to string for message manipulations
- provide a way to notify and link 2 users in the conversation
- Print a list of conversation by the titled by the other parties' name for user to select
- Display the conversation based on user selection
- Provide a password check method to verify user's identity
- Print the profile information
- Uses export to csv methods in conversation to output csv to a file designated by the user
- TestCasesMain
- testFilterMessages
- testInvisible
- testLoginSuccess
- testWrongUsername
- testBlocking
- testWrongPassword
- testLogout
FullBuyer class represents attributes and functionalities associated with the buyer
- Uses Full User as parent
- Uses Public Information Methods
- list of store messaged and the frequency list
- create a buyer
- message store
- message seller
- view buyer dashboard
- TestCasesMain
- testBuyerDashBoard
FullSeller class represents attributes and functionalities associated with the seller
- Uses Full User as parent
- Uses Public Information Methods
- a static list of stop words in English to filter out stop words for common word method
- create a seller
- create a store
- message buyer
- view seller dashboard
- TestCasesMain
- testSellerDashBoard
- testMostFrequentWord
- testCreateStore
Public information contains a collection of static utility methods for accessing and exchanging public information include all the sellers, buyers, stores, and used usernames
- Uses Full Seller as field
- Uses Full Buyer as field
- Uses Store as field
- a static list of all the Full Buyers
- a static list of all the Full Sellers
- a static list of all the usernames in
- a static list of stores
- Data persistence by serializing all static lists
- Translate a user instance to FullUser
- provide a global login and logout method
- Find the owner of a store
- Sort all stores by the messages they received
- Method to check for duplication during account creation and edition
- Search for seller and buyer by usernames
- Find the seller, buyer, and store by putting in the exact name for them
- Delete user and recover user
- And various unsafe debugging methods
- TestCasesMain
- testAccountDeletion
- testAccountRecovery
- testDataPersistence
- Arthur Ruano - submitting report
- Arthur Ruano - submiting code
- Teresa Wan - Submitting video