You are on page 1of 41

SWE2005-SOFTWARE TESTING

Project Title:-
Multiple Client-Server Chatting and
Sharing System

Members:-
16MIS0187-K.Gopi Krishna
16MIS0320-G.Nagendra babu
16MIS0364-N.Pavan Kalyan

Faculty:-Uma.K Slot:-B1+TB1
Table of Contents
1 Introduction..............................................................................................3
1.1 Problem definition ...............................................................................3
1.2 Project description ...............................................................................3
1.3 Statement of scope ...............................................................................4
2 Technical background ............................................................................. 5
2.1 Instant messengers ...............................................................................5
2.2 Java ..................................................................................................... 5
3 System architecture ................................................................................. 6
3.1 Overview............................................................................................. 6
3.2 The client ............................................................................................ 6
3.3 The server ........................................................................................... 8
3.4 The administrator .................................................................................8
3.5 The database ....................................................................................... 9
4 Design and implementation details....................................................... 10
4.1 SSL Sockets ...................................................................................... 10
4.2 GUI Design ....................................................................................... 11
4.3 Implemented features........................................................................ 11
4.4 The Protocol...................................................................................... 12
5 Conclusion ............................................................................................ 14
6 Future work ........................................................................................... 14
7 References ............................................................................................. 15
1 Introduction

1.1 Problem definition


Chat server is a network based application which having two faces: one
for the server side and one for the client. Our chat server has been
developed with optimized technique to make fast and of less size. Even
though, it’s a small application, but eligible to meet client side
requirements. It’s having two page source code, one for the server and
can be placed on any system which you want to make a server. For
working as client side, you have to place the client code to other
computer, which will act as client side. At the same time, there can be
more than one client which can be handle by the TCP connection.

In order to handle with networking concepts, we have used


number of java built in features to have optimized codes like threading,
networking console, Input and Output console, collections, streams and
much more. Among all, it’s the application which can be run, using the
concept of LAN and all clients need to be connected to server or use their
dedicated IP address to receive and send messages through broadcasting
central server.

1.2 Project description


It’s the system which only not allow users to send messages from one clients
to all clients but even facilitate to send private message and group chats with
other clients. It’s the system, which provide clients the details of other clients
with information like: name, logged in time, total duration and their message
in public section. The server side will responsible to maintain users list, their
messages, passwords and log details. It’s the application where the concept of
data structure like linked list, array list has been used
The project is split into two parts:
1.Server Application: -
It will act as a broadcasting server which will handle the sending and receiving
of messages. It’s the part which have to deal with TCP/IP, port number and SSL
techniques. Its predefined logic handles where to send messages, from where it
has been received and what data has to carry.
2.Client Application: -
Using the client panel, client can login to their account using their username and
password. It’s the panel where message exchange process will take place and
their representation medium among other clients.
1.3 Statement of scope
● The client must be able to connect to other clients as well as connecting
to the server. All traffic must be encrypted. The clients must be able to
transfer text and files.
● The server must be able to receive incoming connections from clients.
The protocol must support forwarding of messages from client to client.
The server must broadcast who is online and when a user disconnects to
all clients.
● When a user registers the information must be saved in the database.
Important information such a username and password must be pulled out
and verified before a client connection can be successfully established.
The database must also save IP addresses that are banned.
● The administrative application is merely an application for setting up the
database from a remote location, as well as monitoring the server, who
is online/offline, and banning IP addresses from the server.
2 Technical background

2.1 Instant messengers


Instant messengers are applications that support chat, file transfers as well as
other features. Most instant messengers are client/server based. The clients
can connect to the server. Both clients must connect to the server for
communication to be established. Some popular Instant messengers are MSN
Messenger, AIM, Yahoo messenger etc.

2.2 Java
This project is written entirely in J2SE 1.5 (Source 1) and takes advantage of
the following packages:
● javax.swing.* - GUI.

● java.awt.* - Events, Layout managers, etc.


● java.util.* - ArrayList, ToolBox etc.
● java.net.* - Standard sockets.
● javax.net.ssl.* - SSL sockets.
● java.sql.* - SQL queries etc.

In addition to these packages an external API must be loaded into the


jre/lib/ext directory for the server to function correctly, the MySQL (Source
2) driver. This provides the following package:
● org.gjt.mm.mysql.* - Connection to MySQL database.
3 System architecture

3.1 Overview
The complete overview over the system can be seen in figure 1. The clients
can connect to each other, as well as connect to the server and communicate
through this. The server runs as a standalone applications but can be controlled
by the administrator. User information and information about banned IP
addresses is stored in the database.

Figure 1: Overview over client, server, administrator and


database.

3.2 The client


The client consists of many components. We can group them into GUI,
controller and managers. (Figure 2)
GUI

Controller

Managers

Figure 2: Client components overview


The controller basically acts as a link between the GUI and the managers. The
Managers are split into different types:
 Outgoing managers – These managers take care of all outgoing traffic.

 Incoming managers – These managers take care of all incoming


traffic. Thread listens for new incoming sockets.
This again is split into different types:
 File manager – Handles file traffic. (Outgoing/Incoming)
 Text manager – Handles text traffic. (Outgoing/Incoming)
 Server Manager – Handles server communication. (Outgoing)

Figure 3 shows the 3 different types of traffic handled by the managers. Figure
4 shows the internal structure of the managers. The protocol is implemented
at the level of the sender/receiver and the reader/writer.

Figure 3: Client
traffic.
Figure 4: Manager handling (left) file transfers
and (right) text traffic.
The server
The server does not have any GUI components, thus simple in many ways. At
the top there is a controller. The controller handles the database, the
adminlistener and the clientlistener, and all interaction between those classes.
The server listens for incoming clients (multiple) and incoming administrator
(only one), but does not initiate any outgoing traffic. (Figure 5)

Figure 5: The
server

3.3 The administrator


The administrator has GUI components at the top. The controller is in the
middle working between the actual socket and the GUI. The application does
not listen for incoming traffic (sockets), it only initiates. The socket connects
s to the adminlistener socket of the server.

Figure 6: The administrator application


4 Design and implementation details

4.1 SSL Sockets


For the network part of my application I have consequently used SSL
Sockets. In Java this is easy. Typically the usage spans over the following
areas1:
1. Listening for incoming connection. (Example 1)

2. Creating new outgoing connection. (Example 2)

3. Constantly reading from a connection by using a thread.

import java.net.*;
import javax.net.ssl.*;

SSLServerSocket ss = null;
ss = (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket
(CLIENTLISTEN_PORT);
ss.setNeedClientAuth(false);
String cipherSuite [] = {"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"};
ss.setEnabledCipherSuites(cipherSuite);
Socket tmp_socket = ss.accept();

Example 1: Listening for incoming SSL connections.

import javax.net.ssl.*;

SSLSocket socket = (SSLSocket)SSLSocketFactory.getDefault().createSocket(host,port);


socket.setNeedClientAuth(false);
String cipherSuite [] = { "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA" };
socket.setEnabledCipherSuites(cipherSuite);

Example 2: Creating new outgoing connection.


4.2 GUI Design
Most of the GUI has been created using the following API and as a
combination between them (Source 3):
 javax.swing

o BoxLayout
o JFrame
o JPanel

 java.awt
o BorderLayout
o FlowLayout
o GridBagLayout
o GridLayout

Other than that general graphical editing software have been used for creating
icons and images etc.

4.3 Implemented features


The client:
 Text transfer (chat)
 File transfers
 Sockets over SSL
 Application firewall
The server:
 Administrator network interface
 Client network interface
 Database connectivity
 Console application
 Event system
The administrator:
 Connect to server
 After connecting set up the server with a database and maximum
number of allowed users.
 Supported features (GUI) but not implemented (protocol):

o Monitoring, being able to see which users are online and which
are offline, also monitoring events.
o Banning IP addresses and seeing which IP addresses are banned.

4.4 The Protocol


Client/Client protocol:
 Text transactions
o DISCONN – External chat closed.
o INIT – Initiate chat with other end.
o TXT <txt> - Sending text.
o PING – Keeping connection alive.

 File transactions
o <Filename> - Name of file.
o <Filesize> - Filesize in bytes.
o TACC – Accept filetransfer.
o TDEN – Deny filetransfer.
o 1<100010010101…> - As file is sent (raw bytes) each block
transaction must be started with 1 to indicate healthy
connection.
TESTING PROCESS
Testing is the process of checking the functionality of an application to
ensure it runs as per requirements. Unit testing comes into picture at the
developers’ level; it is the testing of single entity (class or method). Unit testing
plays a critical role in helping a software company deliver quality products to its
customers.
Unit testing is a software development process in which the smallest testable
parts of an application, called units, are individually and independently
scrutinized for proper operation. Unit testing is often automated but it can also
be done manually.
Unit testing is commonly automated, but may still be performed manually.
The IEEE does not favor one over the other. The objective in unit testing is to
isolate a unit and validate its correctness. A manual approach to unit testing may
employ a step-by-step instructional document. However, automation is efficient
for achieving this, and enables the many benefits listed in this article.
Conversely, if not planned carefully, a careless manual unit test case may
execute as an integration test case that involves many software components, and
thus preclude the achievement of most if not all of the goals established for unit
testing.
Advantages
The goal of unit testing is to isolate each part of the program and show
that the individual parts are correct. A unit test provides a strict, written contract
that the piece of code must satisfy. As a result, it affords several benefits.
 Find problems early
Unit testing finds problems early in the development cycle. This includes
both bugs in the programmer's implementation and flaws or missing parts of the
specification for the unit. The process of writing a thorough set of tests forces
the author to think through inputs, outputs, and error conditions, and thus more
crisply define the unit's desired behavior. The cost of finding a bug before
coding begins or when the code is first written is considerably lower than the
cost of detecting, identifying, and correcting the bug later; bugs may also cause
problems for the endusers of the software. Code can be impossible or difficult to
test if poorly written, thus unit testing can force developers to structure functions
and objects in better ways.
In test-driven development (TDD), which is frequently used in both extreme
programming and scrum, unit tests are created before the code itself is written.
When the tests pass, that code is considered complete. The same unit tests are
run against that function frequently as the larger code base is developed either as
the code is changed or via an automated process with the build. If the unit tests
fail, it is considered to be a bug either in the changed code or the tests
themselves. The unit tests then allow the location of the fault or failure to be
easily traced. Since the unit tests alert the development team of the problem
before handing the code off to testers or clients, it is still early in the
development process.
 Facilitates change
Unit testing allows the programmer to refactor code or upgrade system
libraries at a later date, and make sure the module still works correctly like in
regression testing. The procedure is to write test cases for all functions and
methods so that whenever a change causes a fault, it can be quickly identified.
Unit tests detect changes which may break a design contract.
 Simplifies integration
Unit testing may reduce uncertainty in the units themselves and can be used
in a bottom-up testing style approach. By testing the parts of a program first and
then testing the sum of its parts, integration testing becomes much easier.
Design
When software is developed using a test-driven approach, the combination of
writing the unit test to specify the interface plus the refactoring activities
performed after the test is passing, may take the place of formal design. Each
unit test can be seen as a design element specifying classes, methods, and
observable behavior.
Unit testing can be done in two ways − manual testing and automated
testing.
Manual Testing
Executing a test cases manually without any tool support is known as manual
testing.
 Time-consuming and tedious − Since test cases are executed by human
resources, it is very slow and tedious.
 Huge investment in human resources − As test cases need to be executed
manually, more testers are required in manual testing.
 Less reliable − Manual testing is less reliable, as it has to account for
human errors.
 Non-programmable − No programming can be done to write sophisticated
tests to fetch hidden information.
Automated Testing
Taking tool support and executing the test cases by using an automation
tool is known as automation testing.
 Fast − Automation runs test cases significantly faster than human
resources.
 Less investment in human resources − Test cases are executed using
automation tools, so less number of testers are required in automation
testing.
 More reliable − Automation tests are precise and reliable.
 Programmable − Testers can program sophisticated tests to bring out
hidden information.

TEST CASE
• A Unit Test Case is a part of code, which ensures that another part of
code (method) works as expected. To achieve the desired results
quickly, a test framework is required. JUnit is a perfect unit test
framework for Java programming language.
• A formal written unit test case is characterized by a known input and an
expected output, which is worked out before the test is executed. The
known input should test a precondition and the expected output should
test a post-condition.
• There must be at least two unit test cases for each requirement − one
positive test and one negative test. If a requirement has
subrequirements, each sub-requirement must have at least two test cases
as positive and negative.

Test Cases Prepared for Sign Up, Database, Message & File Transfer
Modules
Sign Up Process:
For Sign Up, You must submit Username & Password Fields
Test Case Table for Sign Up Module:
Test Test Case Test Test Expected Actual Stat Remarks
Case ID Description Executio Inputs Result Result us
n Steps

‘Usernam
e &
Password’
TC_IN_1 Plan to give 1.Run Usernam Sign Up Same as PAS ---
username the e : Raja Successful expected S
as Progra Password result
Characters m : 1234
& Password 2.Input
as Integers value of
Userna
me &
Passwor
d in
Signup
Dialogu
e Box
TC_IN_2 Plan to give 1.Run Usernam Sign Up Same as PAS
username as the e : Successful expected S
Strings & Progra Bha146 result ---
Password m Password
as 2.Input : METOO
Character value of
Userna
me &
Passwor
d in
Signup
Dialogu
e Box
TC_IN_3 Plan to give 1.Run Usernam Error due to No FAIL
username as the e : special Output
Special Progra (@@$$) character
Characters m Password usage in Minor
& Password 2.Input : Hari987 Username
as String value of

Userna
me &
Passwor
d in
Signup
Dialogu
e Box
TC_IN_4 Plan to 1.Run Usernam Sign Up Same as PAS
give the e : 8970 Successful expected S
username Progra Password result ---
as Integers m : #!(%%)
& 2.Input
Password value of
Userna
as Special
me &
Characters
Passwor
d in
Signup
Dialogu
e Box
TC_IN_5 Plan to 1.Run Usernam Sign Up Error FAIL
give the e : Surya Successful
username Progra Password
as String m : Sai Major
& 2.Input
Password value of
Userna
as String
me &
Passwor
d in
Signup
Dialogu
e Box
TC_IN_6 Plan to 1.Run Usernam Error Message No Result FAIL Minor
give the e : Sj364 after
username Progra Password execution
as Strings m :
& 2.Input HASK*(JS
Password value of KD124GJ
Userna DHk(*&(
as
me &
Strin
Passwor
gs with
d in
Extreme
Signup
length
Dialogu
e Box
TC_IN_7 Plan to 1.Run Usernam Error Message Blank Box FAIL
give the e : JAI
username
as Strings
&
Password Progra Password Medi
as NULL m : um
2.Input
value of
Userna
me &
Passwor
d in
Signup
Dialogu
e Box
TC_IN_8 Plan to 1.Run Usernam Error Message Username PAS
give the e: cannot S
username Progra Password be ---
as NULL m : Krish12 Empty
& 2.Input
Password value of
Userna
as String
me &
Passwor
d in
Signup
Dialogu
e Box
Client/Server protocol:
 CONNECTED – Connection is established.
 REGOK – Registration is ok.
 REGREF – Registration is refused.
 LOGINOK – Login is ok.
 LOGINREF – Login is refused.
 PING – Server to the client, keeping connection alive.
 PONG – Client response to ping, only after ping.
 NOCONN – Can not connect for some reason.
 USERS <user1 user2 .. usern> - Users online.
 ADDUSER <user> - A new user is online.
 CHAT <txt> - Text transfer/chat.
 REMOVEUSER <user> - A user has logged off.
 CLOSECHAT – A user has closed the chat.

SOURCE CODE:

Socketclient.java

package com.socket;

import com.ui.ChatFrame;
import java.io.*;
import java.net.*;
import java.util.Date;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;

public class SocketClient implements Runnable{


public int port;
public String serverAddr;
public Socket socket;
public ChatFrame ui;
public ObjectInputStream In;
public ObjectOutputStream Out;

public SocketClient(ChatFrame frame) throws IOException{


ui = frame; this.serverAddr = ui.serverAddr; this.port = ui.port;
socket = new Socket(InetAddress.getByName(serverAddr), port);

Out = new ObjectOutputStream(socket.getOutputStream());


Out.flush();
In = new ObjectInputStream(socket.getInputStream());

@Override
public void run() {
boolean keepRunning = true;
while(keepRunning){
try {
Message msg = (Message) In.readObject();
System.out.println("Incoming : "+msg.toString());

if(msg.type.equals("message")){
if(msg.recipient.equals(ui.username)){
ui.jTextArea1.append("["+msg.sender +" > Me] : " + msg.content
+ "\n");
}
else{
ui.jTextArea1.append("[Me > "+ msg.recipient +"] : " +
msg.content + "\n");
}

if(!msg.content.equals(".bye") &&
!msg.sender.equals(ui.username)){
String msgTime = (new Date()).toString();

}
}
else if(msg.type.equals("login")){
if(msg.content.equals("TRUE")){
ui.jButton2.setEnabled(false); ui.jButton3.setEnabled(false);
ui.jButton4.setEnabled(true); ui.jButton5.setEnabled(true);
ui.jTextArea1.append("[SERVER > Me] : Login Successful\n");
ui.jTextField3.setEnabled(false);
ui.jPasswordField1.setEnabled(false);
}
else{
ui.jTextArea1.append("[SERVER > Me] : Login Failed\n");
}
}
else if(msg.type.equals("test")){
ui.jButton1.setEnabled(false);
ui.jButton2.setEnabled(true); ui.jButton3.setEnabled(true);
ui.jTextField3.setEnabled(true);
ui.jPasswordField1.setEnabled(true);
ui.jTextField1.setEditable(false); ui.jTextField2.setEditable(false);

}
else if(msg.type.equals("newuser")){
if(!msg.content.equals(ui.username)){
boolean exists = false;
for(int i = 0; i < ui.model.getSize(); i++){
if(ui.model.getElementAt(i).equals(msg.content)){
exists = true; break;
}
}
if(!exists){ ui.model.addElement(msg.content); }
}
}
else if(msg.type.equals("signup")){
if(msg.content.equals("TRUE")){
ui.jButton2.setEnabled(false); ui.jButton3.setEnabled(false);
ui.jButton4.setEnabled(true); ui.jButton5.setEnabled(true);
ui.jTextArea1.append("[SERVER > Me] : Singup Successful\n");
}
else{
ui.jTextArea1.append("[SERVER > Me] : Signup Failed\n");
}
}
else if(msg.type.equals("signout")){
if(msg.content.equals(ui.username)){
ui.jTextArea1.append("["+ msg.sender +" > Me] : Bye\n");
ui.jButton1.setEnabled(true); ui.jButton4.setEnabled(false);
ui.jTextField1.setEditable(true); ui.jTextField2.setEditable(true);

for(int i = 1; i < ui.model.size(); i++){


ui.model.removeElementAt(i);
}

ui.clientThread.stop();
}
else{
ui.model.removeElement(msg.content);
ui.jTextArea1.append("["+ msg.sender +" > All] : "+ msg.content
+" has signed out\n");
}
}
else if(msg.type.equals("upload_req")){

if(JOptionPane.showConfirmDialog(ui, ("Accept '"+msg.content+"'


from "+msg.sender+" ?")) == 0){

JFileChooser jf = new JFileChooser();


jf.setSelectedFile(new File(msg.content));
int returnVal = jf.showSaveDialog(ui);

String saveTo = jf.getSelectedFile().getPath();


if(saveTo != null && returnVal ==
JFileChooser.APPROVE_OPTION){
Download dwn = new Download(saveTo, ui);
Thread t = new Thread(dwn);
t.start();
//send(new Message("upload_res",
(""+InetAddress.getLocalHost().getHostAddress()), (""+dwn.port),
msg.sender));
send(new Message("upload_res", ui.username, (""+dwn.port),
msg.sender));
}
else{
send(new Message("upload_res", ui.username, "NO",
msg.sender));
}
}
else{
send(new Message("upload_res", ui.username, "NO",
msg.sender));
}
}
else if(msg.type.equals("upload_res")){
if(!msg.content.equals("NO")){
int port = Integer.parseInt(msg.content);
String addr = msg.sender;

ui.jButton5.setEnabled(false); ui.jButton6.setEnabled(false);
Upload upl = new Upload(addr, port, ui.file, ui);
Thread t = new Thread(upl);
t.start();
}
else{
ui.jTextArea1.append("[SERVER > Me] : "+msg.sender+"
rejected file request\n");
}
}
else{
ui.jTextArea1.append("[SERVER > Me] : Unknown message
type\n");
}
}
catch(Exception ex) {
keepRunning = false;
ui.jTextArea1.append("[Application > Me] : Connection Failure\n");
ui.jButton1.setEnabled(true); ui.jTextField1.setEditable(true);
ui.jTextField2.setEditable(true);
ui.jButton4.setEnabled(false); ui.jButton5.setEnabled(false);
ui.jButton5.setEnabled(false);

for(int i = 1; i < ui.model.size(); i++){


ui.model.removeElementAt(i);
}

ui.clientThread.stop();

System.out.println("Exception SocketClient run()");


ex.printStackTrace();
}
}
}

public void send(Message msg){


try {
Out.writeObject(msg);
Out.flush();
System.out.println("Outgoing : "+msg.toString());

if(msg.type.equals("message") && !msg.content.equals(".bye")){


String msgTime = (new Date()).toString();

}
}
catch (IOException ex) {
System.out.println("Exception SocketClient send()");
}
}
public void closeThread(Thread t){
t = null;
}
}

Upload.java:
package com.socket;

import com.ui.ChatFrame;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Upload implements Runnable{

public String addr;


public int port;
public Socket socket;
public FileInputStream In;
public OutputStream Out;
public File file;
public ChatFrame ui;

public Upload(String addr, int port, File filepath, ChatFrame frame){


super();
try {
file = filepath; ui = frame;
socket = new Socket(InetAddress.getByName(addr), port);
Out = socket.getOutputStream();
In = new FileInputStream(filepath);
}
catch (Exception ex) {
System.out.println("Exception [Upload : Upload(...)]");
}
}
@Override
public void run() {
try {
byte[] buffer = new byte[1024];
int count;

while((count = In.read(buffer)) >= 0){


Out.write(buffer, 0, count);
}
Out.flush();

ui.jTextArea1.append("[Message] : File upload complete\n");


ui.jButton5.setEnabled(true); ui.jButton6.setEnabled(true);
ui.jTextField5.setVisible(true);

if(In != null){ In.close(); }


if(Out != null){ Out.close(); }
if(socket != null){ socket.close(); }
}
catch (Exception ex) {
System.out.println("Exception [Upload : run()]");
ex.printStackTrace();
}
}

Message.java:
package com.socket;

import java.io.Serializable;

public class Message implements Serializable{

private static final long serialVersionUID = 1L;


public String type, sender, content, recipient;

public Message(String type, String sender, String content, String recipient){


this.type = type; this.sender = sender; this.content = content; this.recipient =
recipient;
}

@Override
public String toString(){
return "{type='"+type+"', sender='"+sender+"', content='"+content+"',
recipient='"+recipient+"'}";
}
}

Download.java:
package com.socket;

import com.ui.ChatFrame;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Download implements Runnable{

public ServerSocket server;


public Socket socket;
public int port;
public String saveTo = "";
public InputStream In;
public FileOutputStream Out;
public ChatFrame ui;

public Download(String saveTo, ChatFrame ui){


try {
server = new ServerSocket(0);
port = server.getLocalPort();
this.saveTo = saveTo;
this.ui = ui;
}
catch (IOException ex) {
System.out.println("Exception [Download : Download(...)]");
}
}

@Override
public void run() {
try {
socket = server.accept();
System.out.println("Download : "+socket.getRemoteSocketAddress());

In = socket.getInputStream();
Out = new FileOutputStream(saveTo);

byte[] buffer = new byte[1024];


int count;

while((count = In.read(buffer)) >= 0){


Out.write(buffer, 0, count);
}

Out.flush();

ui.jTextArea1.append("[Message] : Download complete\n");

if(Out != null){ Out.close(); }


if(In != null){ In.close(); }
if(socket != null){ socket.close(); }
}
catch (Exception ex) {
System.out.println("Exception [Download : run(...)]");
}
}
}

SERVER SIDE:

Message.java
package com.socket;

import java.io.Serializable;

public class Message implements Serializable{

private static final long serialVersionUID = 1L;


public String type, sender, content, recipient;

public Message(String type, String sender, String content, String recipient){


this.type = type; this.sender = sender; this.content = content; this.recipient =
recipient;
}

@Override
public String toString(){
return "{type='"+type+"', sender='"+sender+"', content='"+content+"',
recipient='"+recipient+"'}";
}
}

Database.java:

package com.socket;

import java.io.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;

public class Database {

public String filePath;

public Database(String filePath){


this.filePath = filePath;
}

public boolean userExists(String username){

try{
File fXmlFile = new File(filePath);
DocumentBuilderFactory dbFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();

NodeList nList = doc.getElementsByTagName("user");

for (int temp = 0; temp < nList.getLength(); temp++) {


Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
if(getTagValue("username", eElement).equals(username)){
return true;
}
}
}
return false;
}
catch(Exception ex){
System.out.println("Database exception : userExists()");
return false;
}
}

public boolean checkLogin(String username, String password){

if(!userExists(username)){ return false; }

try{
File fXmlFile = new File(filePath);
DocumentBuilderFactory dbFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();

NodeList nList = doc.getElementsByTagName("user");


for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
if(getTagValue("username", eElement).equals(username) &&
getTagValue("password", eElement).equals(password)){
return true;
}
}
}
System.out.println("Hippie");
return false;
}
catch(Exception ex){
System.out.println("Database exception : userExists()");
return false;
}
}

public void addUser(String username, String password){

try {
DocumentBuilderFactory docFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filePath);

Node data = doc.getFirstChild();

Element newuser = doc.createElement("user");


Element newusername = doc.createElement("username");
newusername.setTextContent(username);
Element newpassword = doc.createElement("password");
newpassword.setTextContent(password);

newuser.appendChild(newusername);
newuser.appendChild(newpassword); data.appendChild(newuser);

TransformerFactory transformerFactory =
TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(filePath));
transformer.transform(source, result);

}
catch(Exception ex){
System.out.println("Exceptionmodify xml");
}
}

public static String getTagValue(String sTag, Element eElement) {


NodeList nlList =
eElement.getElementsByTagName(sTag).item(0).getChildNodes();
Node nValue = (Node) nlList.item(0);
return nValue.getNodeValue();
}
}

SCREENSHOTS:

Messenger Home
Server home:
Connected to a database:

Screen Home:
5 Conclusion:
I have created a client, a server, an administrator and set up a database. The
applications are done, except for the administrator, which needs more work. The
standard functionality of the server is in place; users can register, log in, chat
with other users, IP addresses can be banned through the database. To sum it up:
 Client – Done

 Server – Done
 Administrator – Needs more work
 Database – Done

6 Future work:
I will continue to work on this project. The most obvious future work will be:
 Finishing the administrator.
 Polish the GUI of the applications.
 Fix bugs and errors.

Once this is ok I can start looking at multiserver support:


 Several servers can connect to the same database.
 Adds support for more users.
 Needs stronger protocol, interserver communication etc.

7 References
Source 1: “Java Technology”, http://java.sun.com/
Source 2: “MySQL. The world’s most popular open source
database”, http://www.mysql.com/

You might also like