/**
*
* OLAT - Online Learning and Training
* http://www.olat.org
*
* This software is protected by the OLAT software license.
* Use is subject to license terms.
* See LICENSE.TXT in this distribution for details.
*
* Copyright (c) 2003 OLAT Zentrum, University of Zurich, Switzerland.
* All rights reserved.
*
* Description:
* TODO: Class Description for JabberClientSmack
*
*
* @version $Revision: 1.2 $
* Initial Date: 14.10.2004
* Last modified: $Date: 2004/10/18 12:43:49 $
*
* @author guido
*/
package org.olat.instantMessaging;
import java.util.ArrayList;
import java.util.List;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.RosterPacket;
/**
* @author guido
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class InstantMessagingClient {
// username is olat global unique username
private String username = null;
//password is auto generated and only used for instant messaging
private String password = null;
private XMPPConnection connection = null;
private Roster roster = null;
// null means 'not connected'
private Presence.Mode status = null;
private Message message = null;
// the jabber id like username@olat.ch
private String jid = null;
private static final String JABBERSERVER = "localhost";
private List subscribedUsers = new ArrayList();
protected static final String OLATBUDDIES = "OLAT-Buddies";
private boolean collaborationDisabled = false;
/**
*
* @param username
* @param password
*/
public InstantMessagingClient(String username, String password) {
this.username = username;
this.password = password;
connect();
}
/**
* connect to the JabberServer
*
*/
public void connect() {
try {
XMPPConnection.DEBUG_ENABLED = false;
connection = new XMPPConnection(JABBERSERVER);
connection.login(username, password);
roster = connection.getRoster();
//subscription accept all = 0
roster.setSubscriptionMode(0);
setStatus(Presence.Mode.AVAILABLE);
addMessageListener();
addSubscriptionListener();
} catch (XMPPException e) {
// TODO Auto-generated catch block
//Fragen: Was machen wir mit den Exceptions, mail, redscreen oder meldung auf gui?
e.printStackTrace();
}
}
/**
* change jabber status.
* Example: sendPresencePacket(Presence.Type.AVAILABLE, req.getParameter("status"), 1, Presence.Mode.AWAY);
* @param type
* @param status
* @param priority
* @param mode
*
*/
public void sendPresence(Presence.Type type, String status, int priority, Presence.Mode mode){
Presence presence = new Presence(type);
if (status == null){
status = "TODO, default statusmeldug fuer jeden mode";
presence.setStatus(status);
}else{
presence.setStatus(status);
}
presence.setPriority(priority);
if (mode != null)
presence.setMode(mode);
connection.sendPacket(presence);
}
Presence getPresence(){
return null;
}
/**
* Each client listens to it's own messages
*
*/
private void addMessageListener(){
PacketFilter filter = new PacketTypeFilter(Message.class);
PacketCollector myCollector = connection.createPacketCollector(filter);
PacketListener myListener = new PacketListener() {
public void processPacket(Packet packet) {
Message jabbmessage = (Message)packet;
if(jabbmessage.getType() == Message.Type.CHAT || jabbmessage.getType() == Message.Type.NORMAL)
if(!collaborationDisabled){
message = jabbmessage;
}else message = null;
}
};
connection.addPacketListener(myListener, filter);
}
/**
* By adding this methode (right now added to the contructor) we do
* have auto subscription. All subscribe packets get automatically
* answered by a subscribed packet.
*/
private void addSubscriptionListener(){
PacketFilter filter = new PacketTypeFilter(Presence.class);
PacketCollector myCollector = connection.createPacketCollector(filter);
PacketListener myListener = new PacketListener() {
public void processPacket(Packet packet) {
Presence presence = (Presence)packet;
if(presence.getType() == Presence.Type.SUBSCRIBE){
Presence response = new Presence(Presence.Type.SUBSCRIBED);
response.setTo(presence.getFrom());
System.out.println("subscribed to: "+presence.getFrom());
connection.sendPacket(response);
//ask also for subscription
if(!subscribedUsers.contains(presence.getFrom())){
response = null;
response = new Presence(Presence.Type.SUBSCRIBE);
response.setTo(presence.getFrom());
connection.sendPacket(response);
//update the roster with the new user
RosterPacket rosterPacket = new RosterPacket();
RosterPacket.Item item = new RosterPacket.Item(presence.getFrom(),parseName(presence.getFrom()));
item.addGroupName(OLATBUDDIES);
item.setItemType(RosterPacket.ItemType.BOTH);
//item.setItemStatus(RosterPacket.ItemStatus.fromString());
rosterPacket.addRosterItem(item);
connection.sendPacket(rosterPacket);
}
}
if(presence.getType() == Presence.Type.SUBSCRIBED){
subscribedUsers.add(presence.getFrom());
}
}
};
connection.addPacketListener(myListener, filter);
}
/**
* For unsubscription we have to create a packet like:
*
*
*
*
*
* @param String a valid jid like guido@jabber.org
*/
public void removeSubscription(String username){
RosterPacket rosterPacket = new RosterPacket();
rosterPacket.setType(IQ.Type.SET);
RosterPacket.Item item = new RosterPacket.Item(username+"@"+JABBERSERVER,parseName(jid));
item.setItemType(RosterPacket.ItemType.REMOVE);
rosterPacket.addRosterItem(item);
connection.sendPacket(rosterPacket);
}
/**
*
* @return message
*/
public Message getMessage(){
return this.message;
}
/**
* reset the message object
* users do this after reading a message in olat
*/
public void resetMessage(){
this.message = null;
}
/**
* @return Returns the jid.
*/
public String getJid() {
String jid = this.username+"@"+JABBERSERVER;
return jid;
}
/**
* @return Returns the status.
*/
public Presence.Mode getStatus() {
return status;
}
/**
* @param status The status to set.
*/
public void setStatus(Presence.Mode status) {
this.status = status;
}
/**
* Used for communication with the flash jabber client.
* May gets replaced with javascript to flash communication
* @param chatpartner
* @param message
*/
public void sendChatParamsToFlashClient(String chatpartner, String message){
StringBuffer out = new StringBuffer();
out.append("chatpartner:");
out.append(chatpartner);
out.append(",");
out.append("message:"+message);
sendCustomMessagePacket(out.toString());
}
public void sendConferenceParamsToFlashClient(String roomName){
String roomname = "chatroom:"+roomName;
sendCustomMessagePacket(roomname);
}
/**
* On OpenIm on the windows plattform, der type headline wird automatisch nach
* chat gewcheselt durch den server, grrrr. Wie sieht es unter jabberd aus?
* @param body of the custom message
*/
private void sendCustomMessagePacket(String msgBody){
//Chat chat = connection.createChat(olatUsername+"@"+JABBERHOST+"/xiff");
//Message customMsg = chat.createMessage();
Message customMsg = new Message();
//custom messages are sent only to our flash client with ressource /xiff
customMsg.setTo(username+"@"+JABBERSERVER+"/xiff");
customMsg.setType(Message.Type.HEADLINE);
customMsg.setBody(msgBody);
System.out.println("Custom message: "+customMsg.toXML());
connection.sendPacket(customMsg);
}
/**
* @return Returns the roster.
*/
public Roster getRoster() {
return roster;
}
/**
* Close the connection to the server
*
*/
public void closeConnection(){
connection.close();
}
/**
* Ask an other online user to subscribe to their roster
* @param username
*/
public void subscribeToUser(String username){
Presence presence = new Presence(Presence.Type.SUBSCRIBE);
presence.setTo(username+"@"+JABBERSERVER);
connection.sendPacket(presence);
}
/**
* @param an jabber jid like guido@swissjabber.org
* @return returns just the name "guido" without the rest
*/
private String parseName(String XMPPAddress) {
if (XMPPAddress == null) {
return null;
}
int atIndex = XMPPAddress.indexOf("@");
if (atIndex <= 0) {
return "";
}
else {
return XMPPAddress.substring(0, atIndex);
}
}
/**
*
* @param reason The reason why this user is not allowd to chat e.g. doing test
* By setting the third param to 10 all messages should be send to
* this client even if other clients are up. So we have full control over them.
*/
public void disableCollaboration(String reason){
sendPresence(Presence.Type.AVAILABLE, reason, 10, Presence.Mode.DO_NOT_DISTURB);
collaborationDisabled = true;
}
public void enableCollaboration(){
collaborationDisabled = false;
}
}