mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-09-10 17:49:38 +02:00
Phase 1 of large refactoring. Removing dead code, bug fixes, updates to JDK 1.5.
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@4511 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
1a08715f67
commit
bbbfe09c31
62 changed files with 291 additions and 3524 deletions
|
@ -1,353 +0,0 @@
|
|||
/**
|
||||
* $RCSfile$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
* Copyright 2003-2004 Jive Software.
|
||||
*
|
||||
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.filter.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A GroupChat is a conversation that takes place among many users in a virtual
|
||||
* room. When joining a group chat, you specify a nickname, which is the identity
|
||||
* that other chat room users see.
|
||||
*
|
||||
* @see XMPPConnection#createGroupChat(String)
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public class GroupChat {
|
||||
|
||||
private XMPPConnection connection;
|
||||
private String room;
|
||||
private String nickname = null;
|
||||
private boolean joined = false;
|
||||
private List participants = new ArrayList();
|
||||
private List connectionListeners = new ArrayList();
|
||||
|
||||
private PacketFilter presenceFilter;
|
||||
private PacketFilter messageFilter;
|
||||
private PacketCollector messageCollector;
|
||||
|
||||
/**
|
||||
* Creates a new group chat with the specified connection and room name. Note: no
|
||||
* information is sent to or received from the server until you attempt to
|
||||
* {@link #join(String) join} the chat room. On some server implementations,
|
||||
* the room will not be created until the first person joins it.<p>
|
||||
*
|
||||
* Most XMPP servers use a sub-domain for the chat service (eg chat.example.com
|
||||
* for the XMPP server example.com). You must ensure that the room address you're
|
||||
* trying to connect to includes the proper chat sub-domain.
|
||||
*
|
||||
* @param connection the XMPP connection.
|
||||
* @param room the name of the room in the form "roomName@service", where
|
||||
* "service" is the hostname at which the multi-user chat
|
||||
* service is running.
|
||||
*/
|
||||
public GroupChat(XMPPConnection connection, String room) {
|
||||
this.connection = connection;
|
||||
this.room = room;
|
||||
// Create a collector for all incoming messages.
|
||||
messageFilter = new AndFilter(new FromContainsFilter(room),
|
||||
new PacketTypeFilter(Message.class));
|
||||
messageFilter = new AndFilter(messageFilter, new PacketFilter() {
|
||||
public boolean accept(Packet packet) {
|
||||
Message msg = (Message)packet;
|
||||
return msg.getType() == Message.Type.GROUP_CHAT;
|
||||
}
|
||||
});
|
||||
messageCollector = connection.createPacketCollector(messageFilter);
|
||||
// Create a listener for all presence updates.
|
||||
presenceFilter = new AndFilter(new FromContainsFilter(room),
|
||||
new PacketTypeFilter(Presence.class));
|
||||
connection.addPacketListener(new PacketListener() {
|
||||
public void processPacket(Packet packet) {
|
||||
Presence presence = (Presence)packet;
|
||||
String from = presence.getFrom();
|
||||
if (presence.getType() == Presence.Type.AVAILABLE) {
|
||||
synchronized (participants) {
|
||||
if (!participants.contains(from)) {
|
||||
participants.add(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (presence.getType() == Presence.Type.UNAVAILABLE) {
|
||||
synchronized (participants) {
|
||||
participants.remove(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, presenceFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the room this GroupChat object represents.
|
||||
*
|
||||
* @return the groupchat room name.
|
||||
*/
|
||||
public String getRoom() {
|
||||
return room;
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins the chat room using the specified nickname. If already joined
|
||||
* using another nickname, this method will first leave the room and then
|
||||
* re-join using the new nickname. The default timeout of 5 seconds for a reply
|
||||
* from the group chat server that the join succeeded will be used.
|
||||
*
|
||||
* @param nickname the nickname to use.
|
||||
* @throws XMPPException if an error occurs joining the room. In particular, a
|
||||
* 409 error can occur if someone is already in the group chat with the same
|
||||
* nickname.
|
||||
*/
|
||||
public synchronized void join(String nickname) throws XMPPException {
|
||||
join(nickname, SmackConfiguration.getPacketReplyTimeout());
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins the chat room using the specified nickname. If already joined as
|
||||
* another nickname, will leave as that name first before joining under the new
|
||||
* name.
|
||||
*
|
||||
* @param nickname the nickname to use.
|
||||
* @param timeout the number of milleseconds to wait for a reply from the
|
||||
* group chat that joining the room succeeded.
|
||||
* @throws XMPPException if an error occurs joining the room. In particular, a
|
||||
* 409 error can occur if someone is already in the group chat with the same
|
||||
* nickname.
|
||||
*/
|
||||
public synchronized void join(String nickname, long timeout) throws XMPPException {
|
||||
if (nickname == null || nickname.equals("")) {
|
||||
throw new IllegalArgumentException("Nickname must not be null or blank.");
|
||||
}
|
||||
// If we've already joined the room, leave it before joining under a new
|
||||
// nickname.
|
||||
if (joined) {
|
||||
leave();
|
||||
}
|
||||
// We join a room by sending a presence packet where the "to"
|
||||
// field is in the form "roomName@service/nickname"
|
||||
Presence joinPresence = new Presence(Presence.Type.AVAILABLE);
|
||||
joinPresence.setTo(room + "/" + nickname);
|
||||
// Wait for a presence packet back from the server.
|
||||
PacketFilter responseFilter = new AndFilter(
|
||||
new FromContainsFilter(room + "/" + nickname),
|
||||
new PacketTypeFilter(Presence.class));
|
||||
PacketCollector response = connection.createPacketCollector(responseFilter);
|
||||
// Send join packet.
|
||||
connection.sendPacket(joinPresence);
|
||||
// Wait up to a certain number of seconds for a reply.
|
||||
Presence presence = (Presence)response.nextResult(timeout);
|
||||
response.cancel();
|
||||
if (presence == null) {
|
||||
throw new XMPPException("No response from server.");
|
||||
}
|
||||
else if (presence.getError() != null) {
|
||||
throw new XMPPException(presence.getError());
|
||||
}
|
||||
this.nickname = nickname;
|
||||
joined = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if currently in the group chat (after calling the {@link
|
||||
* #join(String)} method.
|
||||
*
|
||||
* @return true if currently in the group chat room.
|
||||
*/
|
||||
public boolean isJoined() {
|
||||
return joined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leave the chat room.
|
||||
*/
|
||||
public synchronized void leave() {
|
||||
// If not joined already, do nothing.
|
||||
if (!joined) {
|
||||
return;
|
||||
}
|
||||
// We leave a room by sending a presence packet where the "to"
|
||||
// field is in the form "roomName@service/nickname"
|
||||
Presence leavePresence = new Presence(Presence.Type.UNAVAILABLE);
|
||||
leavePresence.setTo(room + "/" + nickname);
|
||||
connection.sendPacket(leavePresence);
|
||||
// Reset participant information.
|
||||
participants = new ArrayList();
|
||||
nickname = null;
|
||||
joined = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nickname that was used to join the room, or <tt>null</tt> if not
|
||||
* currently joined.
|
||||
*
|
||||
* @return the nickname currently being used.
|
||||
*/
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of participants in the group chat.<p>
|
||||
*
|
||||
* Note: this value will only be accurate after joining the group chat, and
|
||||
* may fluctuate over time. If you query this value directly after joining the
|
||||
* group chat it may not be accurate, as it takes a certain amount of time for
|
||||
* the server to send all presence packets to this client.
|
||||
*
|
||||
* @return the number of participants in the group chat.
|
||||
*/
|
||||
public int getParticipantCount() {
|
||||
synchronized (participants) {
|
||||
return participants.size();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator (of Strings) for the list of fully qualified participants
|
||||
* in the group chat. For example, "conference@chat.jivesoftware.com/SomeUser".
|
||||
* Typically, a client would only display the nickname of the participant. To
|
||||
* get the nickname from the fully qualified name, use the
|
||||
* {@link org.jivesoftware.smack.util.StringUtils#parseResource(String)} method.
|
||||
* Note: this value will only be accurate after joining the group chat, and may
|
||||
* fluctuate over time.
|
||||
*
|
||||
* @return an Iterator for the participants in the group chat.
|
||||
*/
|
||||
public Iterator getParticipants() {
|
||||
synchronized (participants) {
|
||||
return Collections.unmodifiableList(new ArrayList(participants)).iterator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a packet listener that will be notified of any new Presence packets
|
||||
* sent to the group chat. Using a listener is a suitable way to know when the list
|
||||
* of participants should be re-loaded due to any changes.
|
||||
*
|
||||
* @param listener a packet listener that will be notified of any presence packets
|
||||
* sent to the group chat.
|
||||
*/
|
||||
public void addParticipantListener(PacketListener listener) {
|
||||
connection.addPacketListener(listener, presenceFilter);
|
||||
connectionListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to the chat room.
|
||||
*
|
||||
* @param text the text of the message to send.
|
||||
* @throws XMPPException if sending the message fails.
|
||||
*/
|
||||
public void sendMessage(String text) throws XMPPException {
|
||||
Message message = new Message(room, Message.Type.GROUP_CHAT);
|
||||
message.setBody(text);
|
||||
connection.sendPacket(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Message to send to the chat room.
|
||||
*
|
||||
* @return a new Message addressed to the chat room.
|
||||
*/
|
||||
public Message createMessage() {
|
||||
return new Message(room, Message.Type.GROUP_CHAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a Message to the chat room.
|
||||
*
|
||||
* @param message the message.
|
||||
* @throws XMPPException if sending the message fails.
|
||||
*/
|
||||
public void sendMessage(Message message) throws XMPPException {
|
||||
connection.sendPacket(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Polls for and returns the next message, or <tt>null</tt> if there isn't
|
||||
* a message immediately available. This method provides significantly different
|
||||
* functionalty than the {@link #nextMessage()} method since it's non-blocking.
|
||||
* In other words, the method call will always return immediately, whereas the
|
||||
* nextMessage method will return only when a message is available (or after
|
||||
* a specific timeout).
|
||||
*
|
||||
* @return the next message if one is immediately available and
|
||||
* <tt>null</tt> otherwise.
|
||||
*/
|
||||
public Message pollMessage() {
|
||||
return (Message)messageCollector.pollResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next available message in the chat. The method call will block
|
||||
* (not return) until a message is available.
|
||||
*
|
||||
* @return the next message.
|
||||
*/
|
||||
public Message nextMessage() {
|
||||
return (Message)messageCollector.nextResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next available message in the chat. The method call will block
|
||||
* (not return) until a packet is available or the <tt>timeout</tt> has elapased.
|
||||
* If the timeout elapses without a result, <tt>null</tt> will be returned.
|
||||
*
|
||||
* @param timeout the maximum amount of time to wait for the next message.
|
||||
* @return the next message, or <tt>null</tt> if the timeout elapses without a
|
||||
* message becoming available.
|
||||
*/
|
||||
public Message nextMessage(long timeout) {
|
||||
return (Message)messageCollector.nextResult(timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a packet listener that will be notified of any new messages in the
|
||||
* group chat. Only "group chat" messages addressed to this group chat will
|
||||
* be delivered to the listener. If you wish to listen for other packets
|
||||
* that may be associated with this group chat, you should register a
|
||||
* PacketListener directly with the XMPPConnection with the appropriate
|
||||
* PacketListener.
|
||||
*
|
||||
* @param listener a packet listener.
|
||||
*/
|
||||
public void addMessageListener(PacketListener listener) {
|
||||
connection.addPacketListener(listener, messageFilter);
|
||||
connectionListeners.add(listener);
|
||||
}
|
||||
|
||||
public void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
try {
|
||||
if (messageCollector != null) {
|
||||
messageCollector.cancel();
|
||||
}
|
||||
// Remove all the PacketListeners added to the connection by this GroupChat
|
||||
for (Iterator it=connectionListeners.iterator(); it.hasNext();) {
|
||||
connection.removePacketListener((PacketListener) it.next());
|
||||
}
|
||||
}
|
||||
catch (Exception e) {}
|
||||
}
|
||||
}
|
|
@ -135,17 +135,34 @@ public class PacketCollector {
|
|||
public synchronized Packet nextResult(long timeout) {
|
||||
// Wait up to the specified amount of time for a result.
|
||||
if (resultQueue.isEmpty()) {
|
||||
long waitTime = timeout;
|
||||
long start = System.currentTimeMillis();
|
||||
try {
|
||||
wait(timeout);
|
||||
// Keep waiting until the specified amount of time has elapsed, or
|
||||
// a packet is available to return.
|
||||
while (resultQueue.isEmpty()) {
|
||||
if (waitTime <= 0) {
|
||||
break;
|
||||
}
|
||||
wait(waitTime);
|
||||
long now = System.currentTimeMillis();
|
||||
waitTime -= (now - start);
|
||||
start = now;
|
||||
}
|
||||
}
|
||||
catch (InterruptedException ie) {
|
||||
// Ignore.
|
||||
}
|
||||
// Still haven't found a result, so return null.
|
||||
if (resultQueue.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
// Return the packet that was found.
|
||||
else {
|
||||
return (Packet)resultQueue.removeLast();
|
||||
}
|
||||
}
|
||||
// If still no result, return null.
|
||||
if (resultQueue.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
// There's already a packet waiting, so return it.
|
||||
else {
|
||||
return (Packet)resultQueue.removeLast();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.jivesoftware.smack.filter.*;
|
|||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Represents a user's roster, which is the collection of users a person receives
|
||||
|
@ -68,10 +69,10 @@ public class Roster {
|
|||
private static int defaultSubscriptionMode = SUBSCRIPTION_ACCEPT_ALL;
|
||||
|
||||
private XMPPConnection connection;
|
||||
private Map groups;
|
||||
private Map<String,RosterGroup> groups;
|
||||
private List entries;
|
||||
private List unfiledEntries;
|
||||
private List rosterListeners;
|
||||
private List<RosterListener> rosterListeners;
|
||||
private Map presenceMap;
|
||||
// The roster is marked as initialized when at least a single roster packet
|
||||
// has been recieved and processed.
|
||||
|
@ -110,10 +111,10 @@ public class Roster {
|
|||
*/
|
||||
Roster(final XMPPConnection connection) {
|
||||
this.connection = connection;
|
||||
groups = new Hashtable();
|
||||
groups = new ConcurrentHashMap<String,RosterGroup>();
|
||||
unfiledEntries = new ArrayList();
|
||||
entries = new ArrayList();
|
||||
rosterListeners = new ArrayList();
|
||||
rosterListeners = new ArrayList<RosterListener>();
|
||||
presenceMap = new HashMap();
|
||||
// Listen for any roster packets.
|
||||
PacketFilter rosterFilter = new PacketTypeFilter(RosterPacket.class);
|
||||
|
@ -130,7 +131,7 @@ public class Roster {
|
|||
*
|
||||
* If using the manual mode, a PacketListener should be registered that
|
||||
* listens for Presence packets that have a type of
|
||||
* {@link org.jivesoftware.smack.packet.Presence.Type#SUBSCRIBE}.
|
||||
* {@link org.jivesoftware.smack.packet.Presence.Type#subscribe}.
|
||||
*
|
||||
* @return the subscription mode.
|
||||
*/
|
||||
|
@ -145,7 +146,7 @@ public class Roster {
|
|||
*
|
||||
* If using the manual mode, a PacketListener should be registered that
|
||||
* listens for Presence packets that have a type of
|
||||
* {@link org.jivesoftware.smack.packet.Presence.Type#SUBSCRIBE}.
|
||||
* {@link org.jivesoftware.smack.packet.Presence.Type#subscribe}.
|
||||
*
|
||||
* @param subscriptionMode the subscription mode.
|
||||
*/
|
||||
|
@ -251,7 +252,7 @@ public class Roster {
|
|||
}
|
||||
|
||||
// Create a presence subscription packet and send.
|
||||
Presence presencePacket = new Presence(Presence.Type.SUBSCRIBE);
|
||||
Presence presencePacket = new Presence(Presence.Type.subscribe);
|
||||
presencePacket.setTo(user);
|
||||
connection.sendPacket(presencePacket);
|
||||
}
|
||||
|
@ -291,7 +292,7 @@ public class Roster {
|
|||
throw new XMPPException(response.getError());
|
||||
}
|
||||
else {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,42 +302,26 @@ public class Roster {
|
|||
* @return the number of entries in the roster.
|
||||
*/
|
||||
public int getEntryCount() {
|
||||
HashMap entryMap = new HashMap();
|
||||
// Loop through all roster groups.
|
||||
for (Iterator groups = getGroups(); groups.hasNext(); ) {
|
||||
RosterGroup rosterGroup = (RosterGroup) groups.next();
|
||||
for (Iterator entries = rosterGroup.getEntries(); entries.hasNext(); ) {
|
||||
entryMap.put(entries.next(), "");
|
||||
}
|
||||
}
|
||||
synchronized (unfiledEntries) {
|
||||
return entryMap.size() + unfiledEntries.size();
|
||||
}
|
||||
return getEntries().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all entries in the roster, including entries that don't belong to
|
||||
* any groups.
|
||||
* Returns an unmodifiable collection of all entries in the roster, including entries
|
||||
* that don't belong to any groups.
|
||||
*
|
||||
* @return all entries in the roster.
|
||||
*/
|
||||
public Iterator getEntries() {
|
||||
ArrayList allEntries = new ArrayList();
|
||||
public Collection<RosterEntry> getEntries() {
|
||||
Set<RosterEntry> allEntries = new HashSet<RosterEntry>();
|
||||
// Loop through all roster groups and add their entries to the answer
|
||||
for (Iterator groups = getGroups(); groups.hasNext(); ) {
|
||||
RosterGroup rosterGroup = (RosterGroup) groups.next();
|
||||
for (Iterator entries = rosterGroup.getEntries(); entries.hasNext(); ) {
|
||||
RosterEntry entry = (RosterEntry)entries.next();
|
||||
if (!allEntries.contains(entry)) {
|
||||
allEntries.add(entry);
|
||||
}
|
||||
}
|
||||
for (RosterGroup rosterGroup: getGroups()) {
|
||||
allEntries.addAll(rosterGroup.getEntries());
|
||||
}
|
||||
// Add the roster unfiled entries to the answer
|
||||
synchronized (unfiledEntries) {
|
||||
allEntries.addAll(unfiledEntries);
|
||||
}
|
||||
return allEntries.iterator();
|
||||
return Collections.unmodifiableCollection(allEntries);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -406,9 +391,7 @@ public class Roster {
|
|||
* @return the roster group with the specified name.
|
||||
*/
|
||||
public RosterGroup getGroup(String name) {
|
||||
synchronized (groups) {
|
||||
return (RosterGroup)groups.get(name);
|
||||
}
|
||||
return groups.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -417,21 +400,16 @@ public class Roster {
|
|||
* @return the number of groups in the roster.
|
||||
*/
|
||||
public int getGroupCount() {
|
||||
synchronized (groups) {
|
||||
return groups.size();
|
||||
}
|
||||
return groups.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator the for all the roster groups.
|
||||
* Returns an unmodiable collections of all the roster groups.
|
||||
*
|
||||
* @return an iterator for all roster groups.
|
||||
*/
|
||||
public Iterator getGroups() {
|
||||
synchronized (groups) {
|
||||
List groupsList = Collections.unmodifiableList(new ArrayList(groups.values()));
|
||||
return groupsList.iterator();
|
||||
}
|
||||
public Collection<RosterGroup> getGroups() {
|
||||
return Collections.unmodifiableCollection(groups.values());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -483,7 +461,7 @@ public class Roster {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns the presence info for a particular user's resource, or <tt>null</tt> if the user
|
||||
* is unavailable (offline) or if no presence information is available, such as
|
||||
* when you are not subscribed to the user's presence updates.
|
||||
|
@ -603,7 +581,7 @@ public class Roster {
|
|||
|
||||
// If an "available" packet, add it to the presence map. Each presence map will hold
|
||||
// for a particular user a map with the presence packets saved for each resource.
|
||||
if (presence.getType() == Presence.Type.AVAILABLE) {
|
||||
if (presence.getType() == Presence.Type.available) {
|
||||
Map userPresences;
|
||||
// Get the user presence map
|
||||
if (presenceMap.get(key) == null) {
|
||||
|
@ -628,7 +606,7 @@ public class Roster {
|
|||
}
|
||||
}
|
||||
// If an "unavailable" packet, remove any entries in the presence map.
|
||||
else if (presence.getType() == Presence.Type.UNAVAILABLE) {
|
||||
else if (presence.getType() == Presence.Type.unavailable) {
|
||||
if (presenceMap.get(key) != null) {
|
||||
Map userPresences = (Map) presenceMap.get(key);
|
||||
synchronized (userPresences) {
|
||||
|
@ -648,27 +626,27 @@ public class Roster {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (presence.getType() == Presence.Type.SUBSCRIBE) {
|
||||
else if (presence.getType() == Presence.Type.subscribe) {
|
||||
if (subscriptionMode == SUBSCRIPTION_ACCEPT_ALL) {
|
||||
// Accept all subscription requests.
|
||||
Presence response = new Presence(Presence.Type.SUBSCRIBED);
|
||||
Presence response = new Presence(Presence.Type.subscribed);
|
||||
response.setTo(presence.getFrom());
|
||||
connection.sendPacket(response);
|
||||
}
|
||||
else if (subscriptionMode == SUBSCRIPTION_REJECT_ALL) {
|
||||
// Reject all subscription requests.
|
||||
Presence response = new Presence(Presence.Type.UNSUBSCRIBED);
|
||||
Presence response = new Presence(Presence.Type.unsubscribed);
|
||||
response.setTo(presence.getFrom());
|
||||
connection.sendPacket(response);
|
||||
}
|
||||
// Otherwise, in manual mode so ignore.
|
||||
}
|
||||
else if (presence.getType() == Presence.Type.UNSUBSCRIBE) {
|
||||
else if (presence.getType() == Presence.Type.unsubscribe) {
|
||||
if (subscriptionMode != SUBSCRIPTION_MANUAL) {
|
||||
// Acknowledge and accept unsubscription notification so that the
|
||||
// server will stop sending notifications saying that the contact
|
||||
// has unsubscribed to our presence.
|
||||
Presence response = new Presence(Presence.Type.UNSUBSCRIBED);
|
||||
Presence response = new Presence(Presence.Type.unsubscribed);
|
||||
response.setTo(presence.getFrom());
|
||||
connection.sendPacket(response);
|
||||
}
|
||||
|
@ -690,8 +668,7 @@ public class Roster {
|
|||
Collection deletedEntries = new ArrayList();
|
||||
|
||||
RosterPacket rosterPacket = (RosterPacket)packet;
|
||||
for (Iterator i=rosterPacket.getRosterItems(); i.hasNext(); ) {
|
||||
RosterPacket.Item item = (RosterPacket.Item)i.next();
|
||||
for (RosterPacket.Item item : rosterPacket.getRosterItems()) {
|
||||
RosterEntry entry = new RosterEntry(item.getUser(), item.getName(),
|
||||
item.getItemType(), item.getItemStatus(), connection);
|
||||
|
||||
|
@ -733,7 +710,7 @@ public class Roster {
|
|||
}
|
||||
// If the roster entry belongs to any groups, remove it from the
|
||||
// list of unfiled entries.
|
||||
if (item.getGroupNames().hasNext()) {
|
||||
if (!item.getGroupNames().isEmpty()) {
|
||||
synchronized (unfiledEntries) {
|
||||
unfiledEntries.remove(entry);
|
||||
}
|
||||
|
@ -749,18 +726,16 @@ public class Roster {
|
|||
}
|
||||
|
||||
// Find the list of groups that the user currently belongs to.
|
||||
List currentGroupNames = new ArrayList();
|
||||
for (Iterator j = entry.getGroups(); j.hasNext(); ) {
|
||||
RosterGroup group = (RosterGroup)j.next();
|
||||
currentGroupNames.add(group.getName());
|
||||
List<String> currentGroupNames = new ArrayList<String>();
|
||||
for (RosterGroup rosterGroup : entry.getGroups()) {
|
||||
currentGroupNames.add(rosterGroup.getName());
|
||||
}
|
||||
|
||||
// If the packet is not of the type REMOVE then add the entry to the groups
|
||||
if (!RosterPacket.ItemType.REMOVE.equals(item.getItemType())) {
|
||||
// Create the new list of groups the user belongs to.
|
||||
List newGroupNames = new ArrayList();
|
||||
for (Iterator k = item.getGroupNames(); k.hasNext(); ) {
|
||||
String groupName = (String)k.next();
|
||||
List<String> newGroupNames = new ArrayList<String>();
|
||||
for (String groupName : item.getGroupNames()) {
|
||||
// Add the group name to the list.
|
||||
newGroupNames.add(groupName);
|
||||
|
||||
|
@ -798,12 +773,9 @@ public class Roster {
|
|||
// RosterGroup.removeEntry removes the entry immediately (locally) and the
|
||||
// group could remain empty.
|
||||
// TODO Check the performance/logic for rosters with large number of groups
|
||||
for (Iterator it = getGroups(); it.hasNext();) {
|
||||
RosterGroup group = (RosterGroup)it.next();
|
||||
for (RosterGroup group : getGroups()) {
|
||||
if (group.getEntryCount() == 0) {
|
||||
synchronized (groups) {
|
||||
groups.remove(group.getName());
|
||||
}
|
||||
groups.remove(group.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,21 +106,20 @@ public class RosterEntry {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator for all the roster groups that this entry belongs to.
|
||||
* Returns an unmodifiable collection of the roster groups that this entry belongs to.
|
||||
*
|
||||
* @return an iterator for the groups this entry belongs to.
|
||||
*/
|
||||
public Iterator getGroups() {
|
||||
List results = new ArrayList();
|
||||
public Collection<RosterGroup> getGroups() {
|
||||
List<RosterGroup> results = new ArrayList<RosterGroup>();
|
||||
// Loop through all roster groups and find the ones that contain this
|
||||
// entry. This algorithm should be fine
|
||||
for (Iterator i=connection.roster.getGroups(); i.hasNext(); ) {
|
||||
RosterGroup group = (RosterGroup)i.next();
|
||||
for (RosterGroup group: connection.roster.getGroups()) {
|
||||
if (group.contains(this)) {
|
||||
results.add(group);
|
||||
}
|
||||
}
|
||||
return results.iterator();
|
||||
return Collections.unmodifiableCollection(results);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -152,14 +151,15 @@ public class RosterEntry {
|
|||
buf.append(name).append(": ");
|
||||
}
|
||||
buf.append(user);
|
||||
Iterator groups = getGroups();
|
||||
if (groups.hasNext()) {
|
||||
Collection<RosterGroup> groups = getGroups();
|
||||
if (!groups.isEmpty()) {
|
||||
buf.append(" [");
|
||||
RosterGroup group = (RosterGroup)groups.next();
|
||||
Iterator<RosterGroup> iter = groups.iterator();
|
||||
RosterGroup group = iter.next();
|
||||
buf.append(group.getName());
|
||||
while (groups.hasNext()) {
|
||||
while (iter.hasNext()) {
|
||||
buf.append(", ");
|
||||
group = (RosterGroup)groups.next();
|
||||
group = iter.next();
|
||||
buf.append(group.getName());
|
||||
}
|
||||
buf.append("]");
|
||||
|
@ -184,8 +184,7 @@ public class RosterEntry {
|
|||
item.setItemType(entry.getType());
|
||||
item.setItemStatus(entry.getStatus());
|
||||
// Set the correct group names for the item.
|
||||
for (Iterator j=entry.getGroups(); j.hasNext(); ) {
|
||||
RosterGroup group = (RosterGroup)j.next();
|
||||
for (RosterGroup group : entry.getGroups()) {
|
||||
item.addGroupName(group.getName());
|
||||
}
|
||||
return item;
|
||||
|
|
|
@ -37,7 +37,7 @@ public class RosterGroup {
|
|||
|
||||
private String name;
|
||||
private XMPPConnection connection;
|
||||
private List entries;
|
||||
private List<RosterEntry> entries;
|
||||
|
||||
/**
|
||||
* Creates a new roster group instance.
|
||||
|
@ -48,7 +48,7 @@ public class RosterGroup {
|
|||
RosterGroup(String name, XMPPConnection connection) {
|
||||
this.name = name;
|
||||
this.connection = connection;
|
||||
entries = new ArrayList();
|
||||
entries = new ArrayList<RosterEntry>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,13 +95,13 @@ public class RosterGroup {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator for the entries in the group.
|
||||
* Returns an unmodifiable collection of all entries in the group.
|
||||
*
|
||||
* @return an iterator for the entries in the group.
|
||||
* @return all entries in the group.
|
||||
*/
|
||||
public Iterator getEntries() {
|
||||
public Collection<RosterEntry> getEntries() {
|
||||
synchronized (entries) {
|
||||
return Collections.unmodifiableList(new ArrayList(entries)).iterator();
|
||||
return Collections.unmodifiableList(new ArrayList<RosterEntry>(entries));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -454,7 +454,7 @@ public class XMPPConnection {
|
|||
|
||||
// Set presence to online.
|
||||
if (sendPresence) {
|
||||
packetWriter.sendPacket(new Presence(Presence.Type.AVAILABLE));
|
||||
packetWriter.sendPacket(new Presence(Presence.Type.available));
|
||||
}
|
||||
|
||||
// Indicate that we're now authenticated.
|
||||
|
@ -512,7 +512,7 @@ public class XMPPConnection {
|
|||
roster = null;
|
||||
|
||||
// Set presence to online.
|
||||
packetWriter.sendPacket(new Presence(Presence.Type.AVAILABLE));
|
||||
packetWriter.sendPacket(new Presence(Presence.Type.available));
|
||||
|
||||
// Indicate that we're now authenticated.
|
||||
authenticated = true;
|
||||
|
@ -595,24 +595,6 @@ public class XMPPConnection {
|
|||
return new Chat(this, participant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new group chat connected to the specified room. The room name
|
||||
* should be full address, such as <tt>room@chat.example.com</tt>.
|
||||
* <p>
|
||||
* Most XMPP servers use a sub-domain for the chat service (eg chat.example.com
|
||||
* for the XMPP server example.com). You must ensure that the room address you're
|
||||
* trying to connect to includes the proper chat sub-domain.
|
||||
*
|
||||
* @param room the fully qualifed name of the room.
|
||||
* @return a new GroupChat object.
|
||||
*/
|
||||
public GroupChat createGroupChat(String room) {
|
||||
if (!isConnected()) {
|
||||
throw new IllegalStateException("Not connected to server.");
|
||||
}
|
||||
return new GroupChat(this, room);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if currently connected to the XMPP server.
|
||||
*
|
||||
|
@ -656,7 +638,7 @@ public class XMPPConnection {
|
|||
*/
|
||||
public void close() {
|
||||
// Set presence to offline.
|
||||
packetWriter.sendPacket(new Presence(Presence.Type.UNAVAILABLE));
|
||||
packetWriter.sendPacket(new Presence(Presence.Type.unavailable));
|
||||
packetReader.shutdown();
|
||||
packetWriter.shutdown();
|
||||
// Wait 150 ms for processes to clean-up, then shutdown.
|
||||
|
|
|
@ -26,16 +26,16 @@ import org.jivesoftware.smack.util.StringUtils;
|
|||
* Represents XMPP presence packets. Every presence packet has a type, which is one of
|
||||
* the following values:
|
||||
* <ul>
|
||||
* <li><tt>Presence.Type.AVAILABLE</tt> -- (Default) indicates the user is available to
|
||||
* <li>{@link Presence.Type#available available} -- (Default) indicates the user is available to
|
||||
* receive messages.
|
||||
* <li><tt>Presence.Type.UNAVAILABLE</tt> -- the user is unavailable to receive messages.
|
||||
* <li><tt>Presence.Type.SUBSCRIBE</tt> -- request subscription to recipient's presence.
|
||||
* <li><tt>Presence.Type.SUBSCRIBED</tt> -- grant subscription to sender's presence.
|
||||
* <li><tt>Presence.Type.UNSUBSCRIBE</tt> -- request removal of subscription to sender's
|
||||
* presence.
|
||||
* <li><tt>Presence.Type.UNSUBSCRIBED</tt> -- grant removal of subscription to sender's
|
||||
* presence.
|
||||
* <li><tt>Presence.Type.ERROR</tt> -- the presence packet contains an error message.
|
||||
* <li>{@link Presence.Type#unavailable unavailable} -- the user is unavailable to receive messages.
|
||||
* <li>{@link Presence.Type#subscribe subscribe} -- request subscription to recipient's presence.
|
||||
* <li>{@link Presence.Type#subscribed subscribed} -- grant subscription to sender's presence.
|
||||
* <li>{@link Presence.Type#unsubscribe unsubscribe} -- request removal of subscription to
|
||||
* sender's presence.
|
||||
* <li>{@link Presence.Type#unsubscribed unsubscribed} -- grant removal of subscription to
|
||||
* sender's presence.
|
||||
* <li>{@link Presence.Type#error error} -- the presence packet contains an error message.
|
||||
* </ul><p>
|
||||
*
|
||||
* A number of attributes are optional:
|
||||
|
@ -44,8 +44,9 @@ import org.jivesoftware.smack.util.StringUtils;
|
|||
* <li>Priority -- non-negative numerical priority of a sender's resource. The
|
||||
* highest resource priority is the default recipient of packets not addressed
|
||||
* to a particular resource.
|
||||
* <li>Mode -- one of five presence modes: available (the default), chat, away,
|
||||
* xa (extended away, and dnd (do not disturb).
|
||||
* <li>Mode -- one of five presence modes: {@link Mode#available available} (the default),
|
||||
* {@link Mode#chat chat}, {@link Mode#away away}, {@link Mode#xa xa} (extended away), and
|
||||
* {@link Mode#dnd dnd} (do not disturb).
|
||||
* </ul><p>
|
||||
*
|
||||
* Presence packets are used for two purposes. First, to notify the server of our
|
||||
|
@ -57,10 +58,10 @@ import org.jivesoftware.smack.util.StringUtils;
|
|||
*/
|
||||
public class Presence extends Packet {
|
||||
|
||||
private Type type = Type.AVAILABLE;
|
||||
private Type type = Type.available;
|
||||
private String status = null;
|
||||
private int priority = -1;
|
||||
private Mode mode = Mode.AVAILABLE;
|
||||
private Mode mode = Mode.available;
|
||||
|
||||
/**
|
||||
* Creates a new presence update. Status, priority, and mode are left un-set.
|
||||
|
@ -179,7 +180,7 @@ public class Presence extends Packet {
|
|||
if (getFrom() != null) {
|
||||
buf.append(" from=\"").append(StringUtils.escapeForXML(getFrom())).append("\"");
|
||||
}
|
||||
if (type != Type.AVAILABLE) {
|
||||
if (type != Type.available) {
|
||||
buf.append(" type=\"").append(type).append("\"");
|
||||
}
|
||||
buf.append(">");
|
||||
|
@ -189,7 +190,7 @@ public class Presence extends Packet {
|
|||
if (priority != -1) {
|
||||
buf.append("<priority>").append(priority).append("</priority>");
|
||||
}
|
||||
if (mode != null && mode != Mode.AVAILABLE) {
|
||||
if (mode != null && mode != Mode.available) {
|
||||
buf.append("<show>").append(mode).append("</show>");
|
||||
}
|
||||
|
||||
|
@ -219,105 +220,78 @@ public class Presence extends Packet {
|
|||
}
|
||||
|
||||
/**
|
||||
* A typsafe enum class to represent the presecence type.
|
||||
* A enum to represent the presecence type. Not that presence type is often confused
|
||||
* with presence mode. Generally, if a user is signed into a server, they have a presence
|
||||
* type of {@link #available available}, even if the mode is {@link Mode#away away},
|
||||
* {@link Mode#dnd dnd}, etc. The presence type is only {@link #unavailable unavailable} when
|
||||
* the user is signing out of the server.
|
||||
*/
|
||||
public static class Type {
|
||||
public enum Type {
|
||||
|
||||
public static final Type AVAILABLE = new Type("available");
|
||||
public static final Type UNAVAILABLE = new Type("unavailable");
|
||||
public static final Type SUBSCRIBE = new Type("subscribe");
|
||||
public static final Type SUBSCRIBED = new Type("subscribed");
|
||||
public static final Type UNSUBSCRIBE = new Type("unsubscribe");
|
||||
public static final Type UNSUBSCRIBED = new Type("unsubscribed");
|
||||
public static final Type ERROR = new Type("error");
|
||||
|
||||
private String value;
|
||||
|
||||
private Type(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* The user is available to receive messages (default).
|
||||
*/
|
||||
available,
|
||||
|
||||
/**
|
||||
* Returns the type constant associated with the String value.
|
||||
* The user is unavailable to receive messages.
|
||||
*/
|
||||
public static Type fromString(String value) {
|
||||
if (value == null) {
|
||||
return AVAILABLE;
|
||||
}
|
||||
value = value.toLowerCase();
|
||||
if ("unavailable".equals(value)) {
|
||||
return UNAVAILABLE;
|
||||
}
|
||||
else if ("subscribe".equals(value)) {
|
||||
return SUBSCRIBE;
|
||||
}
|
||||
else if ("subscribed".equals(value)) {
|
||||
return SUBSCRIBED;
|
||||
}
|
||||
else if ("unsubscribe".equals(value)) {
|
||||
return UNSUBSCRIBE;
|
||||
}
|
||||
else if ("unsubscribed".equals(value)) {
|
||||
return UNSUBSCRIBED;
|
||||
}
|
||||
else if ("error".equals(value)) {
|
||||
return ERROR;
|
||||
}
|
||||
// Default to available.
|
||||
else {
|
||||
return AVAILABLE;
|
||||
}
|
||||
}
|
||||
unavailable,
|
||||
|
||||
/**
|
||||
* Request subscription to recipient's presence.
|
||||
*/
|
||||
subscribe,
|
||||
|
||||
/**
|
||||
* Grant subscription to sender's presence.
|
||||
*/
|
||||
subscribed,
|
||||
|
||||
/**
|
||||
* Request removal of subscription to sender's presence.
|
||||
*/
|
||||
unsubscribe,
|
||||
|
||||
/**
|
||||
* Grant removal of subscription to sender's presence.
|
||||
*/
|
||||
unsubscribed,
|
||||
|
||||
/**
|
||||
* The presence packet contains an error message.
|
||||
*/
|
||||
error
|
||||
}
|
||||
|
||||
/**
|
||||
* A typsafe enum class to represent the presence mode.
|
||||
* An enum to represent the presence mode.
|
||||
*/
|
||||
public static class Mode {
|
||||
|
||||
public static final Mode AVAILABLE = new Mode("available");
|
||||
public static final Mode CHAT = new Mode("chat");
|
||||
public static final Mode AWAY = new Mode("away");
|
||||
public static final Mode EXTENDED_AWAY = new Mode("xa");
|
||||
public static final Mode DO_NOT_DISTURB = new Mode("dnd");
|
||||
|
||||
private String value;
|
||||
|
||||
private Mode(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
public enum Mode {
|
||||
|
||||
/**
|
||||
* Returns the mode constant associated with the String value.
|
||||
* Available (the default).
|
||||
*/
|
||||
public static Mode fromString(String value) {
|
||||
if (value == null) {
|
||||
return AVAILABLE;
|
||||
}
|
||||
value = value.toLowerCase();
|
||||
if (value.equals("chat")) {
|
||||
return CHAT;
|
||||
}
|
||||
else if (value.equals("away")) {
|
||||
return AWAY;
|
||||
}
|
||||
else if (value.equals("xa")) {
|
||||
return EXTENDED_AWAY;
|
||||
}
|
||||
else if (value.equals("dnd")) {
|
||||
return DO_NOT_DISTURB;
|
||||
}
|
||||
else {
|
||||
return AVAILABLE;
|
||||
}
|
||||
}
|
||||
available,
|
||||
|
||||
/**
|
||||
* Free to chat.
|
||||
*/
|
||||
chat,
|
||||
|
||||
/**
|
||||
* Away.
|
||||
*/
|
||||
away,
|
||||
|
||||
/**
|
||||
* Away for an extended period of time.
|
||||
*/
|
||||
xa,
|
||||
|
||||
/**
|
||||
* Do not disturb.
|
||||
*/
|
||||
dnd
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ package org.jivesoftware.smack.packet;
|
|||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
/**
|
||||
* Represents XMPP roster packets.
|
||||
|
@ -31,7 +32,7 @@ import java.util.*;
|
|||
*/
|
||||
public class RosterPacket extends IQ {
|
||||
|
||||
private final List rosterItems = new ArrayList();
|
||||
private final List<Item> rosterItems = new ArrayList<Item>();
|
||||
|
||||
/**
|
||||
* Adds a roster item to the packet.
|
||||
|
@ -56,14 +57,13 @@ public class RosterPacket extends IQ {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the roster items in the packet.
|
||||
* Returns an unmodifiable collection for the roster items in the packet.
|
||||
*
|
||||
* @return and Iterator for the roster items in the packet.
|
||||
* @return an unmodifiable collection for the roster items in the packet.
|
||||
*/
|
||||
public Iterator getRosterItems() {
|
||||
public Collection<Item> getRosterItems() {
|
||||
synchronized (rosterItems) {
|
||||
List entries = Collections.unmodifiableList(new ArrayList(rosterItems));
|
||||
return entries.iterator();
|
||||
return Collections.unmodifiableList(new ArrayList<Item>(rosterItems));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,8 +71,7 @@ public class RosterPacket extends IQ {
|
|||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<query xmlns=\"jabber:iq:roster\">");
|
||||
synchronized (rosterItems) {
|
||||
for (int i=0; i<rosterItems.size(); i++) {
|
||||
Item entry = (Item)rosterItems.get(i);
|
||||
for (Item entry : rosterItems) {
|
||||
buf.append(entry.toXML());
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +89,7 @@ public class RosterPacket extends IQ {
|
|||
private String name;
|
||||
private ItemType itemType;
|
||||
private ItemStatus itemStatus;
|
||||
private final List groupNames;
|
||||
private final Set<String> groupNames;
|
||||
|
||||
/**
|
||||
* Creates a new roster item.
|
||||
|
@ -103,7 +102,7 @@ public class RosterPacket extends IQ {
|
|||
this.name = name;
|
||||
itemType = null;
|
||||
itemStatus = null;
|
||||
groupNames = new ArrayList();
|
||||
groupNames = new CopyOnWriteArraySet<String>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -170,15 +169,13 @@ public class RosterPacket extends IQ {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator for the group names (as Strings) that the roster item
|
||||
* Returns an unmodifiable set of the group names that the roster item
|
||||
* belongs to.
|
||||
*
|
||||
* @return an Iterator for the group names.
|
||||
* @return an unmodifiable set of the group names.
|
||||
*/
|
||||
public Iterator getGroupNames() {
|
||||
synchronized (groupNames) {
|
||||
return Collections.unmodifiableList(groupNames).iterator();
|
||||
}
|
||||
public Set<String> getGroupNames() {
|
||||
return Collections.unmodifiableSet(groupNames);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -187,11 +184,7 @@ public class RosterPacket extends IQ {
|
|||
* @param groupName the group name.
|
||||
*/
|
||||
public void addGroupName(String groupName) {
|
||||
synchronized (groupNames) {
|
||||
if (!groupNames.contains(groupName)) {
|
||||
groupNames.add(groupName);
|
||||
}
|
||||
}
|
||||
groupNames.add(groupName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -200,9 +193,7 @@ public class RosterPacket extends IQ {
|
|||
* @param groupName the group name.
|
||||
*/
|
||||
public void removeGroupName(String groupName) {
|
||||
synchronized (groupNames) {
|
||||
groupNames.remove(groupName);
|
||||
}
|
||||
groupNames.remove(groupName);
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
|
@ -218,11 +209,8 @@ public class RosterPacket extends IQ {
|
|||
buf.append(" ask=\"").append(itemStatus).append("\"");
|
||||
}
|
||||
buf.append(">");
|
||||
synchronized (groupNames) {
|
||||
for (int i=0; i<groupNames.size(); i++) {
|
||||
String groupName = (String)groupNames.get(i);
|
||||
buf.append("<group>").append(StringUtils.escapeForXML(groupName)).append("</group>");
|
||||
}
|
||||
for (String groupName : groupNames) {
|
||||
buf.append("<group>").append(StringUtils.escapeForXML(groupName)).append("</group>");
|
||||
}
|
||||
buf.append("</item>");
|
||||
return buf.toString();
|
||||
|
|
|
@ -131,7 +131,16 @@ public class PacketParserUtils {
|
|||
* @throws Exception if an exception occurs while parsing the packet.
|
||||
*/
|
||||
public static Presence parsePresence(XmlPullParser parser) throws Exception {
|
||||
Presence.Type type = Presence.Type.fromString(parser.getAttributeValue("", "type"));
|
||||
Presence.Type type = Presence.Type.available;
|
||||
String typeString = parser.getAttributeValue("", "type");
|
||||
if (typeString != null && !typeString.equals("")) {
|
||||
try {
|
||||
type = Presence.Type.valueOf(typeString);
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
System.err.println("Found invalid presence type " + typeString);
|
||||
}
|
||||
}
|
||||
|
||||
Presence presence = new Presence(type);
|
||||
presence.setTo(parser.getAttributeValue("", "to"));
|
||||
|
@ -154,14 +163,22 @@ public class PacketParserUtils {
|
|||
int priority = Integer.parseInt(parser.nextText());
|
||||
presence.setPriority(priority);
|
||||
}
|
||||
catch (NumberFormatException nfe) { }
|
||||
catch (NumberFormatException nfe) {
|
||||
// Ignore.
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
// Presence priority is out of range so assume priority to be zero
|
||||
presence.setPriority(0);
|
||||
}
|
||||
}
|
||||
else if (elementName.equals("show")) {
|
||||
presence.setMode(Presence.Mode.fromString(parser.nextText()));
|
||||
String modeText = parser.nextText();
|
||||
try {
|
||||
presence.setMode(Presence.Mode.valueOf(modeText));
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
System.err.println("Found invalid presence mode " + modeText);
|
||||
}
|
||||
}
|
||||
else if (elementName.equals("error")) {
|
||||
presence.setError(parseError(parser));
|
||||
|
|
|
@ -129,8 +129,9 @@ public class RosterExchangeManager {
|
|||
Message msg = new Message(targetUserID);
|
||||
// Create a RosterExchange Package and add it to the message
|
||||
RosterExchange rosterExchange = new RosterExchange();
|
||||
for (Iterator it = rosterGroup.getEntries(); it.hasNext();)
|
||||
rosterExchange.addRosterEntry((RosterEntry) it.next());
|
||||
for (RosterEntry entry : rosterGroup.getEntries()) {
|
||||
rosterExchange.addRosterEntry(entry);
|
||||
}
|
||||
msg.addExtension(rosterExchange);
|
||||
|
||||
// Send the message that contains the roster
|
||||
|
|
|
@ -47,7 +47,7 @@ public class DeafOccupantInterceptor implements PacketInterceptor {
|
|||
public void interceptPacket(Packet packet) {
|
||||
Presence presence = (Presence) packet;
|
||||
// Check if user is joining a room
|
||||
if (Presence.Type.AVAILABLE == presence.getType() &&
|
||||
if (Presence.Type.available == presence.getType() &&
|
||||
presence.getExtension("x", "http://jabber.org/protocol/muc") != null) {
|
||||
// Add extension that indicates that user wants to be a deaf occupant
|
||||
packet.addExtension(new DeafExtension());
|
||||
|
|
|
@ -291,7 +291,7 @@ public class MultiUserChat {
|
|||
}
|
||||
// We create a room by sending a presence packet to room@service/nick
|
||||
// and signal support for MUC. The owner will be automatically logged into the room.
|
||||
Presence joinPresence = new Presence(Presence.Type.AVAILABLE);
|
||||
Presence joinPresence = new Presence(Presence.Type.available);
|
||||
joinPresence.setTo(room + "/" + nickname);
|
||||
// Indicate the the client supports MUC
|
||||
joinPresence.addExtension(new MUCInitialPresence());
|
||||
|
@ -422,7 +422,7 @@ public class MultiUserChat {
|
|||
}
|
||||
// We join a room by sending a presence packet where the "to"
|
||||
// field is in the form "roomName@service/nickname"
|
||||
Presence joinPresence = new Presence(Presence.Type.AVAILABLE);
|
||||
Presence joinPresence = new Presence(Presence.Type.available);
|
||||
joinPresence.setTo(room + "/" + nickname);
|
||||
|
||||
// Indicate the the client supports MUC
|
||||
|
@ -484,7 +484,7 @@ public class MultiUserChat {
|
|||
}
|
||||
// We leave a room by sending a presence packet where the "to"
|
||||
// field is in the form "roomName@service/nickname"
|
||||
Presence leavePresence = new Presence(Presence.Type.UNAVAILABLE);
|
||||
Presence leavePresence = new Presence(Presence.Type.unavailable);
|
||||
leavePresence.setTo(room + "/" + nickname);
|
||||
// Invoke presence interceptors so that extra information can be dynamically added
|
||||
for (Iterator it = presenceInterceptors.iterator(); it.hasNext();) {
|
||||
|
@ -944,7 +944,7 @@ public class MultiUserChat {
|
|||
// We change the nickname by sending a presence packet where the "to"
|
||||
// field is in the form "roomName@service/nickname"
|
||||
// We don't have to signal the MUC support again
|
||||
Presence joinPresence = new Presence(Presence.Type.AVAILABLE);
|
||||
Presence joinPresence = new Presence(Presence.Type.available);
|
||||
joinPresence.setTo(room + "/" + nickname);
|
||||
// Invoke presence interceptors so that extra information can be dynamically added
|
||||
for (Iterator it = presenceInterceptors.iterator(); it.hasNext();) {
|
||||
|
@ -995,7 +995,7 @@ public class MultiUserChat {
|
|||
}
|
||||
// We change the availability status by sending a presence packet to the room with the
|
||||
// new presence status and mode
|
||||
Presence joinPresence = new Presence(Presence.Type.AVAILABLE);
|
||||
Presence joinPresence = new Presence(Presence.Type.available);
|
||||
joinPresence.setStatus(status);
|
||||
joinPresence.setMode(mode);
|
||||
joinPresence.setTo(room + "/" + nickname);
|
||||
|
@ -2112,7 +2112,7 @@ public class MultiUserChat {
|
|||
String from = presence.getFrom();
|
||||
String myRoomJID = room + "/" + nickname;
|
||||
boolean isUserStatusModification = presence.getFrom().equals(myRoomJID);
|
||||
if (presence.getType() == Presence.Type.AVAILABLE) {
|
||||
if (presence.getType() == Presence.Type.available) {
|
||||
Presence oldPresence;
|
||||
synchronized (occupantsMap) {
|
||||
oldPresence = (Presence)occupantsMap.get(from);
|
||||
|
@ -2145,7 +2145,7 @@ public class MultiUserChat {
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (presence.getType() == Presence.Type.UNAVAILABLE) {
|
||||
else if (presence.getType() == Presence.Type.unavailable) {
|
||||
synchronized (occupantsMap) {
|
||||
occupantsMap.remove(from);
|
||||
}
|
||||
|
|
|
@ -64,8 +64,8 @@ public class RosterExchange implements PacketExtension {
|
|||
*/
|
||||
public RosterExchange(Roster roster) {
|
||||
// Add all the roster entries to the new RosterExchange
|
||||
for (Iterator rosterEntries = roster.getEntries(); rosterEntries.hasNext();) {
|
||||
this.addRosterEntry((RosterEntry) rosterEntries.next());
|
||||
for (RosterEntry rosterEntry : roster.getEntries()) {
|
||||
this.addRosterEntry(rosterEntry);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,15 +76,16 @@ public class RosterExchange implements PacketExtension {
|
|||
*/
|
||||
public void addRosterEntry(RosterEntry rosterEntry) {
|
||||
// Obtain a String[] from the roster entry groups name
|
||||
ArrayList groupNamesList = new ArrayList();
|
||||
List<String> groupNamesList = new ArrayList<String>();
|
||||
String[] groupNames;
|
||||
for (Iterator groups = rosterEntry.getGroups(); groups.hasNext();) {
|
||||
groupNamesList.add(((RosterGroup) groups.next()).getName());
|
||||
for (RosterGroup group : rosterEntry.getGroups()) {
|
||||
groupNamesList.add(group.getName());
|
||||
}
|
||||
groupNames = (String[]) groupNamesList.toArray(new String[groupNamesList.size()]);
|
||||
groupNames = groupNamesList.toArray(new String[groupNamesList.size()]);
|
||||
|
||||
// Create a new Entry based on the rosterEntry and add it to the packet
|
||||
RemoteRosterEntry remoteRosterEntry = new RemoteRosterEntry(rosterEntry.getUser(), rosterEntry.getName(), groupNames);
|
||||
RemoteRosterEntry remoteRosterEntry = new RemoteRosterEntry(rosterEntry.getUser(),
|
||||
rosterEntry.getName(), groupNames);
|
||||
|
||||
addRosterEntry(remoteRosterEntry);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue