Embed
Email

Jabber Client

Document Sample

Shared by: jianghongl
Categories
Tags
Stats
views:
0
posted:
1/7/2012
language:
pages:
74
Distributed Systems

CSC8530









Jabber Client

Submitted on Dec 2, 2003

Jeevan Varma Anga

(Jeevanvarma.anga@villanova.edu)









Distributed Systems (CSC8530)

Department of Computing Sciences

Villanova University.

Vision:

The Jabber Instant Messaging Client has two goals. The first and most essential,

is to provide an Instant Messaging Service Client. The second is to allow transparent

messaging to third party services (YAHOO, ICQ, MSN, AIM. etc.)



What is Jabber?

Jabber is a set of streaming XML protocols and technologies that enable any two

entities on the Internet to exchange messages, presence, and other structured information

in close to real time. The first Jabber application is an instant messaging (IM) network

that offers functionality similar to legacy IM services such as AIM, ICQ, MSN, and

Yahoo. However, Jabber is more than just IM, and Jabber technologies offer several key

advantages:

 Open -- the Jabber protocols are free, open, public, and easily understandable; in

addition, multiple implementations exist for clients, servers, components, and

code libraries.

 Standard -- the Internet Engineering Task Force (IETF) has formalized the core

XML streaming protocols as an approved instant messaging and presence

technology under the name of XMPP.

 Decentralized -- the architecture of the Jabber network is similar to email; as a

result, anyone can run their own Jabber server, enabling individuals and

organizations to take control of their IM experience.

 Secure -- any Jabber server may be isolated from the public Jabber network (e.g.,

on a company intranet), and robust security using SASL and TLS has been built

into the core XMPP specifications.

 Extensible -- using the power of XML namespaces, anyone can build custom

functionality on top of the core protocols; to maintain interoperability, common

extensions are managed by the Jabber Software Foundation.

 Flexible -- Jabber applications beyond IM include network management, content

syndication, collaboration tools, file sharing, gaming, and remote systems

monitoring.

 Diverse -- a wide range of companies and open-source projects use the Jabber

protocols to build and deploy real-time applications and services.



Why Jabber?:

Millions of users have found IM (instant messaging) to be an easy and convenient

way to communicate with co-workers, friends, and family with more immediacy than e-

mail and without the expense of long-distance phone calls. Business executives are also

starting to reap the benefits of IM solutions through their on-demand capability of

engaging in problem-solving conversations and business dealings.



The problem with IM services arises when users, employees, partners, and

customers use different IM clients. To chat with users of other IM solutions -- contacting

someone on MSN Messenger using an AOL Instant Messenger (AIM) client, for example

-- employees would need both services up and running on their PCs. The simplest way to

get around using two or more clients, therefore, is to use a solution that supports multiple

IM clients. Open-source development project Jabber Instant Messaging solution is

intended to allow users to chat not only with other Jabber users but also with users of

AIM, ICQ, MSN Messenger, and Yahoo Messenger.



Jabber IM includes corporate-level control and security that allows administrators

to exercise control over employees by imposing different access privileges for groups and

users. This client/server solution is easy to use and contains powerful collaboration and

security features. Unlike other proprietary IM solutions, Jabber is an open-source, XML-

based IM solution. It provides the best of two worlds: the capability of leveraging open

source while simultaneously deploying performance testing and highly scalable products.



Jabber can be installed on all major platforms including Windows, Mac, and Linux. Once

installed on the system, we could have one-on-one chats with another user or create a

multiple participant text conference, with any combination of ICQ, MSN, and Yahoo

users.

As an open-source solution, Jabber IM allows companies to take advantage of other IM

services and leverage open-source development and applications -- Jabber is clearly a

solution to consider.





Communication:

Jabber utilizes XML Streams to connect client to servers and between servers.

The XML Stream is always initiated by the client to the server and is primarily a two-way

communication path. The lifetime of the XML Stream is directly associated with the

lifetime of that user’s online session.

Jabber specifically requires NO client to client direct connections. All Jabber

messages and data from one client to another MUST go through the server. Any client is

free to negotiate any direct connections to another client, but those connections are for

application specific usage only. There are specific instances where this is encouraged,

such as file transfers. Jabber will deliver the file transfer information in the form of a

URL, but how a client either serves or retrieves the file is completely at the will of the

user/client.

Jabber Protocol -XMPP:

The Extensible Messaging and Presence Protocol (XMPP) is an IETF adaptation

of the open Jabber protocol for instant messaging and presence. XMPP/Jabber is a pure

XML protocol that has been quite stable since 1999. It provides a complete set of IM and

presence features on top of a dedicated data transport layer. The basic technology

involves negotiating an XML stream between client and server using the Simple

Authentication and Security Layer (SASL) and Transport Layer Security (TLS) protocols

to secure the stream. Once authenticated, a user may send fragments of XML over the

stream in order to engage in common functionality such as sending messages, chatting

with contacts. There are three basic types of XML fragments used in Jabber:

• Messages ()

• Presence ()

• Info/Query ()



Three Parts of Jabber Protocol

• XML Streams

• Common Data Types

• Standard Extended Namespaces



Jabber Identifiers (JIDs) identifies Any Jabber Entity. E.g. user@server/resource

Protocol Namespaces are stream namespaces. They are of two types: jabber:server for

server/server communications and jabber:client for client/server communications

Example XML Stream

Node:



Host:



Node:



Hello ..Watson



Host: (user receiving a message from receiving-ID)



Hi…How are you?



Node:



Host:





The Node’s XML Document





Watson come here, I need you!







Registration Data Flow

Step 1: Node queries host regarding information that is required in order to register:









Step 2: Host responds with the required registration fields:







Choose a username and password to register with this

service.















Step 3: Node provides required information:





xyz@capulet.com

R0m30

juliet







Step 4: Host informs node of successful registration:





Step 4 (alt): Host informs node of failed registration:





Not Acceptable







Requirements:

Client should be able to:

• Communicate to the server through TCP sockets

• Parse well-formed XML

• Understand the Message data type

• Express presence (online/offline/unavailable) information to the server and

understand incoming presence data.

• Understand the Info/Query data type and have some preset queries such as

logging in, rosters, browsing services, etc.

USECASES:



Use Case UC1: Authorize User

Primary Actor:

User

Supporting Actor:

Jabber Server

Stakeholders and Interests:

User: Wants to chat with his buddies.

Jabber Server: Wants to provide chat service.

Preconditions:

1. User has internet connectivity.

2. Port 5222 on the user’s computer is available.

Success Guarantee (Postconditions):

The user will be able to log in and log out properly.

Main Success Scenario (or Basic Flow):

1. User starts the client.

2. User connects to a specific Jabber server.

3. User enters a Username and a Password and prompts to continue.

4. The Jabber Server authorizes the Username/Password.

5. User is ready to chat.

Extensions (or Alternate Flows):

*a. At any time, System fails:

1. The user will restart the client.

2. User initiates the authorization process again.

*b. At any time, user can log out or close his system.

2-3a. Invalid Server name/Username/Password:

1. System signals error and prompts the user to enter the information

again.

3b. New Account:

1. System prompts the server for new accounts creation.

1a. Denial of new account:

1. System signals the user that he cannot create a new account on

the server

2. System prompts the user to enter the information.

2. Server creates a new account.

2a. Username not available:

1. System signals the error and prompts the user to choose another

username.

3. Server sends the roster information to the System.

Special Requirements:

None

Technology and Data Variations List:

None

Frequency of Occurrence:

Could be random

Open Issues:

1. Can the user initiate two or more client systems on his computer?

Sequence Diagram:









Use Case UC2: Manage Buddies

Primary Actor:

User

Supporting Actor:

Jabber Server

Stakeholders and Interests:

User: Wants to chat with his buddies.

Jabber Server: Wants to provide chat service.

Preconditions:

User has logged into the server.

Success Guarantee (Postconditions):

User’s buddies are organized(categorized) in his roster.

Main Success Scenario (or Basic Flow):

1. At some point after logging into the server, user is ready to add some buddy

names to his roster.

2. User enters a buddyID and prompts to proceed.

3. System sends the information to the Jabber Server and receives the result.

4. BuddyID is added to the user’s roster.

Extensions (or Alternate Flows):

*a. At any time, System fails:

1. The user will restart the client.

2. User initiates the authorization process.

*b. At any time, user can log out or close his system.

2. Invalid Buddy userID format:

1. System signals the user that the format is invalid.

2. System prompts the user to enter the information.

3. Buddy not found:

1. System signals the error to the user.

2. System prompts the user to enter the proper information.

Special Requirements:

None

Technology and Data Variations List:

None

Frequency of Occurrence:

Almost random.

Open Issues:

1. What is the maximum time limit the system should wait for the result from the

Jabber server?

Sequence Diagram:









Use Case UC3: Manage Agents

Primary Actor:

User

Supporting Actor:

Jabber Server

Stakeholders and Interests:

User: Wants to chat with his buddies.

Jabber Server: Wants to provide chat service.

Preconditions:

1. User has logged into the server

2. User has one or more accounts in other Instant Messaging systems like

Yahoo, MSN, AIM etc.

Success Guarantee (Postconditions):

1. User registers/unregisters with other agents available in the server.

Main Success Scenario (or Basic Flow):

1. At any time after logging into the server, user is ready to register / unregister

with the agents available on the server.

2. User chooses the agent.

3. User enters the username and account and then prompts to continue.

4. User is registered / unregistered.

5. Server sends new buddies information from the agent to the client

Extensions (or Alternate Flows):

*a. At any time, System fails:

1. The user will restart the client.

2. User initiates the authorization process.

*b. At any time, user can log out or close his system.

2. No agent available:

1. System signals the user that there are no agents on the server.

3. Invalid Username/Password:

1. System signals the error to the user.

2. System prompts the user to enter the proper information.

5a. System receives the new buddies and adds them to the user’s roster.

5b. System updates the buddies’ presence information

Special Requirements:

None

Technology and Data Variations List:

None

Frequency of Occurrence:

Almost continuous.

Open Issues:

1. Can the user create new accounts in other IM systems though the agents?

Sequence Diagram:









Use Case UC4: Chat with Buddies

Primary Actor:

User

Supporting Actor:

Jabber Server

Stakeholders and Interests:

1. User wants to chat with his buddies.

2. Server wants to provide IM service to the clients.

Preconditions:

1. User is logged into the server.

2. User’s roster has buddies’ information.

3. User can enter public chat rooms.

4. User can create private chat rooms.

Success Guarantee (Postconditions):

1. User chats with his buddies.

Main Success Scenario (or Basic Flow):

1. User can initiate new chat session with other users.

2. User’s Buddies can send messages to the user.

Extensions (or Alternate Flows):

*a. At any time, System fails:

1. The user will restart the client.

2. User initiates the authorization process.

*b. At any time, user can log out or close his system.

1. Buddy Unavailable:

1. System signals the user that the buddy is not available now.

2. User can send offline messages.

2. User is not available:

1. User receives offline messages.

Special Requirements:

None

Technology and Data Variations List:

None

Frequency of Occurrence:

Random.

Open Issues:

None

Sequence Diagram:

Modules:

1. Session Management.

2. Roster Management

3. Presence Managment

4. Chat.

5. Service Registration.

6. Members Display.



Features Implemented:

1. Creating new user account.

2. Log in/out.

3. Add/remove a friend to/from roster.

4. Service (YAHOO, MSN, ICQ etc) registration.

5. Presence view of online/offline buddies.

6. Change user presence (invisible, away, chat..etc).



Class Diagram:

A Higher level UML Class diagram of the project :



Package level view:

--jclient

--com

--forms

--threads

--listeners

The following diagram illustrates the classes implemented in the packages:

Code Listing:

/*

Copyright (C) 2003 Jeevan Varma Anga



This program is free software; you can redistribute it and/or modify

it under the terms of the GNU General Public License as published by

the Free Software Foundation; either version 1, or (at your option)

any later version.



This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.



You should have received a copy of the GNU General Public License

along with this program; if not, write to the Free Software

Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

/**

* JClient is another Jabber client.

*

* It was/is my course project for distributed systems.

* Thanks to Jabber Inc, Jabber.org discussion forms and Adam Olsen.

* Special Thanks to Prof. Paul Schragger for giving me a chance to work on this project.

* Title: JClient

* Description: Jabber Client

* Copyright: Copyright (c) 2003

* @author: Jeevan Varma Anga

* @version: 1.0

*/







package jclient.com;



import javax.swing.UIManager;

import java.awt.*;



public class JClientClass {

boolean packFrame = false;



//Construct the application

public JClientClass() {

JClientFrame frame = new JClientFrame();

//Validate frames that have preset sizes

//Pack frames that have useful preferred size info, e.g. from their layout

if (packFrame) {

frame.pack();

}

else {

frame.validate();

}

//Center the window

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

Dimension frameSize = frame.getSize();

if (frameSize.height > screenSize.height) {

frameSize.height = screenSize.height;

}

if (frameSize.width > screenSize.width) {

frameSize.width = screenSize.width;

}

frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);

frame.setVisible(true);

}

//Main method

public static void main(String[] args) {

try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

}

catch(Exception e) {

e.printStackTrace();

}

new JClientClass();

}

}



#################################################################################



package jclient.com;



import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import org.jivesoftware.smack.*;

import org.jivesoftware.smack.packet.*;

import org.jivesoftware.smack.filter.*;

import javax.swing.tree.*;

import java.util.*;

import java.util.regex.*;

import jclient.com.forms.*;

import jclient.com.listeners.*;



public class JClientFrame extends JFrame {

JPanel contentPane;

JMenuBar jMenuBar1 = new JMenuBar();

JMenu jMenuMenu = new JMenu();

JMenu jMenuHelp = new JMenu();

JMenuItem jMenuHelpAbout = new JMenuItem();

JToolBar jToolBar = new JToolBar();

JButton AddBuddy = new JButton();

JButton RemoveBuddy = new JButton();

JButton ChatWithBuddy = new JButton();

JLabel statusBar = new JLabel();

JMenuItem jMenuLogin = new JMenuItem();

JMenuItem jMenuLogout = new JMenuItem();

JScrollPane jScrollPane1 = new JScrollPane();

JTree jTree1 = new JTree();

JMenu jMenuStatus = new JMenu();

JMenuItem jMenuAvailable = new JMenuItem();

JMenuItem jMenuAway = new JMenuItem();

JMenuItem jMenuIDND = new JMenuItem();

JMenuItem jMenuExit = new JMenuItem();

JMenuItem jMenuInvisible = new JMenuItem();

JMenuItem jMenuRegistration = new JMenuItem();



private XMPPConnection connection;

private KillObserver killObserver = new KillObserver();

private DefaultTreeModel model;

private DefaultMutableTreeNode rootNode;

private Properties StatusOfBuddies=new Properties();

private CustomCellRenderer cellrenderer;

private TreeMap memberStatuses = new TreeMap();

JTree emptyTree=new JTree(new DefaultMutableTreeNode(""));

//Construct the frame

public JClientFrame() {

enableEvents(AWTEvent.WINDOW_EVENT_MASK);

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}

//Component initialization

private void jbInit() throws Exception {

contentPane = (JPanel) this.getContentPane();

contentPane.setLayout(null);

this.setResizable(false);

this.setSize(new Dimension(306, 462));

this.setTitle("Jabber Client (Java Version)");

statusBar.setBackground(Color.lightGray);

statusBar.setBorder(BorderFactory.createEtchedBorder());

statusBar.setText("Not Connected");

statusBar.setBounds(new Rectangle(0, 389, 306, 20));

jMenuMenu.setText("Menu");

jMenuHelp.setText("Help");

jMenuHelpAbout.setText("About");

jMenuHelpAbout.addActionListener(new JClientFrame_jMenuHelpAbout_ActionAdapter(this));

AddBuddy.setText("ADD");

AddBuddy.addActionListener(new JClientFrame_AddBuddy_actionAdapter(this));

AddBuddy.setToolTipText("Add new Buddy");

AddBuddy.setIcon(null);

RemoveBuddy.setToolTipText("Remove Buddy");

RemoveBuddy.setIcon(null);

RemoveBuddy.setText("REMOVE");

RemoveBuddy.addActionListener(new JClientFrame_RemoveBuddy_actionAdapter(this));

ChatWithBuddy.setText("CHAT");

ChatWithBuddy.addActionListener(new JClientFrame_ChatWithBuddy_actionAdapter(this));

ChatWithBuddy.setToolTipText("Chat With Buddy");

jMenuLogin.setText("Login");

jMenuLogin.addActionListener(new JClientFrame_jMenuLogin_actionAdapter(this));

jMenuLogout.setEnabled(false);

jMenuLogout.setText("Logout");

jMenuLogout.addActionListener(new JClientFrame_jMenuLogout_actionAdapter(this));

jScrollPane1.setBounds(new Rectangle(0, 29, 294, 360));

jToolBar.setFloatable(false);

jToolBar.setBounds(new Rectangle(0, 0, 294, 29));

jMenuStatus.setEnabled(false);

jMenuStatus.setText("Change My Status");

jMenuAvailable.setText("Available");

jMenuAvailable.addActionListener(new JClientFrame_jMenuAvailable_actionAdapter(this));

jMenuAway.setText("Away");

jMenuAway.addActionListener(new JClientFrame_jMenuAway_actionAdapter(this));

jMenuIDND.setText("Do Not Disturb");

jMenuIDND.addActionListener(new JClientFrame_jMenuIDND_actionAdapter(this));

jMenuExit.setText("Exit");

jMenuExit.addActionListener(new JClientFrame_jMenuExit_actionAdapter(this));

jMenuInvisible.setText("Invisible");

jMenuInvisible.addActionListener(new JClientFrame_jMenuInvisible_actionAdapter(this));

jMenuRegistration.setText("Service Registration");

jMenuRegistration.setEnabled(false);

jMenuRegistration.addActionListener(new JClientFrame_jMenuRegistration_actionAdapter(this));

jToolBar.add(AddBuddy);

jToolBar.add(RemoveBuddy);

jToolBar.add(ChatWithBuddy);

jMenuMenu.add(jMenuLogin);

jMenuMenu.add(jMenuLogout);

jMenuMenu.addSeparator();

jMenuMenu.add(jMenuStatus);

jMenuMenu.add(jMenuRegistration);

jMenuMenu.add(jMenuExit);

jMenuHelp.add(jMenuHelpAbout);

jMenuBar1.add(jMenuMenu);

jMenuBar1.add(jMenuHelp);

this.setJMenuBar(jMenuBar1);

contentPane.add(jToolBar, null);

contentPane.add(statusBar, null);

contentPane.add(jScrollPane1, null);

emptyTree.setRootVisible(false);

DefaultTreeModel model = (DefaultTreeModel)jTree1.getModel();

jScrollPane1.getViewport().add(emptyTree,null);//jTree1, null);

jMenuStatus.add(jMenuAvailable);

jMenuStatus.add(jMenuAway);

jMenuStatus.add(jMenuIDND);

jMenuStatus.add(jMenuInvisible);



}

//File | Exit action performed

public void jMenuExit_actionPerformed(ActionEvent e) {

System.exit(0);

}

//Help | About action performed

public void jMenuHelpAbout_actionPerformed(ActionEvent e) {

JClientFrame_AboutBox dlg = new JClientFrame_AboutBox(this);

Dimension dlgSize = dlg.getPreferredSize();

Dimension frmSize = getSize();

Point loc = getLocation();

dlg.setLocation((frmSize.width - dlgSize.width) / 2 + loc.x, (frmSize.height - dlgSize.height) / 2 + loc.y);

dlg.setModal(true);

dlg.pack();

dlg.show();

}

//Overridden so we can exit when window is closed

protected void processWindowEvent(WindowEvent e) {

super.processWindowEvent(e);

if (e.getID() == WindowEvent.WINDOW_CLOSING) {

jMenuExit_actionPerformed(null);

}

}

void PacketWaiter()

{

PacketFilter filter = new PacketTypeFilter( Presence.class );

connection.addPacketListener( new SmackPresencePacketListener( this ), filter );

filter = new PacketTypeFilter( Message.class );

connection.addPacketListener( new SmackMessagePacketListener( this ), filter );

filter = new PacketTypeFilter( IQ.class );

connection.addPacketListener( new SmackIQPacketListener( this ), filter );

Presence presence = new Presence( Presence.Type.AVAILABLE );



int priority = 0;

presence.setPriority( priority );

getConnection().sendPacket( presence );

reloadBuddies();

}

public void UpdateBuddyView()

{

jScrollPane1.getViewport().updateUI();

}

public void reloadBuddies()

{

cellrenderer=new CustomCellRenderer(this,connection);

jScrollPane1.setViewportView( NewList() );

}

private JTree NewList()

{

rootNode = processBuddyGroups(connection.getRoster() );



model = new DefaultTreeModel( rootNode );



Runtime.getRuntime().gc();



jTree1 = new JTree( model );

ToolTipManager.sharedInstance().registerComponent( jTree1 );



forloop:

for( int i = 0; i =2)

{

ShowChatBox();

}

}

}

void ShowChatBox()

{

if( jTree1.getSelectionPath() == null ) return;

TreePath path = jTree1.getSelectionPath();

DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();



try {

RosterEntry entry = (RosterEntry)node.getUserObject();

MemberStatus buddy = getMemberStatus( entry.getUser() );



if( buddy.getConversation() == null ){

SimpleChatForm scf=new SimpleChatForm( this, buddy, entry.getUser(), entry.getUser() );

scf.show();

buddy.setConversation(scf);

}else

{

buddy.getConversation().toFront();

buddy.getConversation().setVisible( true );

}



}

catch( Exception e ) {}

}

public DefaultMutableTreeNode processBuddyGroups( Roster roster )

{

TreeMap groupNodes = new TreeMap();



Iterator iterator = roster.getEntries();



while( iterator.hasNext() )

{

RosterEntry entry = (RosterEntry)iterator.next();

MemberStatus m = getMemberStatus( entry.getUser() );

if( !m.getRemoved() )

{

DefaultMutableTreeNode entryNode = new DefaultMutableTreeNode( entry );



Iterator groupIterator = entry.getGroups();

int groupCount = 0;

while( groupIterator.hasNext() )

{

RosterGroup group = (RosterGroup)groupIterator.next();

if( groupNodes.get( group.getName() ) == null ) groupNodes.put( group.getName(), new

DefaultMutableTreeNode( group.getName() ) );



DefaultMutableTreeNode groupNode = (DefaultMutableTreeNode)groupNodes.get(

group.getName() );

if( Pattern.matches( ".*@.*", entry.getUser() ) ||

!Pattern.matches( ".*@.*", entry.getUser() ) ) groupNode.add( entryNode );



groupCount++;

}



//if it's an agent...

if( groupCount == 0 && !Pattern.matches( ".*@.*", entry.getUser() ))

{

if( groupNodes.get( "agents" ) == null ) groupNodes.put( "agents", new DefaultMutableTreeNode(

"Agents/Transports" ) );

DefaultMutableTreeNode groupNode = (DefaultMutableTreeNode)groupNodes.get( "agents" );

groupNode.add( entryNode );

}

else if( groupCount == 0 && Pattern.matches( ".*@.*", entry.getUser() ) )

{

if( groupNodes.get( "unfiled" ) == null ) groupNodes.put( "unfiled", new DefaultMutableTreeNode(

"Contacts" ) );

DefaultMutableTreeNode groupNode = (DefaultMutableTreeNode)groupNodes.get( "unfiled" );

groupNode.add( entryNode );

}

}

}

return addGroupNodes( groupNodes );

}

private DefaultMutableTreeNode addGroupNodes( TreeMap groupNodes )

{

DefaultMutableTreeNode root = new DefaultMutableTreeNode();

java.util.List keys = new ArrayList( groupNodes.keySet() );

Iterator iterator = keys.iterator();

while( iterator.hasNext() )

{

DefaultMutableTreeNode node = (DefaultMutableTreeNode)groupNodes.get( iterator.next() );

if( node.getChildCount() > 0 ) root.add( node );

}

return root;

}



public void ResetAllMemberStatuses()

{

TreeMap m=getMemberStatuses();

Iterator i = m.values().iterator();

while (i.hasNext()) {

MemberStatus member = (MemberStatus) i.next();

if (member.getConversation() != null) {

member.getConversation().dispose();

member.setConversation(null);

}

}

memberStatuses.clear();

}

public MemberStatus getMemberStatus( String userId )

{

MemberStatus m = new MemberStatus( this,userId );



if( memberStatuses.get( userId ) != null )

{

System.err.println("Member exists");

m = (MemberStatus)memberStatuses.get( userId );

}

else

{

System.err.println("Member not found...!");

memberStatuses.put( userId, m );

}

return m;

}

public TreeMap getMemberStatuses() { return this.memberStatuses; }





class CustomCellRenderer extends DefaultTreeCellRenderer

{

private XMPPConnection connection=null;

private JClientFrame frame;

public String toString()

{

return getText();

}

CustomCellRenderer(JClientFrame frame,XMPPConnection con)

{

this.frame=frame;

connection=con;

}

public Component getTreeCellRendererComponent(JTree jTree1,Object value,boolean bSelected,

boolean bExpanded,boolean bLeaf,int iRow,boolean bHasFocus){

if( bLeaf )

{

DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;

RosterEntry entry = (RosterEntry)(node.getUserObject());

if( entry == null )

{

super.getTreeCellRendererComponent( jTree1, "root", bSelected, bExpanded, bLeaf, iRow,

bHasFocus );

return this;

}

value = entry.getName();

if( value == null ) value = entry.getUser();



MemberStatus buddy = (MemberStatus)frame.getMemberStatus( entry.getUser() );

if( buddy.getName() != null ) value = buddy.getName();



super.getTreeCellRendererComponent( jTree1, value, bSelected, bExpanded, bLeaf, iRow,

bHasFocus );



setFont( new Font("Arial",Font.BOLD,12));

if( buddy.size() == 0 )

{

//offline;

setForeground( Color.GRAY );

}

String user = entry.getUser();

String server = entry.getUser();

if(Pattern.matches( ".*@.*", user ) )

{

String parts[] = new String[2];

parts = entry.getUser().split( "@" );

user = parts[0];

server = parts[0];

if( parts[1] != null ) server = parts[1];

}

setToolTipText( statusMessage( buddy, buddy.getPresenceMode().toString() ) );

}

else {

super.getTreeCellRendererComponent( jTree1, value, bSelected, bExpanded, bLeaf, iRow,

bHasFocus );

setToolTipText( null );

setFont( new Font( "Sans", Font.ITALIC, 10 ) );

}



return this;

}

public String statusMessage( MemberStatus buddy, String mode )

{

String s;



if( buddy.size() == 0 ) return "Offline";



if( !buddy.getStatusMessage().equals( "" ) ) s = buddy.getStatusMessage();

else if( mode.equals( "away" ) ) s = "Away";

else if( mode.equals( "xa" ) ) s = "Extended Away";

else if( mode.equals( "dnd" ) ) s = "Do Not Disturb";

else if( mode.equals( "chat" ) ) s = "Wants to Chat";

else s = "Available";



return s;

}

}



public XMPPConnection getConnection()

{

return connection;

}

public void SetConnection(XMPPConnection con)

{

connection=con;

PacketWaiter();

}

public void ShowLoginForm()

{

LoginForm loginform=new LoginForm(this,"Login/Registration Form",true);

Dimension dlgSize = loginform.getPreferredSize();

Dimension frmSize = getSize();

Point loc = getLocation();

loginform.setBounds(getX(),getY()+100,300,300);

loginform.show();

}

public void LoggedIn()

{

jMenuLogin.setEnabled(false);

jMenuLogout.setEnabled(true);

jMenuStatus.setEnabled(true);

jMenuRegistration.setEnabled(true);

statusBar.setText("Available");

JOptionPane.showMessageDialog(this,"Successfully Logged

In....!","Info",JOptionPane.INFORMATION_MESSAGE);

}

public void LoggedOut()

{

ResetAllMemberStatuses();

jMenuLogin.setEnabled(true);

jMenuLogout.setEnabled(false);

jMenuStatus.setEnabled(false);

jMenuRegistration.setEnabled(false);

jScrollPane1.setViewportView( emptyTree);

statusBar.setText("Not Connected");

}

void jMenuLogin_actionPerformed(ActionEvent e) {

ShowLoginForm();

}



void jMenuLogout_actionPerformed(ActionEvent e) {

if (JOptionPane.showConfirmDialog(this,"Do you want to

logout?","Logout",JOptionPane.YES_NO_OPTION)==JOptionPane.NO_OPTION)

return;

connection.close();

LoggedOut();

}



void jMenuAvailable_actionPerformed(ActionEvent e) {

Presence presence = new Presence( Presence.Type.AVAILABLE );

int priority = 0;

presence.setPriority( priority );

presence.setMode(Presence.Mode.AVAILABLE);

getConnection().sendPacket( presence );

statusBar.setText("Available");

}

void jMenuAway_actionPerformed(ActionEvent e) {

Presence presence = new Presence( Presence.Type.AVAILABLE );

int priority = 0;

presence.setPriority( priority );

presence.setMode(Presence.Mode.AWAY);

getConnection().sendPacket( presence );

statusBar.setText("Away");

}



void jMenuIDND_actionPerformed(ActionEvent e) {

Presence presence = new Presence( Presence.Type.AVAILABLE );

int priority = 0;

presence.setPriority( priority );

presence.setMode(Presence.Mode.DO_NOT_DISTURB);

getConnection().sendPacket( presence );

statusBar.setText("Do Not Disturb");

}



void jMenuInvisible_actionPerformed(ActionEvent e) {

Presence presence = new Presence( Presence.Type.UNAVAILABLE );

int priority = 0;

presence.setPriority( priority );

presence.setMode(Presence.Mode.INVISIBLE);

getConnection().sendPacket( presence );

statusBar.setText("Invisible");

}



void jMenuRegistration_actionPerformed(ActionEvent e) {

ServiceRegistrationForm srf=new ServiceRegistrationForm(this,"Service Registration

Form",true,connection);

Dimension dlgSize = srf.getPreferredSize();

Dimension frmSize = getSize();

Point loc = getLocation();

srf.setBounds((frmSize.width - dlgSize.width) / 2+170,

(frmSize.height - dlgSize.height) / 2+100,450,325);

srf.show();

}





public void addObserver( Observer obj ) { killObserver.addObserver( obj ); }

public void kill()

{

setVisible( false );

killObserver.kill();

dispose();

}

/**

* This Observable class allows all the open dialogs that are observing it to be

* destroyed when it is.

**/

class KillObserver extends Observable

{

public void kill()

{

setChanged();

notifyObservers();

}

}



void AddBuddy_actionPerformed(ActionEvent e) {

//show dialog box

if (!jMenuLogout.isEnabled()) return;

AddBuddyForm form=new AddBuddyForm(this);

Dimension dlgSize = form.getPreferredSize();

Dimension frmSize = getSize();

Point loc = getLocation();

form.setBounds(getX()+20,getY()+100,250,200);

form.show();

}



void RemoveBuddy_actionPerformed(ActionEvent e) {

if (!jMenuLogout.isEnabled()) return;

if (JOptionPane.showConfirmDialog( null, "Are you sure you wish to remove this contact", "Remove

Contact",

JOptionPane.YES_NO_OPTION )==JOptionPane.NO_OPTION) return;

DefaultMutableTreeNode node =

(DefaultMutableTreeNode)jTree1.getSelectionPath().getLastPathComponent();

RosterEntry entry = (RosterEntry)node.getUserObject();

Iterator iterator = entry.getGroups();

while( iterator.hasNext() )

{

RosterGroup group = (RosterGroup)iterator.next();

group.removeEntry( entry );

}



RosterPacket packet = new RosterPacket();

packet.setType( IQ.Type.SET );

RosterPacket.Item item = new RosterPacket.Item( entry.getUser(), entry.getName() );

item.setItemType( RosterPacket.ItemType.REMOVE );

packet.addRosterItem( item );

getConnection().sendPacket( packet );

MemberStatus buddy = getMemberStatus( entry.getUser() );

buddy.setRemoved( true );

reloadBuddies();

}



void ChatWithBuddy_actionPerformed(ActionEvent e) {

//continue only if the selected node is a leafnode

if (!model.isLeaf(jTree1.getSelectionPath().getLastPathComponent())) return;

ShowChatBox();

}



}







class JClientFrame_jMenuHelpAbout_ActionAdapter implements ActionListener {

JClientFrame adaptee;



JClientFrame_jMenuHelpAbout_ActionAdapter(JClientFrame adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.jMenuHelpAbout_actionPerformed(e);

}

}



class JClientFrame_jMenuLogin_actionAdapter implements java.awt.event.ActionListener {

JClientFrame adaptee;



JClientFrame_jMenuLogin_actionAdapter(JClientFrame adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.jMenuLogin_actionPerformed(e);

}

}



class JClientFrame_jMenuLogout_actionAdapter implements java.awt.event.ActionListener {

JClientFrame adaptee;



JClientFrame_jMenuLogout_actionAdapter(JClientFrame adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.jMenuLogout_actionPerformed(e);

}

}



class JClientFrame_jMenuExit_actionAdapter implements java.awt.event.ActionListener {

JClientFrame adaptee;



JClientFrame_jMenuExit_actionAdapter(JClientFrame adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.jMenuExit_actionPerformed(e);

}

}



class JClientFrame_jMenuAvailable_actionAdapter implements java.awt.event.ActionListener {

JClientFrame adaptee;



JClientFrame_jMenuAvailable_actionAdapter(JClientFrame adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.jMenuAvailable_actionPerformed(e);

}

}



class JClientFrame_jMenuAway_actionAdapter implements java.awt.event.ActionListener {

JClientFrame adaptee;



JClientFrame_jMenuAway_actionAdapter(JClientFrame adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.jMenuAway_actionPerformed(e);

}

}



class JClientFrame_jMenuIDND_actionAdapter implements java.awt.event.ActionListener {

JClientFrame adaptee;



JClientFrame_jMenuIDND_actionAdapter(JClientFrame adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.jMenuIDND_actionPerformed(e);

}

}



class JClientFrame_jMenuInvisible_actionAdapter implements java.awt.event.ActionListener {

JClientFrame adaptee;



JClientFrame_jMenuInvisible_actionAdapter(JClientFrame adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.jMenuInvisible_actionPerformed(e);

}

}



class JClientFrame_jMenuRegistration_actionAdapter implements java.awt.event.ActionListener {

JClientFrame adaptee;



JClientFrame_jMenuRegistration_actionAdapter(JClientFrame adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.jMenuRegistration_actionPerformed(e);

}

}



class JClientFrame_AddBuddy_actionAdapter implements java.awt.event.ActionListener {

JClientFrame adaptee;



JClientFrame_AddBuddy_actionAdapter(JClientFrame adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.AddBuddy_actionPerformed(e);

}

}



class JClientFrame_RemoveBuddy_actionAdapter implements java.awt.event.ActionListener {

JClientFrame adaptee;



JClientFrame_RemoveBuddy_actionAdapter(JClientFrame adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.RemoveBuddy_actionPerformed(e);

}

}



class JClientFrame_ChatWithBuddy_actionAdapter implements java.awt.event.ActionListener {

JClientFrame adaptee;



JClientFrame_ChatWithBuddy_actionAdapter(JClientFrame adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.ChatWithBuddy_actionPerformed(e);

}

}



#################################################################################



package jclient.com;



import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.border.*;





public class JClientFrame_AboutBox extends JDialog implements ActionListener {



JPanel panel1 = new JPanel();

JPanel panel2 = new JPanel();

JPanel insetsPanel1 = new JPanel();

JPanel insetsPanel2 = new JPanel();

JPanel insetsPanel3 = new JPanel();

JButton button1 = new JButton();

JLabel imageLabel = new JLabel();

JLabel label1 = new JLabel();

JLabel label2 = new JLabel();

JLabel label3 = new JLabel();

JLabel label4 = new JLabel();

ImageIcon image1 = new ImageIcon();

BorderLayout borderLayout1 = new BorderLayout();

BorderLayout borderLayout2 = new BorderLayout();

FlowLayout flowLayout1 = new FlowLayout();

GridLayout gridLayout1 = new GridLayout();

String product = "JClient";

String version = "1.0";

String copyright = "Copyright (c) 2003";

String comments = "Jabber Client";

public JClientFrame_AboutBox(Frame parent) {

super(parent);

enableEvents(AWTEvent.WINDOW_EVENT_MASK);

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}

//Component initialization

private void jbInit() throws Exception {

image1 = new ImageIcon(jclient.com.JClientFrame.class.getResource("about.png"));

imageLabel.setIcon(image1);

this.setTitle("About");

panel1.setLayout(borderLayout1);

panel2.setLayout(borderLayout2);

insetsPanel1.setLayout(flowLayout1);

insetsPanel2.setLayout(flowLayout1);

insetsPanel2.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

gridLayout1.setRows(4);

gridLayout1.setColumns(1);

label1.setText(product);

label2.setText(version);

label3.setText(copyright);

label4.setText(comments);

insetsPanel3.setLayout(gridLayout1);

insetsPanel3.setBorder(BorderFactory.createEmptyBorder(10, 60, 10, 10));

button1.setText("Ok");

button1.addActionListener(this);

insetsPanel2.add(imageLabel, null);

panel2.add(insetsPanel2, BorderLayout.WEST);

this.getContentPane().add(panel1, null);

insetsPanel3.add(label1, null);

insetsPanel3.add(label2, null);

insetsPanel3.add(label3, null);

insetsPanel3.add(label4, null);

panel2.add(insetsPanel3, BorderLayout.CENTER);

insetsPanel1.add(button1, null);

panel1.add(insetsPanel1, BorderLayout.SOUTH);

panel1.add(panel2, BorderLayout.NORTH);

setResizable(true);

}

//Overridden so we can exit when window is closed

protected void processWindowEvent(WindowEvent e) {

if (e.getID() == WindowEvent.WINDOW_CLOSING) {

cancel();

}

super.processWindowEvent(e);

}

//Close the dialog

void cancel() {

dispose();

}

//Close the dialog on a button event

public void actionPerformed(ActionEvent e) {

if (e.getSource() == button1) {

cancel();

}

}

}

#################################################################################



package jclient.com;



import java.util.*;

import org.jivesoftware.smack.*;

import org.jivesoftware.smack.packet.*;

import jclient.com.forms.*;



public class MemberStatus extends Hashtable

{

private String userId = "";

private Presence.Mode presenceMode = Presence.Mode.EXTENDED_AWAY;

private String statusMessage = "";

private SimpleChatForm conversation = null;

private String buddyName;

private boolean removed = false;

private boolean hasSignedOn = false;

jclient.com.JClientFrame parent;

public MemberStatus( jclient.com.JClientFrame frame,String buddyId )

{

parent=frame;

this.userId = buddyId;

if (buddyId.indexOf("@")!=-1)

this.buddyName=buddyId.substring(0,buddyId.indexOf("@"));

else

buddyName=buddyId;

}

public String getHighestResource()

{

String resource = "";

java.util.List keys = new ArrayList( keySet() );

Iterator iterator = keys.iterator();

int highest = -2;

while( iterator.hasNext() )

{

Object key = iterator.next();

Integer value = (Integer)get( key );

if( value.intValue() > highest )

{

resource = (String)key;

highest = value.intValue();

}

}

return resource;

}



public void setHasSignedOn( boolean on ) { this.hasSignedOn = on; parent.UpdateBuddyView();}

public boolean getHasSignedOn() { return this.hasSignedOn; }



public void setRemoved( boolean removed ) { this.removed = removed; }

public boolean getRemoved() { return this.removed; }



public void setName( String name ) { this.buddyName = name; }

public String getName() { return this.buddyName; }

public void setUserId( String buddyId ) { this.userId = buddyId; }

public String getUserId() { return this.userId; }



public void setPresenceMode( Presence.Mode mode ) { this.presenceMode = mode;

parent.UpdateBuddyView();}

public Presence.Mode getPresenceMode() { return this.presenceMode; }



public void setStatusMessage( String message ) { this.statusMessage = message;

parent.UpdateBuddyView();}

public String getStatusMessage() { return this.statusMessage; }



public void setConversation( SimpleChatForm window ) { this.conversation = window; }

public SimpleChatForm getConversation() { return this.conversation; }

}



#################################################################################



package jclient.com;



import org.jivesoftware.smack.packet.*;

import org.jivesoftware.smack.packet.XMPPError;

import org.jivesoftware.smack.filter.PacketFilter;

import org.jivesoftware.smack.util.StringUtils;

import org.jivesoftware.smack.provider.*;

import java.util.*;

import org.xmlpull.v1.*;





public class Service extends IQ implements IQProvider {



private String service = null;



public Service() {

}

public String getChildElementXML(){

return null;

}

public IQ parseIQ(org.xmlpull.v1.XmlPullParser parser) throws Exception

{

IQ iqPacket = null;



String serviceName = null;

String serviceAddress = null;

String serviceInfo=null;



Map properties = new HashMap();



if (parser==null) return null;

String elementName = parser.getName();

String namespace = parser.getNamespace();



XMPPError error=null;

boolean done = false;

while (!done)

{

int eventType = parser.next();

if (eventType == XmlPullParser.START_TAG &&parser.getName().equals("conference"))

{

serviceName = parser.getAttributeValue("", "type");

serviceAddress=parser.getAttributeValue("","jid");

serviceInfo=parser.getAttributeValue("","name");

properties.put(serviceName,serviceAddress+":"+serviceInfo);

}

if (eventType == XmlPullParser.START_TAG && parser.getName().equals("service"))

{

elementName = parser.getName();

if (elementName.equals("service"))

{

serviceName = parser.getAttributeValue("", "type");

serviceAddress=parser.getAttributeValue("","jid");

serviceInfo=parser.getAttributeValue("","name");

properties.put(serviceName,serviceAddress+":"+serviceInfo);

eventType=parser.next();

}

int index1=parser.getText().indexOf("/");

if (index1==-1)

while(!parser.getText().equals(""))

eventType=parser.next();

}

else if (eventType == XmlPullParser.END_TAG)

{

if (parser.getName().equals("service"))

done = true;

}

}

// Set basic values on the iq packet.

if (iqPacket == null) {

// If an IQ packet wasn't created above, create an empty IQ packet.

iqPacket = new IQ() {

public String getChildElementXML() {

return null;

}};

}



// Set packet properties.

if (properties != null)

{

for (Iterator i=properties.keySet().iterator(); i.hasNext(); )

{

String name = (String)i.next();

iqPacket.setProperty(name, properties.get(name));

}

}

iqPacket.setPacketID("service");

return iqPacket;

}

}

#################################################################################



package jclient.com.forms;



import java.awt.*;

import javax.swing.*;

import javax.swing.border.*;

import java.awt.event.*;

import javax.swing.event.*;

import jclient.com.*;

import jclient.com.threads.*;

import org.jivesoftware.smack.*;

import org.jivesoftware.smack.packet.*;



public class LoginForm extends JDialog{

JPanel panel1 = new JPanel();

JTextField ServerName = new JTextField();

JTextField Username = new JTextField();

JPasswordField Password = new JPasswordField();

JLabel jLabel1 = new JLabel();

JLabel jLabel2 = new JLabel();

JLabel jLabel3 = new JLabel();

JButton Login = new JButton();

JButton Close = new JButton();

Border border1;

JCheckBox NewUser = new JCheckBox();

JPasswordField RenteredPassword = new JPasswordField();

JLabel jLabel4 = new JLabel();

JClientFrame parent=null;

public LoginForm(JClientFrame frame, String title, boolean modal) {

super(frame, title, modal);

try {

parent=frame;

jbInit();

pack();

}

catch(Exception ex) {

ex.printStackTrace();

}

}



public LoginForm() {

this(null, "", false);



}

private void jbInit() throws Exception {

border1 = BorderFactory.createCompoundBorder(new

EtchedBorder(EtchedBorder.RAISED,Color.white,new Color(156, 156,

158)),BorderFactory.createEmptyBorder(10,10,10,10));

panel1.setLayout(null);

panel1.setToolTipText("");

panel1.setBounds(new Rectangle(0, 0, 400, 300));

ServerName.setText("jabber.dk");

ServerName.setBounds(new Rectangle(104, 32, 132, 24));

Username.setText("testingid1");

Username.setBounds(new Rectangle(104, 96, 132, 24));

Password.setText("testing");

Password.setBounds(new Rectangle(104, 140, 132, 24));

jLabel1.setHorizontalAlignment(SwingConstants.RIGHT);

jLabel1.setText("Server");

jLabel1.setBounds(new Rectangle(14, 32, 67, 24));

jLabel2.setHorizontalAlignment(SwingConstants.RIGHT);

jLabel2.setText("Username");

jLabel2.setBounds(new Rectangle(15, 96, 66, 25));

jLabel3.setHorizontalAlignment(SwingConstants.RIGHT);

jLabel3.setText("Password");

jLabel3.setBounds(new Rectangle(18, 140, 63, 23));

Login.setBounds(new Rectangle(12, 215, 99, 29));

Login.setText("Login");

Login.addActionListener(new LoginForm_Login_actionAdapter(this));

Close.setBounds(new Rectangle(156, 214, 110, 31));

Close.setText("Close");

Close.addActionListener(new LoginForm_Close_actionAdapter(this));

this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

this.setModal(true);

this.setResizable(false);

this.setTitle("Login Form");

this.getContentPane().setLayout(null);

NewUser.setText("New User");

NewUser.setBounds(new Rectangle(104, 68, 104, 23));

NewUser.addChangeListener(new LoginForm_NewUser_changeAdapter(this));

RenteredPassword.setBounds(new Rectangle(104, 176, 132, 24));

RenteredPassword.setEnabled(true);

RenteredPassword.setEditable(false);

RenteredPassword.setText("");

jLabel4.setBounds(new Rectangle(5, 176, 76, 23));

jLabel4.setText("Password");

jLabel4.setHorizontalAlignment(SwingConstants.RIGHT);

getContentPane().add(panel1, null);

panel1.add(jLabel1, null);

panel1.add(ServerName, null);

panel1.add(NewUser, null);

panel1.add(Username, null);

panel1.add(jLabel2, null);

panel1.add(jLabel3, null);

panel1.add(Password, null);

panel1.add(RenteredPassword, null);

panel1.add(jLabel4, null);

panel1.add(Close, null);

panel1.add(Login, null);

}



void Login(String userid,String password,String server)

{

WaitForm waitform=new WaitForm(null,"Trying to Connect to the server...!");

ConnectorThread ct=new ConnectorThread(parent,waitform,userid,password,server);

Thread thread = new Thread(ct);

thread.start();

waitform.setVisible( true );

setVisible( false );

}

public boolean createAccount(String userid,String password,String server)

{

XMPPConnection connection;

AccountManager manager;



try {

connection = new XMPPConnection(server );

}

catch( XMPPException e )

{

JOptionPane.showMessageDialog(this,e.getMessage(),"Account

Creation",JOptionPane.ERROR_MESSAGE);

return false;

}



manager = connection.getAccountManager();



try {

manager.createAccount( userid, password, null );

}

catch( XMPPException e )

{

String errorMessage;

XMPPError error = e.getXMPPError();

if( error != null ) errorMessage = error.getMessage();

else errorMessage = "Unkown Error";

JOptionPane.showMessageDialog(this,errorMessage,"Account

Creation",JOptionPane.ERROR_MESSAGE);

return false;

}



connection.close();



return true;

}





void Login_actionPerformed(ActionEvent e)

{

if (NewUser.isSelected()){

if (String.valueOf(RenteredPassword.getPassword()).equals(String.valueOf(Password.getPassword())))

{ if

(createAccount(Username.getText(),String.valueOf(Password.getPassword()),ServerName.getText()))

Login(Username.getText(),String.valueOf(Password.getPassword()),ServerName.getText());//New

account creation module

}else

RenteredPassword.setText("");

}

else

Login(Username.getText(),String.valueOf(Password.getPassword()),ServerName.getText());

}



void Close_actionPerformed(ActionEvent e) {

hide();

}

void NewUser_stateChanged(ChangeEvent e) {

RenteredPassword.setText("");

if (NewUser.isSelected())

RenteredPassword.setEditable(true);

else

RenteredPassword.setEditable(false);

}



}



class LoginForm_Login_actionAdapter implements java.awt.event.ActionListener {

LoginForm adaptee;



LoginForm_Login_actionAdapter(LoginForm adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.Login_actionPerformed(e);

}

}



class LoginForm_Close_actionAdapter implements java.awt.event.ActionListener {

LoginForm adaptee;



LoginForm_Close_actionAdapter(LoginForm adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.Close_actionPerformed(e);

}

}



class LoginForm_NewUser_changeAdapter implements javax.swing.event.ChangeListener {

LoginForm adaptee;



LoginForm_NewUser_changeAdapter(LoginForm adaptee) {

this.adaptee = adaptee;

}

public void stateChanged(ChangeEvent e) {

adaptee.NewUser_stateChanged(e);

}

}





#################################################################################



package jclient.com.forms;



import jclient.com.*;

import java.awt.*;

import javax.swing.*;

import java.awt.event.*;

import org.jivesoftware.smack.*;



public class AddBuddyForm extends JDialog {

JLabel jLabel1 = new JLabel();

JLabel jLabel2 = new JLabel();

JTextField JabberID = new JTextField();

JTextField Group = new JTextField();

JButton Ok = new JButton();

JButton Cancel = new JButton();

String JID=null,GroupName=null;

JClientFrame parent=null;

public AddBuddyForm(JClientFrame frame) throws HeadlessException {

super(frame,"Add Buddy",true);

parent=frame;

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}



public AddBuddyForm() {

try {

jbInit();

}

catch(Exception e) {

e.printStackTrace();

}

}

private void jbInit() throws Exception {

jLabel1.setHorizontalAlignment(SwingConstants.RIGHT);

jLabel1.setText("JabberID");

jLabel1.setBounds(new Rectangle(24, 24, 62, 28));

this.getContentPane().setLayout(null);

jLabel2.setHorizontalAlignment(SwingConstants.RIGHT);

jLabel2.setText("Group");

jLabel2.setBounds(new Rectangle(24, 60, 62, 28));

JabberID.setText("");

JabberID.setBounds(new Rectangle(94, 26, 103, 26));

Group.setText("");

Group.setBounds(new Rectangle(94, 62, 103, 26));

Ok.setBounds(new Rectangle(37, 107, 58, 24));

Ok.setVerifyInputWhenFocusTarget(true);

Ok.setText("Ok");

Ok.addActionListener(new AddBuddyForm_Ok_actionAdapter(this));

Cancel.setBounds(new Rectangle(118, 107, 72, 24));

Cancel.setText("Cancel");

Cancel.addActionListener(new AddBuddyForm_Cancel_actionAdapter(this));

this.setResizable(false);

this.setTitle("Add Contact");

this.getContentPane().add(JabberID, null);

this.getContentPane().add(Group, null);

this.getContentPane().add(jLabel1, null);

this.getContentPane().add(jLabel2, null);

this.getContentPane().add(Ok, null);

this.getContentPane().add(Cancel, null);

}



void Ok_actionPerformed(ActionEvent e) {

JID=JabberID.getText().trim();

GroupName=Group.getText().trim();

if (JID.equals(""))

return;

if (GroupName.equals("")) GroupName="Contacts";

Roster buddyGroups = parent.getConnection().getRoster();

JID=JabberID.getText().trim()+"@"+parent.getConnection().getHost();

WaitForm wait = new WaitForm( parent, "Please wait..." );

wait.setVisible( true );

setVisible( false );

Thread thread = new Thread( new AddBuddyThread( wait, GroupName, JID, this ) );

thread.start();

}



void Cancel_actionPerformed(ActionEvent e) {

this.dispose();

}



class AddBuddyThread implements Runnable

{

private String errorMessage;

private String groupName;

private String buddyId;

private String buddyName;

private AddBuddyForm form;

private WaitForm wait;



public AddBuddyThread( WaitForm wait, String groupName, String buddyId, AddBuddyForm form

)

{

this.wait = wait;

this.groupName = groupName;

this.buddyId = buddyId;

this.form = form;

if (buddyId.indexOf("@")!=-1)

this.buddyName=buddyId.substring(0,buddyId.indexOf("@"));

else

buddyName=buddyId;

}



public void run()

{

Roster buddyGroups = parent.getConnection().getRoster();

try {

if( groupName == null ) buddyGroups.createEntry( buddyId, buddyName, null );

else buddyGroups.createEntry( buddyId, buddyName, new String[] { groupName } );

}

catch( XMPPException e )

{

errorMessage = e.getMessage();

if( errorMessage == null ) errorMessage = "An unkown error has ocurred while attempting

to add/modify your buddy.";

JOptionPane.showMessageDialog(parent,errorMessage,"Add

Buddy",JOptionPane.INFORMATION_MESSAGE);

}

SwingUtilities.invokeLater( new Runnable()

{

public void run()

{

wait.setVisible( false );

wait.dispose();



if( errorMessage != null )

{

JOptionPane.showMessageDialog(parent,errorMessage,"Add

Buddy",JOptionPane.INFORMATION_MESSAGE);

form.setVisible( true );

}

else {

JOptionPane.showMessageDialog(parent,"Your buddy has been saved.","Add

Buddy",JOptionPane.INFORMATION_MESSAGE);



RosterEntry entry = parent.getConnection().getRoster().getEntry( buddyId );

try {

if( entry != null ) entry.setName( buddyName );

}

catch( Exception e ) { }



MemberStatus buddy = parent.getMemberStatus( buddyId );

buddy.setRemoved( false );

buddy.setName( buddyName );



if( buddy.getConversation() != null )

{

buddy.getConversation().setTitle( buddyId + " (" + buddyId + ")" );

buddy.getConversation().setName( buddyId );

}



parent.getConnection().getRoster().reload();



parent.reloadBuddies();

form.dispose();

}

}

} );

}

}

}



class AddBuddyForm_Ok_actionAdapter implements java.awt.event.ActionListener {

AddBuddyForm adaptee;



AddBuddyForm_Ok_actionAdapter(AddBuddyForm adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.Ok_actionPerformed(e);

}

}



class AddBuddyForm_Cancel_actionAdapter implements java.awt.event.ActionListener {

AddBuddyForm adaptee;



AddBuddyForm_Cancel_actionAdapter(AddBuddyForm adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.Cancel_actionPerformed(e);

}

}



#################################################################################



package jclient.com.forms;



import java.awt.*;

import javax.swing.*;

import java.awt.event.*;

import javax.swing.event.*;

import org.jivesoftware.smack.*;

import org.jivesoftware.smack.packet.*;

import org.jivesoftware.smack.filter.*;

import org.jivesoftware.smack.provider.*;

import java.util.*;

import org.xmlpull.v1.*;

import jclient.com.Service;

import jclient.com.JClientFrame;

public class ServiceRegistrationForm extends JDialog {

JPanel panel1 = new JPanel();

BorderLayout borderLayout1 = new BorderLayout();

JPanel jPanel1 = new JPanel();

JList ServicesList = new JList();

JPanel InfoPanel = new JPanel();

JButton Register = new JButton();

JLabel jLabel2 = new JLabel();

JButton Unregister = new JButton();

JPasswordField AccountPassword = new JPasswordField();

JLabel jLabel1 = new JLabel();

JTextField AccountUsername = new JTextField();

JLabel jLabel3 = new JLabel();

JButton Cancel = new JButton();

JLabel jLabel4 = new JLabel();

XMPPConnection connection;

Map TransportAddresses=new HashMap(),TransportInfo=new HashMap();

JClientFrame parent;

WaitForm wait;

String regKey;

public ServiceRegistrationForm(JClientFrame frame, String title, boolean modal,XMPPConnection

connection) {

super(frame, title, modal);

parent=frame;

try {

this.connection=connection;

jbInit();

pack();

}

catch(Exception ex) {

ex.printStackTrace();

}

}



public ServiceRegistrationForm() {

this(null, "", false,null);

}

private void jbInit() throws Exception {

panel1.setLayout(borderLayout1);

jPanel1.setLayout(null);

ServicesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

ServicesList.setBounds(new Rectangle(24, 44, 136, 226));

ServicesList.addListSelectionListener(new

ServiceRegistrationForm_ServicesList_listSelectionAdapter(this));

InfoPanel.setBounds(new Rectangle(172, 45, 276, 229));

InfoPanel.setLayout(null);

Register.setBounds(new Rectangle(44, 189, 102, 26));

Register.setText("Register");

Register.addActionListener(new ServiceRegistrationForm_Register_actionAdapter(this));

jLabel2.setHorizontalAlignment(SwingConstants.RIGHT);

jLabel2.setText("Password");

jLabel2.setBounds(new Rectangle(41, 76, 57, 30));

//Unregister.setBounds(new Rectangle(160, 150, 102, 25));

//Unregister.setText("Unregister");

//Unregister.addActionListener(new ServiceRegistrationForm_Unregister_actionAdapter(this));

AccountPassword.setText("");

AccountPassword.setBounds(new Rectangle(106, 77, 113, 24));

jLabel1.setHorizontalAlignment(SwingConstants.RIGHT);

jLabel1.setText("UserName");

jLabel1.setBounds(new Rectangle(36, 45, 62, 26));

AccountUsername.setText("");

AccountUsername.setBounds(new Rectangle(106, 46, 113, 24));

jLabel3.setText("Enter Account Information");

jLabel3.setBounds(new Rectangle(46, 12, 162, 21));

Cancel.setBounds(new Rectangle(160, 188, 102, 26));

Cancel.setText("Cancel");

Cancel.addActionListener(new ServiceRegistrationForm_Cancel_actionAdapter(this));

jLabel4.setBounds(new Rectangle(23, 18, 127, 21));

jLabel4.setText("List of Services Available");

this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

getContentPane().add(panel1);

panel1.add(jPanel1, BorderLayout.CENTER);

jPanel1.add(ServicesList, null);

jPanel1.add(InfoPanel, null);

InfoPanel.add(jLabel1, null);

InfoPanel.add(jLabel2, null);

InfoPanel.add(AccountPassword, null);

InfoPanel.add(AccountUsername, null);

InfoPanel.add(Cancel, null);

InfoPanel.add(Register, null);

InfoPanel.add(jLabel3, null);

jPanel1.add(jLabel4, null);

InfoPanel.setVisible(false);

LoadServices();

}

void LoadServices()

{



Packet p = new Packet() {

public String toString(){

return "";

}

public String toXML() {

return "";

}};

try {

connection.sendPacket(p);

PacketWaiter();

//load the names into the list

}

catch (XMPPException ex) {

JOptionPane.showMessageDialog(this,ex.getMessage(),"Load

Services",JOptionPane.ERROR_MESSAGE);

}

}



void PacketWaiter() throws XMPPException

{

ProviderManager.addIQProvider("service","jabber:iq:browse",new Service());

OrFilter or2=new OrFilter(new PacketTypeFilter(Service.class),

new PacketIDFilter("browse1"));

PacketFilter filter = or2;

PacketCollector myCollector = connection.createPacketCollector(filter);

IQ browseiq=(IQ)myCollector.nextResult( 30000 );



Iterator i=browseiq.getPropertyNames();

DefaultListModel dlm=new DefaultListModel();

while(i.hasNext())

{

IQ iq1=browseiq;

String key=(String)i.next();

String value=(String)iq1.getProperty(key);

String[] server=value.split(":");

TransportAddresses.put(key,server[0]);

TransportInfo.put(key,server[1]);

if (key.equals("aim")||key.equals("icq")||key.equals("yahoo")||key.equals("msn"))

dlm.addElement(TransportAddresses.get(key));

}

ServicesList.setModel(dlm);

}

void Register_actionPerformed(ActionEvent e) {

setVisible( false );

wait = new WaitForm( parent, "Please Wait..." );

wait.setVisible( true );

Thread thread = new Thread( new RegisterThread() );

thread.start();

}

void Cancel_actionPerformed(ActionEvent e) {

this.dispose();

}

void ServicesList_valueChanged(ListSelectionEvent e) {

if (ServicesList.getSelectedIndex()==-1)

{

InfoPanel.setVisible(false);

return;

}

else

{

InfoPanel.setVisible(true);

GetRegistrationKey();

}

}

void GetRegKey()

{

Thread thread = new Thread( new GetRegistrationFormThread() );

thread.start();

}

void GetRegistrationKey()

{

String errorMessage=null;

Registration register = new Registration();

register.setType(IQ.Type.GET);

register.setTo( (String) ServicesList.getSelectedValue());

PacketFilter filter = new AndFilter(new PacketIDFilter(register.getPacketID()),

new PacketTypeFilter(IQ.class));



PacketCollector collector = parent.getConnection().createPacketCollector(

filter);

parent.getConnection().sendPacket(register);

IQ result = (IQ) collector.nextResult(20000);

if (result == null) {

errorMessage = "No response from server.";

}

else if (result.getType() == IQ.Type.ERROR) {

errorMessage = result.getError().getMessage();

if (errorMessage == null)

errorMessage = "Unknown Error";

}



if (errorMessage == null) {

Registration register1 = (Registration) result;



Map map = register1.getAttributes();



java.util.List list = new ArrayList(map.keySet());

Iterator iterator = list.iterator();



while (iterator.hasNext()) {

String key = (String) iterator.next();

String value = (String) map.get(key);

if (key.equals("key"))

regKey = value;

else if (key.equals("registered"))

JOptionPane.showMessageDialog(parent,

"You have already registered for this service"

, "Service Registration",

JOptionPane.INFORMATION_MESSAGE);

}

}

}

class GetRegistrationFormThread implements Runnable

{

private String errorMessage;



public void run()

{

Registration register = new Registration();

register.setType( IQ.Type.GET );

register.setTo( (String)ServicesList.getSelectedValue());

PacketFilter filter = new AndFilter( new PacketIDFilter( register.getPacketID() ),

new PacketTypeFilter( IQ.class ) );



PacketCollector collector = parent.getConnection().createPacketCollector( filter );

parent.getConnection().sendPacket( register );

IQ result = (IQ)collector.nextResult( 20000 );

if( result == null )

{

errorMessage = "No response from server.";

}

else if( result.getType() == IQ.Type.ERROR )

{

errorMessage = result.getError().getMessage();

if( errorMessage == null ) errorMessage = "Unknown Error";

}



if( errorMessage == null )

{

Registration register1 = (Registration)result;



Map map = register1.getAttributes();



java.util.List list = new ArrayList( map.keySet() );

Iterator iterator = list.iterator();



while( iterator.hasNext() )

{

String key = (String)iterator.next();

String value = (String)map.get( key );

if( key.equals( "key" ) ) regKey = value;

else if( key.equals( "registered" ) )

JOptionPane.showMessageDialog(parent,"You have already registered for this service"

,"Service Registration",JOptionPane.INFORMATION_MESSAGE);

}

}



SwingUtilities.invokeLater( new Runnable()

{

public void run()

{

if( errorMessage != null )

{

JOptionPane.showMessageDialog(parent,errorMessage

,"Service Registration",JOptionPane.ERROR_MESSAGE);

dispose();

}

else {

pack();

setLocationRelativeTo( null );

setVisible( true );

}

}

} );

}

}

class RegisterThread implements Runnable

{

private String errorMessage;



public void run()

{

Registration register = new Registration();

register.setType( IQ.Type.SET );

register.setTo( (String)ServicesList.getSelectedValue() );



TreeMap map = new TreeMap();

map.put( "key", regKey );



register.setUsername( AccountUsername.getText() );

map.put( "username", AccountUsername.getText() );

register.setPassword( String.valueOf(AccountPassword.getPassword()));

map.put( "password", String.valueOf(AccountPassword.getPassword()) );



register.setAttributes( map );

PacketFilter filter = new AndFilter( new PacketIDFilter( register.getPacketID() ),

new PacketTypeFilter( IQ.class ) );



PacketCollector collector = parent.getConnection().createPacketCollector( filter );



System.err.println("Send : "+register.toXML());

parent.getConnection().sendPacket( register );



IQ result = (IQ)collector.nextResult( 30000 );

wait.dispose();

System.err.println("Receive : "+result.toXML());

if( result == null )

{

errorMessage = "No response from server.";

}

else if( result.getType() == IQ.Type.ERROR )

{

errorMessage = result.getError().getMessage();

if( errorMessage == null ) errorMessage = "Unknown Error";

}



SwingUtilities.invokeLater( new Runnable()

{

public void run()

{

if( errorMessage != null )

{

JOptionPane.showMessageDialog(parent,errorMessage

,"Service Registration",JOptionPane.ERROR_MESSAGE);

dispose();

}

else {

JOptionPane.showMessageDialog(parent,"Registration Successful!"

,"Service Registration",JOptionPane.INFORMATION_MESSAGE);

dispose();

}

}

} );

}

}

}



class ServiceRegistrationForm_Register_actionAdapter implements java.awt.event.ActionListener {

ServiceRegistrationForm adaptee;



ServiceRegistrationForm_Register_actionAdapter(ServiceRegistrationForm adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.Register_actionPerformed(e);

}

}



class ServiceRegistrationForm_Cancel_actionAdapter implements java.awt.event.ActionListener {

ServiceRegistrationForm adaptee;



ServiceRegistrationForm_Cancel_actionAdapter(ServiceRegistrationForm adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.Cancel_actionPerformed(e);

}

}



class ServiceRegistrationForm_ServicesList_listSelectionAdapter implements

javax.swing.event.ListSelectionListener {

ServiceRegistrationForm adaptee;



ServiceRegistrationForm_ServicesList_listSelectionAdapter(ServiceRegistrationForm adaptee) {

this.adaptee = adaptee;

}

public void valueChanged(ListSelectionEvent e) {

adaptee.ServicesList_valueChanged(e);

}

}





#################################################################################



package jclient.com.forms;

import javax.swing.JFrame;

import java.util.Observer;

import javax.swing.*;

import java.awt.event.*;

import jclient.com.*;

import org.jivesoftware.smack.*;

import java.awt.*;



public class SimpleChatForm extends JDialog implements Observer{

JPanel panel1 = new JPanel();

JMenuBar ChatMenuBar = new JMenuBar();

JMenu jMenu1 = new JMenu();

JMenu jMenu2 = new JMenu();

JMenuItem jMenuItem1 = new JMenuItem();

JMenuItem jMenuItem2 = new JMenuItem();

JMenuItem jMenuItem3 = new JMenuItem();

JMenu jMenu3 = new JMenu();

JScrollPane jScrollPane1 = new JScrollPane();

JTextArea MessagesDisplayArea = new JTextArea();

JToolBar jToolBar1 = new JToolBar();

JScrollPane jScrollPane2 = new JScrollPane();

JTextArea MyMessage = new JTextArea();

JButton Send = new JButton();

JMenuItem CloseChatBox = new JMenuItem();

XMPPConnection connection;

Chat c=null;

GridBagLayout gridBagLayout1 = new GridBagLayout();

JClientFrame frame;

String name;

String friend;

MemberStatus buddy;

public SimpleChatForm(JClientFrame frame, MemberStatus m,String name,String user) {

super(frame,name,false);

try {

this.frame=frame;

this.connection=frame.getConnection();

this.name=name;

buddy=m;

friend=user;

jbInit();

setTitle(friend);

pack();

}

catch(Exception ex) {

ex.printStackTrace();

}

}



public SimpleChatForm() {

this(null, null, "","");

}

private void jbInit() throws Exception {

panel1.setLayout(gridBagLayout1);

jMenu1.setText("Menu");

jMenu2.setText("Edit");

jMenuItem1.setText("Cut");

jMenuItem2.setText("Paste");

jMenuItem3.setText("Copy");

jMenu3.setText("Help");

Send.setText("Send");

Send.addActionListener(new ChatForm_Send_actionAdapter(this));

this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

this.setJMenuBar(ChatMenuBar);

this.setResizable(false);

this.setTitle("");

CloseChatBox.setText("Close");

CloseChatBox.addActionListener(new ChatForm_CloseChatBox_actionAdapter(this));

MessagesDisplayArea.setDebugGraphicsOptions(0);

MessagesDisplayArea.setEditable(false);

MessagesDisplayArea.setText("");

MessagesDisplayArea.setLineWrap(true);

MessagesDisplayArea.setWrapStyleWord(false);

jScrollPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

jScrollPane1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

jScrollPane1.setAutoscrolls(true);

MyMessage.setLineWrap(true);

getContentPane().add(panel1);

panel1.add(jScrollPane1, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0

,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(1, 1, 0, 2), 0, 176));

panel1.add(jToolBar1, new GridBagConstraints(0, 1, 2, 1, 1.0, 0.0

,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0, 1, 0, 2), 387,

27));

panel1.add(jScrollPane2, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0

,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 1, 2, 0), 0, 50));

panel1.add(Send, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0

,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 6, 2, 2), 18, 44));

jScrollPane2.getViewport().add(MyMessage, null);

jScrollPane1.getViewport().add(MessagesDisplayArea, null);

ChatMenuBar.add(jMenu1);

ChatMenuBar.add(jMenu2);

ChatMenuBar.add(jMenu3);

jMenu2.add(jMenuItem3);

jMenu2.add(jMenuItem1);

jMenu2.add(jMenuItem2);

jMenu1.add(CloseChatBox);

frame.addObserver( this );

}



/**

* Closes this window if the parent window dies

**/

public void update( java.util.Observable o, Object obj )

{

this.setVisible( false );

dispose();

}

void CloseChatBox_actionPerformed(ActionEvent e) {

MessagesDisplayArea.setText("");

frame.getMemberStatus(friend).setConversation(null);

this.dispose();

}

void Send_actionPerformed(ActionEvent e) {

try {

c=frame.getConnection().createChat(friend);

c.sendMessage(MyMessage.getText());

MessagesDisplayArea.append(frame.getConnection().getUser()+":

"+MyMessage.getText().trim()+"\n");

MyMessage.setText("");

}

catch (XMPPException ex) {

MessagesDisplayArea.append("Error : "+ex+"\n");

}

}

public void signedOff()

{

MessagesDisplayArea.setForeground(Color.RED);

}



public void signedOn()

{

MessagesDisplayArea.setForeground(Color.BLACK);

}



public void recieveMessage( String message )

{

if (message!=null)

MessagesDisplayArea.append(friend+": " + message+"\n\r");

if( !isVisible() ) setVisible( true );

}

}



class ChatForm_CloseChatBox_actionAdapter implements java.awt.event.ActionListener {

SimpleChatForm adaptee;



ChatForm_CloseChatBox_actionAdapter(SimpleChatForm adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.CloseChatBox_actionPerformed(e);

}

}



class ChatForm_Send_actionAdapter implements java.awt.event.ActionListener {

SimpleChatForm adaptee;



ChatForm_Send_actionAdapter(SimpleChatForm adaptee) {

this.adaptee = adaptee;

}

public void actionPerformed(ActionEvent e) {

adaptee.Send_actionPerformed(e);

}

}



#################################################################################



package jclient.com.forms;

import java.awt.*;

import javax.swing.*;

import java.awt.event.*;



import jclient.com.*;

import java.util.*;



public class WaitForm extends JDialog implements Observer{

private JClientFrame buddiesList;



public WaitForm( JClientFrame buddiesList, String title, String string )

{

super( buddiesList, title, false );



JPanel panel = new JPanel( new BorderLayout() );

panel.setBorder( BorderFactory.createEmptyBorder( 30, 60, 30, 60 ) );

setContentPane( panel );



JLabel label = new JLabel( string );



panel.add( label, BorderLayout.CENTER );



pack();

setLocationRelativeTo( null );



addWindowListener( new WindowAdapter() {

public void windowClosing( WindowEvent e )

{

//do nothing

if( !isVisible() ) setVisible( true );

}

} );



if( buddiesList != null )

{

buddiesList.addObserver( this );

}



setResizable( false );

}



public void update( Observable obs, Object obj )

{

dispose();

}



public WaitForm( JClientFrame buddiesList, String string )

{

this( buddiesList, string, string );

}

}

#################################################################################



package jclient.com.threads;



import jclient.com.*;

import jclient.com.forms.*;

import javax.swing.*;

import org.jivesoftware.smack.*;

public class ConnectorThread implements Runnable {

private WaitForm waitform;

private String UserID;

private String Password;

private String ServerName;

private JClientFrame parent;

public ConnectorThread(JClientFrame parent,WaitForm waitform,String UserID,String Password,String

ServerName) {

this.parent=parent;

this.waitform=waitform;

this.UserID=UserID;

this.Password=Password;

this.ServerName=ServerName;

}

public void run() {

final XMPPConnection connection;

String errorMessage;

try {

connection = new XMPPConnection( ServerName,5222 );

String resource = "JClient";

if( resource == null || resource.equals( "" ) ) resource = "JClient";

connection.login( UserID, Password, resource );

SwingUtilities.invokeLater( new Runnable()

{

public void run()

{

waitform.setVisible( false );

if( System.getProperty( "debug" ) != null )

JOptionPane.showMessageDialog(parent,"Connected To Server.",

"Connection Established",JOptionPane.INFORMATION_MESSAGE);

parent.SetConnection(connection);

}

} );

parent.LoggedIn();

return;

}

catch( XMPPException e )

{

errorMessage = "";

if( e.getXMPPError() != null ) errorMessage = e.getXMPPError().getMessage();

else if( e.getMessage() != null ) errorMessage = e.getMessage();



if( errorMessage == null ) errorMessage = "An unkown connection error has occured.";



if( errorMessage.equals( "Unauthorized" ) )

errorMessage = new String( "You have entered and invalid username and/or password." );

waitform.setVisible( false );

JOptionPane.showMessageDialog(parent,"Could not connect : "+e.getMessage(),

"Connection Information",JOptionPane.ERROR_MESSAGE);

}



SwingUtilities.invokeLater( new Runnable()

{

public void run()

{

waitform.setVisible( false );

parent.ShowLoginForm();

}

} );

}



}



#################################################################################



package jclient.com.listeners;



import org.jivesoftware.smack.PacketListener;

import org.jivesoftware.smack.packet.*;

import jclient.com.*;



public class SmackIQPacketListener implements PacketListener

{

private JClientFrame buddiesList;



public SmackIQPacketListener( JClientFrame buddiesList ) { this.buddiesList = buddiesList; }



public void processPacket( Packet packet )

{

this.buddiesList = buddiesList;



IQ iq = (IQ)packet;

if( iq.getType() == IQ.Type.SET ) buddiesList.reloadBuddies();

}

}



#################################################################################



package jclient.com.listeners;



import org.jivesoftware.smack.*;

import org.jivesoftware.smack.packet.*;

import jclient.com.*;

import jclient.com.forms.*;

import java.util.*;

import java.util.regex.*;



/**

* Listens for a message packet, and sends it to the appropriate buddies

* conversation window. If the window does not exist a new window will be created

*

*/

public class SmackMessagePacketListener implements PacketListener

{

private JClientFrame buddiesList; //the calling buddy list

private TreeMap buddyStatuses; //all the available buddy statuses



//Constructor for the packet listener

public SmackMessagePacketListener( JClientFrame buddiesList )

{

this.buddiesList = buddiesList;

buddyStatuses = buddiesList.getMemberStatuses();

}



public void processPacket( Packet message )

{

Message packet = (Message)message;



if( packet.getType() != Message.Type.NORMAL && packet.getType() != Message.Type.CHAT

) return;



String from = packet.getFrom();



if( from != null )

{

from = from.replaceAll( "\\/.*", "" );



MemberStatus memberStatus = buddiesList.getMemberStatus( from );

boolean inList = true;



String user = "";

String server = "";



if( Pattern.matches( ".*@.*", from ) )

{



String parts[] = new String[2];

parts = from.split( "@" );

user = parts[0];

server = parts[1];

}

else {

user = from;

server = from;

}



RosterEntry entry = buddiesList.getConnection().getRoster().getEntry( from );

if( entry != null ) user = entry.getName();



if( memberStatus.getName() != null ) user = memberStatus.getName();

else user=from;

if(memberStatus.getConversation() == null )

memberStatus.setConversation( new SimpleChatForm( buddiesList, memberStatus,

user, from ) );



String messageBody = packet.getBody();

if (messageBody!=null)

memberStatus.getConversation().recieveMessage( messageBody );

}

}

}



#################################################################################



package jclient.com.listeners;



import java.util.*;

import java.util.regex.*;



import java.awt.*;

import java.awt.event.*;

import javax.swing.*;



import jclient.com.*;

import org.jivesoftware.smack.*;

import org.jivesoftware.smack.packet.*;



public class SmackPresencePacketListener implements PacketListener

{

private JClientFrame buddiesList;



public SmackPresencePacketListener( JClientFrame buddiesList )

{

this.buddiesList = buddiesList;

}



public void processPacket( Packet packet )

{

Presence presence = (Presence)packet;

String from = presence.getFrom();

String userId = from;

String sides[] = new String[2];



String resource = "N/A";



// if this message is not from the server, and not from a transport

if( Pattern.matches( ".*@.*", from ) && Pattern.matches( ".*\\/.*", from ) )

{

sides = from.split( "\\/" );



// get the resource

if( sides[1] != null )

{

resource = sides[1];

userId = sides[0];

}

}



// if they are trying to subscribe, as if we want to let them subscribe

if( presence.getType() == Presence.Type.SUBSCRIBE )

{

boolean add = true;

// find out if they are already in the roster

if( buddiesList.getConnection().getRoster().contains( userId ) ) add = false;

if( !Pattern.matches( ".*@.*", from ) ) add = false;

requestSubscription( userId, add );

return;

}



// dealing with Online or offline packets

if( presence.getType() != Presence.Type.AVAILABLE && presence.getType() !=

Presence.Type.UNAVAILABLE ) return;



MemberStatus buddy = buddiesList.getMemberStatus( userId );

performPresenceTasks( buddy, presence.getType() );



// if it's unavailable, check to see if they have any resources still online

// if they do, set the packet to available, and minus one resource

if( presence.getType() == Presence.Type.UNAVAILABLE )

{

buddy.remove( resource );

if( buddy.size() > 0 ) presence.setType( Presence.Type.AVAILABLE );

}

else

{

buddy.put( resource, new Integer( presence.getPriority() ) );

}



if( presence.getType() == Presence.Type.AVAILABLE ) buddy.setHasSignedOn( true );



buddy.setPresenceMode( presence.getMode() );

if( presence.getStatus() != null ) buddy.setStatusMessage( presence.getStatus() );



}



class ReloadHandler implements ActionListener

{

public void actionPerformed( ActionEvent e )

{

buddiesList.reloadBuddies();

}

}



public void performPresenceTasks(MemberStatus buddy, Presence.Type type )

{

if( buddy.getUserId().equals( buddiesList.getConnection().getUser().replaceAll( "\\/.*", "" ) ) )

return;



if( type == Presence.Type.AVAILABLE && buddy.size() Paths tab->Required Libraries tab. Here a reference to

the library can be set by clicking the add button.



Testing:

This software when run shows up the client for Jabber Server. Inorder to test it,

the user needs to be connected to the internet. He also needs to know the available public

Jabber servers. A good resource for this information is at www.jabber.org.

Note: Since Jabber technology is new and is yet to be realized in full. Not all public

servers are up and running. Some public servers don’t provide other service transport

agents. ‘amessage.info’ or ‘jabber.dk’ public servers are some which provide most of the

services.









Figure 1: Main Window Before Loging

Figure 2 : Menu









Figure 3 : Help menu

Logging In:









Figure 4: When the login menu item under Menu is clicked, it brings up the login screen









Figure 5: When an invalid server name is submitted

Figure 6: The result when the user submits a valid username/password/servername









Figure 7: Login Window

Figure 8: Menu Item for Registration after logging









Figure 9: Service Registration Window

Figure 10: Service Registration Form with information









Figure 11: Main window after Service Registration

Figure 12 : Main window after 'testing2003_2' logged in









Figure 13: Message from 'testing2003_2'

Figure 14: Message sent to 'testing2003_2'









Figure 15: New User Account









Figure 16: New User Greeting From Server

Figure 17: User Presence









Figure 18: After the user has changed his presence to 'Do Not Disturb'

Figure 19: After Logging in to Jabber.org









Figure 20: If no Services are available

Figure 21: When the Service Registration Menu item is clicked, the service registration form appears

with the available services.

Figure 22: When a service is selected, the service registration prompts for the service username and

password.









Figure 23: After successfully registering with a service.

Buddies Presence









Figure 24: Active / Online Members can be seen in bold font in the tree view.

Message Window









Figure 25: A sample chat window.





Logout

Figure 26: When the Logout option is selected, a confirmation window appears









Figure 27: After logging out successfully.

Future Implementations:

Since my primary goal in taking this project for this course is to study and

implement a distributed architecture system, I implemented the basic Instant messaging

system. The future implementations will include:

1. Voice Messaging.

2. Conference Chatting.

3. Better features like html content messaging, alerts etc.

4. Searching online users.

5. Finding out the count of online users in the system.



Lessons Learned:

The Jabber Software Foundation (JSF) can offer the world's best protocols for

instant messaging, presence, and near-real-time communication. This can be judged by its

simplicity, extensibility and its power.

As a developer of Jabber technology, I found that JSF (Jabber Software Foundation) has

offered us the technology to implement new things with the help of XMPP protocol.

XMPP is an open, XML-based protocol for near real-time extensible messaging and

presence. It is the core protocol of the Jabber Instant Messaging and Presence technology

which is currently being deployed on thousands of servers across the Internet and is being

used by millions of people worldwide.



Research:

My primary goal in building this Jabber Client was to essentially learn distributed

system architecture. I found that architecture in Jabber. I was able to learn it and

successfully implement a simplified messaging "application" that could handle chatting. I

designed the Jabber Client GUI such that it could be easy to use.



The Extensible Messaging and Presence Protocol (XMPP) is a protocol for

streaming XML elements in order to exchange messages and presence information in

close to real time. The core features of XMPP include -- mainly XML streams, use of

TLS and SASL, and the , , and children of the stream root -

- provide the building blocks for many types of near-real-time applications, which may be

layered on top of the core by sending application-specific data qualified by particular

XML namespaces. This XML fragment contains a URL that points to a location on a

content server. To reach out to external services -- notably authentication services --

Jabber makes available it’s XML Database Extension (XDB). XDB makes it possible to

validate and establish privileges for IM users. The information users want to share with

other IM users is stored in either an external SQL or LDAP database. The XDB

component works with the external database and communicates back to the Jabber server,

using standard XML.

Suggesion: Since this technology is an open source, it is hard to expect any good

documentation. Much of the protocol standards can be gathered from the IETF proposed

documents. None of the public servers are reliable. I found that these public servers aren’t

running all the time since they are still under development phase.

Conclusion:

The Jabber messaging framework is an example of P2P distributed environments

using XML technology. This framework includes its own communications protocol and

server architecture and is based on the concept of switching XML document content

between multiple locations. All messages in Jabber framework, including instant message

content, presence changes, and configuration updates, are delivered as XML fragments.

This forms the critical ingredient in peer-to-peer information sharing schemes, including

grid computing, instant messaging, and Web services. This project explored the cutting-

edge efforts intended to create a unified P2P fabric based on adaptations of existing XML

technology. Considering the low cost of hardware and that the technology is effectively

free, a full implementation of Jabber has the potential to make a positive impact on a

network for a minimal outlay. If significant improvements are made in some areas, it may

well be the future of Instant Messaging.



Bibliography:

1. JSF, “Jabber Protocol”,

URL#http://www.jabber.org/ietf/

2. Peter Saint-Andre, “JEP-0078: Non SASL authentication”,

URL#http://www.jabber.org/jeps/jep-0078.html

3. Jive Software, “Smack API”,

URL#http://www.jivesoftware.com/xmpp/smack/api/

4. Patrick Chan, “The Java Developers Almanac 1.4”,

URL#http://javaalmanac.com/egs/javax.swing.tree/AddNode.html

5. Sun Microsystems, “How to use trees?”,

URL#http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html

6. Smack Library Forum,

URL#http://www.jivesoftware.com/jive/forum.jspa?forumID=39

7. Ana Orubeondo, “Blind to brand name”, InfoWorld (August 24, 2001).


Shared by: jianghongl
Other docs by jianghongl
“Well Seasoned CHEFS”
Views: 15  |  Downloads: 0
“PREZ
Views: 8  |  Downloads: 0
“GENERATION G”
Views: 8  |  Downloads: 0
“Cooking Class Venues”
Views: 15  |  Downloads: 0
“Bundle” of Joy
Views: 11  |  Downloads: 0
Related docs