/** *
 * 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; } }