Commit 4e8859c4 authored by Matt Tucker's avatar Matt Tucker Committed by matt

Partial refactoring of moving to Whack packets. CVS will be broken until refactoring is complete.


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@569 b35dd754-fafc-0310-a699-88a17e54d16e
parent 80ea3382
...@@ -233,6 +233,8 @@ ...@@ -233,6 +233,8 @@
<root url="jar://$PROJECT_DIR$/build/lib/merge/standard.jar!/" /> <root url="jar://$PROJECT_DIR$/build/lib/merge/standard.jar!/" />
<root url="jar://$PROJECT_DIR$/build/lib/merge/jstl.jar!/" /> <root url="jar://$PROJECT_DIR$/build/lib/merge/jstl.jar!/" />
<root url="jar://$PROJECT_DIR$/build/lib/whack.jar!/" /> <root url="jar://$PROJECT_DIR$/build/lib/whack.jar!/" />
<root url="jar://$PROJECT_DIR$/build/lib/merge/whack.jar!/" />
<root url="jar://$PROJECT_DIR$/build/lib/merge/jdic.jar!/" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES />
......
...@@ -14,6 +14,7 @@ package org.jivesoftware.messenger; ...@@ -14,6 +14,7 @@ package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.xmpp.packet.Packet;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
...@@ -38,7 +39,7 @@ import java.util.concurrent.LinkedBlockingQueue; ...@@ -38,7 +39,7 @@ import java.util.concurrent.LinkedBlockingQueue;
* *
* @author Matt Tucker * @author Matt Tucker
*/ */
public class Channel<T extends XMPPPacket> { public class Channel<T extends Packet> {
private String name; private String name;
private ChannelHandler channelHandler; private ChannelHandler channelHandler;
...@@ -83,6 +84,7 @@ public class Channel<T extends XMPPPacket> { ...@@ -83,6 +84,7 @@ public class Channel<T extends XMPPPacket> {
catch (Exception e) { catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e); Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
try { try {
packet.getOriginatingSession().getConnection().close(); packet.getOriginatingSession().getConnection().close();
} }
catch (UnauthorizedException e1) { catch (UnauthorizedException e1) {
......
...@@ -12,13 +12,14 @@ ...@@ -12,13 +12,14 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.Packet;
/** /**
* Interface to handle packets delivered by Channels. * Interface to handle packets delivered by Channels.
* *
* @author Matt Tucker * @author Matt Tucker
*/ */
public interface ChannelHandler<T extends XMPPPacket> { public interface ChannelHandler<T extends Packet> {
/** /**
* Process an XMPP packet. * Process an XMPP packet.
......
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.xmpp.packet.Packet;
public interface Component { public interface Component {
void processPacket(XMPPPacket packet); void processPacket(Packet packet);
} }
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import java.io.StringReader;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.container.ServiceLookupFactory; import org.jivesoftware.messenger.container.ServiceLookupFactory;
import org.jivesoftware.messenger.spi.PacketFactoryImpl;
import org.jivesoftware.messenger.spi.PacketRouterImpl; import org.jivesoftware.messenger.spi.PacketRouterImpl;
import org.jivesoftware.messenger.spi.PresenceImpl;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils; import org.jivesoftware.util.StringUtils;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
/** /**
* <p>Manages the registration and delegation of Components.</p> * <p>Manages the registration and delegation of Components.</p>
...@@ -29,7 +23,7 @@ import org.xmpp.packet.Packet; ...@@ -29,7 +23,7 @@ import org.xmpp.packet.Packet;
public class ComponentManager { public class ComponentManager {
private Map<String, Component> components = new ConcurrentHashMap<String, Component>(); private Map<String, Component> components = new ConcurrentHashMap<String, Component>();
private Map<XMPPAddress, XMPPAddress> presenceMap = new ConcurrentHashMap<XMPPAddress, XMPPAddress>(); private Map<JID, JID> presenceMap = new ConcurrentHashMap<JID, JID>();
static private ComponentManager singleton; static private ComponentManager singleton;
private final static Object LOCK = new Object(); private final static Object LOCK = new Object();
...@@ -110,7 +104,7 @@ public class ComponentManager { ...@@ -110,7 +104,7 @@ public class ComponentManager {
* @param prober the jid probing. * @param prober the jid probing.
* @param probee the presence being probed. * @param probee the presence being probed.
*/ */
public void addPresenceRequest(XMPPAddress prober, XMPPAddress probee) { public void addPresenceRequest(JID prober, JID probee) {
presenceMap.put(prober, probee); presenceMap.put(prober, probee);
} }
...@@ -120,7 +114,7 @@ public class ComponentManager { ...@@ -120,7 +114,7 @@ public class ComponentManager {
* *
* @param packet the packet to send. * @param packet the packet to send.
*/ */
public void sendPacket(XMPPPacket packet) { public void sendPacket(Packet packet) {
PacketRouter router; PacketRouter router;
try { try {
router = (PacketRouterImpl)ServiceLookupFactory.getLookup().lookup(PacketRouterImpl.class); router = (PacketRouterImpl)ServiceLookupFactory.getLookup().lookup(PacketRouterImpl.class);
...@@ -133,44 +127,20 @@ public class ComponentManager { ...@@ -133,44 +127,20 @@ public class ComponentManager {
} }
} }
/**
* Send a packet to the specified recipient. Please note that this sends packets only
* to outgoing jids and does to the incoming server reader.
*
* @param packet the packet to send.
*/
public void sendPacket(Packet packet) {
PacketRouter router;
try {
router = (PacketRouterImpl)ServiceLookupFactory.getLookup().lookup(PacketRouterImpl.class);
if (router != null) {
String packetString = packet.toXML();
System.out.println(packetString + "\n");
XMPPPacket p = readStream(packetString);
router.route(p);
}
}
catch (Exception e) {
Log.error(e);
}
}
private String validateJID(String jid) { private String validateJID(String jid) {
jid = jid.trim().toLowerCase(); jid = jid.trim().toLowerCase();
return jid; return jid;
} }
private void checkPresences() { private void checkPresences() {
for (XMPPAddress prober : presenceMap.keySet()) { for (JID prober : presenceMap.keySet()) {
XMPPAddress probee = presenceMap.get(prober); JID probee = presenceMap.get(prober);
Component component = getComponent(probee.toBareStringPrep()); Component component = getComponent(probee.toBareJID());
if (component != null) { if (component != null) {
Presence presence = new PresenceImpl(); Presence presence = new Presence();
presence.setSender(prober); presence.setFrom(prober);
presence.setRecipient(probee); presence.setTo(probee);
component.processPacket(presence); component.processPacket(presence);
// No reason to hold onto prober reference. // No reason to hold onto prober reference.
...@@ -178,53 +148,4 @@ public class ComponentManager { ...@@ -178,53 +148,4 @@ public class ComponentManager {
} }
} }
} }
}
/** \ No newline at end of file
* Read the incoming stream until it ends. Much of the reading
* will actually be done in the channel handlers as they run the
* XPP through the data. This method mostly handles the idle waiting
* for incoming data. To prevent clients from stalling channel handlers,
* a watch dog timer is used. Packets that take longer than the watch
* dog limit to read will cause the session to be closed.
*
* @throws javax.xml.stream.XMLStreamException
* if there is trouble reading from the socket
*/
private XMPPPacket readStream(String string) throws UnauthorizedException, XMLStreamException {
PacketFactoryImpl packetFactory = new PacketFactoryImpl();
XMLInputFactory x = packetFactory.getXMLFactory();
XMLStreamReader xpp = x.createXMLStreamReader(new StringReader(string));
XMPPPacket packet = null;
while (true) {
for (int eventType = xpp.next();
eventType != XMLStreamConstants.START_ELEMENT;
eventType = xpp.next()) {
if (eventType == XMLStreamConstants.CHARACTERS) {
if (!xpp.isWhiteSpace()) {
throw new XMLStreamException(LocaleUtils.getLocalizedString("admin.error.packet.text"));
}
}
else if (eventType == XMLStreamConstants.END_DOCUMENT) {
return null;
}
}
String tag = xpp.getLocalName();
if ("message".equals(tag)) {
packet = packetFactory.getMessage(xpp);
}
else if ("presence".equals(tag)) {
packet = packetFactory.getPresence(xpp);
}
else if ("iq".equals(tag)) {
packet = packetFactory.getIQ(xpp);
}
else {
throw new XMLStreamException(LocaleUtils.getLocalizedString("admin.error.packet.tag") + tag);
}
return packet;
}
}
}
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.Packet;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
...@@ -128,5 +130,5 @@ public interface Connection { ...@@ -128,5 +130,5 @@ public interface Connection {
* @throws UnauthorizedException If caller doesn't have permission to access this resource * @throws UnauthorizedException If caller doesn't have permission to access this resource
* @throws XMLStreamException if there was a problem sending the packet * @throws XMLStreamException if there was a problem sending the packet
*/ */
void deliver(XMPPPacket packet) throws UnauthorizedException, XMLStreamException; void deliver(Packet packet) throws UnauthorizedException, XMLStreamException;
} }
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger;
import org.dom4j.Element;
/**
* <p>Provides a common implementation of IQ packet creation, read, and update.</p>
* <p>Info-Query (iq) is used for practically all client-server interactions and drives
* all standard extension protocols. IQ itself is a generic envelope and protocol
* used to transport specific protocol XML fragments.</p>
* <h3>Warning</h3>
* <p>Because IQ relies on the sub-element for information regarding what IQ protocol
* is being handled, IQ packets start parsing with the parser pointed to either the end
* tag of the iq, or the start tag event of it's child element which ever is encountered
* first. This allows parser handlers to advance the xpp to the sub-element to know it's
* name and namespace but still defer to the packet for parsing.</p>
*
* @author Iain Shigeoka
*/
public interface IQ extends XMPPPacket {
Type GET = new Type("get");
Type SET = new Type("set");
Type RESULT = new Type("result");
/**
* <p>Obtain the namespace of the child element.</p>
* <p/>
* <p>IQ packets may only contain one child sub-element (other than the error sub-element).</p>
*
* @return The namespace of the child element
*/
String getChildNamespace();
/**
* <p>Set the namespace of the child element.</p>
* <p/>
* <p>IQ packets may only contain one child sub-element (other than the error sub-element).</p>
*
* @param namespace The namespace of the child element
*/
void setChildNamespace(String namespace);
/**
* <p>Obtain the name of the child element.</p>
* <p/>
* <p>IQ packets may only contain one child sub-element (other than the error sub-element).</p>
*
* @return The name of the child element
*/
String getChildName();
/**
* <p>Set the name of the child element.</p>
* <p/>
* <p>IQ packets may only contain one child sub-element (other than the error sub-element).</p>
*
* @param name The name of the child element
*/
void setChildName(String name);
/**
* <p>Returns the IQ packet's only child fragment (excluding the optional error
* sub packet).</p>
* <p>The XMPP spec limits IQ packets to having only one child fragment so this
* is a convenience method to return that fragment rather than having to grab it
* from the general fragments list.</p>
*
* @return The child fragment for this IQ or null if there is none.
*/
XMPPFragment getChildFragment();
/**
* <p>Set the child element for the IQ packet.</p>
* <p/>
* <p>IQ packets may only contain one child sub-element (other than the error sub-element).</p>
*
* @param fragment The fragment to be used as the iq child element
*/
void setChildFragment(XMPPFragment fragment);
/**
* <p>Obtain an IQ result packet for the current IQ using the given body.</p>
*
* @param body The new child element to use
* @return The created result
*/
IQ createResult(Element body);
/**
* <p>Obtain the IQ result packet for the current IQ.</p>
* <p/>
* <p>IQ packets may only contain one child sub-element (other than the error sub-element).</p>
*
* @return The namespace of the child element
*/
IQ createResult();
}
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.xmpp.packet.IQ;
/** /**
* <p>Route iq packets throughout the server.</p> * <p>Route iq packets throughout the server.</p>
* <p>Routing is based on the recipient and sender addresses. The typical * <p>Routing is based on the recipient and sender addresses. The typical
......
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger;
/**
* <p>Allows the simple creation, reading, and updating of message packets.<p>
* <p>The methods used are mainly convenience interfaces to the various parts
* of a typical message packet.</p>
*
* @author Iain Shigeoka
*/
public interface Message extends XMPPPacket {
/**
* Normal message displayed in an email like interface.
*/
Type NORMAL = new Type("normal");
/**
* Chat message displayed in a line-by-line chat interface.
*/
Type CHAT = new Type("chat");
/**
* Groupchat message displayed in chatroom line-by-line interface.
*/
Type GROUP_CHAT = new Type("groupchat");
/**
* Headline message displayed either as an alert, scrolling stock ticker, etc interface.
*/
Type HEADLINE = new Type("headline");
String getBody();
void setBody(String body);
String getSubject();
void setSubject(String subject);
String getThread();
void setThread(String thread);
}
\ No newline at end of file
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.xmpp.packet.Message;
/** /**
* <p>Route message packets throughout the server.</p> * <p>Route message packets throughout the server.</p>
* <p>Routing is based on the recipient and sender addresses. The typical * <p>Routing is based on the recipient and sender addresses. The typical
......
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger;
/**
* <p>Implements the nameprep stringprep profile according to
* the XMPP specification.</p>
*
* @author Iain Shigeoka
*/
public class NamePrep {
/**
* <p>Returns the given domain name according to the resource
* prep profile. See the XMPP 1.0 specification for specifics.</p>
*
* @param name The domain name to prepare
* @return The prepared name
*/
public static String prep(String name) {
String prep = name.trim().toLowerCase();
return prep;
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger;
/**
* <p>Implements the nodeprep stringprep profile according to
* the XMPP specification.</p>
*
* @author Iain Shigeoka
*/
public class NodePrep {
/**
* <p>Returns the given user name (node) according to the resource
* prep profile. See the XMPP 1.0 specification for specifics.</p>
*
* @param username The username to prepare
* @return The prepared name
*/
public static String prep(String username) {
String prep = username.trim().toLowerCase();
return prep;
}
}
...@@ -11,9 +11,16 @@ ...@@ -11,9 +11,16 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.database.SequenceManager;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.database.DbConnectionManager;
import java.util.Iterator; import org.jivesoftware.util.*;
import org.xmpp.packet.Message;
import org.dom4j.io.SAXReader;
import org.dom4j.DocumentFactory;
import java.util.*;
import java.sql.*;
import java.sql.Connection;
/** /**
* Represents the user's offline message storage. A message store holds messages that were sent * Represents the user's offline message storage. A message store holds messages that were sent
...@@ -21,40 +28,154 @@ import java.util.Iterator; ...@@ -21,40 +28,154 @@ import java.util.Iterator;
* their presence to "available". The messages will then be delivered normally. * their presence to "available". The messages will then be delivered normally.
* Offline message storage is optional in which case, a null implementation is returned that * Offline message storage is optional in which case, a null implementation is returned that
* always throws UnauthorizedException adding messages to the store. * always throws UnauthorizedException adding messages to the store.
* <p/>
* A future version of the message store will support POP like message storage so that
* users may download offline messages on demand, inspect headers only, and continue to store
* offline messages even when available.
* *
* @author Iain Shigeoka * @author Iain Shigeoka
*/ */
public interface OfflineMessageStore { public class OfflineMessageStore {
private static final String INSERT_OFFLINE =
"INSERT INTO jiveOffline (username, messageID, creationDate, messageSize, message) " +
"VALUES (?, ?, ?, ?, ?)";
private static final String LOAD_OFFLINE =
"SELECT message FROM jiveOffline WHERE username=?";
private static final String SELECT_SIZE_OFFLINE =
"SELECT SUM(messageSize) FROM jiveOffline WHERE username=?";
private static final String DELETE_OFFLINE =
"DELETE FROM jiveOffline WHERE username=?";
private static OfflineMessageStore instance = new OfflineMessageStore();
/**
* Returns a singleton instance of OfflineMessageStore.
*
* @return an instance.
*/
public static OfflineMessageStore getInstance() {
return instance;
}
private SAXReader saxReader = new SAXReader();
private DocumentFactory docFactory = new DocumentFactory();
private OfflineMessageStore() {
}
/** /**
* Add a message to the message store. Messages will be stored and made available for * Adds a message to this message store. Messages will be stored and made
* later delivery. * available for later delivery.
* *
* @param message The message to store (messages are standard XMPP message XML) * @param message the message to store.
* @throws UnauthorizedException If the user is not allowed to store messages, or they have exceeded their quota
*/ */
void addMessage(Message message) throws UnauthorizedException; public void addMessage(Message message) {
if (message == null) {
return;
}
String username = message.getFrom().getNode();
// If the username is null (such as when an anonymous user), don't store.
if (username == null) {
return;
}
long messageID = SequenceManager.nextID(JiveConstants.OFFLINE);
// Get the message in XML format. We add the element to a new document so
// that we can easily parse the message from the database later.
String msgXML = docFactory.createDocument(message.getElement()).asXML();
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(INSERT_OFFLINE);
pstmt.setString(1, username);
pstmt.setLong(2, messageID);
pstmt.setString(3, StringUtils.dateToMillis(new java.util.Date()));
pstmt.setInt(4, msgXML.length());
pstmt.setString(5, msgXML);
pstmt.executeUpdate();
}
catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
finally {
try { if (pstmt != null) { pstmt.close(); } }
catch (Exception e) { Log.error(e); }
try { if (con != null) { con.close(); } }
catch (Exception e) { Log.error(e); }
}
}
/** /**
* <p>Obtain all messages in the store for a user.</p> * Returns a Collection of all messages in the store for a user.
* <p>Remove messages using the iterator.remove() method. Otherwise * Messages are deleted after being selected from the database.
* messages stay in the message store and will be available to other
* users of getMessages().</p>
* *
* @param username the username of the user who's messages you'd like to receive * @param username the username of the user who's messages you'd like to receive
* @return An iterator of packets containing all offline messages * @return An iterator of packets containing all offline messages
* @throws UnauthorizedException If the user is not allowed to retrieve messages
*/ */
Iterator getMessages(String username) throws UnauthorizedException, UserNotFoundException; public Collection<Message> getMessages(String username) {
List<Message> messages = new ArrayList<Message>();
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(LOAD_OFFLINE);
pstmt.setString(1, username);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
String msgXML = rs.getString(1);
messages.add(new Message(saxReader.read(msgXML).getRootElement()));
}
rs.close();
pstmt.close();
pstmt = con.prepareStatement(DELETE_OFFLINE);
pstmt.setString(1, username);
pstmt.executeUpdate();
}
catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
finally {
try { if (pstmt != null) { pstmt.close(); } }
catch (Exception e) { Log.error(e); }
try { if (con != null) { con.close(); } }
catch (Exception e) { Log.error(e); }
}
return messages;
}
/** /**
* <p>Obtain the approximate size of the XML messages stored for a particular user.</p> * Returns the approximate size (in bytes) of the XML messages stored for
* a particular user.
* *
* @param username the username of the user who's messages you'd like to receive * @param username the username of the user.
* @return The approximate size of messages stored in bytes * @return the approximate size of stored messages (in bytes).
*/ */
int getSize(String username) throws UnauthorizedException; public int getSize(String username) {
int size = 0;
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement(SELECT_SIZE_OFFLINE);
pstmt.setString(1, username);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
size = rs.getInt(1);
}
rs.close();
}
catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
finally {
try { if (pstmt != null) { pstmt.close(); } }
catch (Exception e) { Log.error(e); }
try { if (con != null) { con.close(); } }
catch (Exception e) { Log.error(e); }
}
return size;
}
} }
\ No newline at end of file
...@@ -13,6 +13,7 @@ package org.jivesoftware.messenger; ...@@ -13,6 +13,7 @@ package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.messenger.user.UserNotFoundException;
import org.xmpp.packet.Message;
/** /**
* <p>Configures and controls the server's offline message storage strategy.</p> * <p>Configures and controls the server's offline message storage strategy.</p>
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.Packet;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
/** /**
...@@ -32,6 +34,6 @@ public interface PacketDeliverer { ...@@ -32,6 +34,6 @@ public interface PacketDeliverer {
* @param packet The packet to route * @param packet The packet to route
* @throws java.lang.NullPointerException If the packet is null or the packet could not be routed * @throws java.lang.NullPointerException If the packet is null or the packet could not be routed
*/ */
public void deliver(XMPPPacket packet) throws public void deliver(Packet packet) throws
UnauthorizedException, PacketException, XMLStreamException; UnauthorizedException, PacketException, XMLStreamException;
} }
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.xmpp.packet.Message;
import org.xmpp.packet.IQ;
import org.xmpp.packet.Presence;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamReader;
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.xmpp.packet.Packet;
/** /**
* <p>An uber router that can handle any packet type.</p> * <p>An uber router that can handle any packet type.</p>
* <p>The interface is provided primarily as a convenience for services * <p>The interface is provided primarily as a convenience for services
...@@ -30,5 +32,5 @@ public interface PacketRouter extends IQRouter, MessageRouter, PresenceRouter { ...@@ -30,5 +32,5 @@ public interface PacketRouter extends IQRouter, MessageRouter, PresenceRouter {
* @throws NullPointerException If the packet is null * @throws NullPointerException If the packet is null
* @throws IllegalArgumentException If the packet is not one of the three XMPP packet types * @throws IllegalArgumentException If the packet is not one of the three XMPP packet types
*/ */
public void route(XMPPPacket packet) throws IllegalArgumentException, NullPointerException; public void route(Packet packet) throws IllegalArgumentException, NullPointerException;
} }
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.transport.TransportHandler;
import javax.xml.stream.XMLStreamException;
/**
* A service for transporting packets in/out of the current server domain.
*
* @author Iain Shigeoka
*/
public interface PacketTransporter {
/**
* Obtain the transport handler that this transporter uses for delivering
* transport packets.
*
* @return The transport handler instance used by this transporter
*/
public TransportHandler getTransportHandler();
/**
* Delivers the given packet based on packet recipient and sender. The
* deliverer defers actual routing decisions to other classes.
* <h2>Warning</h2>
* Be careful to enforce concurrency DbC of concurrent by synchronizing
* any accesses to class resources.
*
* @param packet The packet to route
* @throws NullPointerException If the packet is null or the packet could not be routed
*/
public void deliver(XMPPPacket packet) throws UnauthorizedException, PacketException, XMLStreamException;
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import java.util.Date;
/**
* <p>Allows the simple creation, reading, and updating of presence packets.<p>
* <p>The methods used are mainly convenience interfaces to the various parts
* of a typical presence packet.</p>
* <p>A Presence encapsulates information relating to the owning user such as login time, status and
* last update time.</p>
*
* @author Iain Shigeoka
*/
public interface Presence extends XMPPPacket {
/**
* <p>Sender is available for messaging.</p>
*/
Type AVAILABLE = new Type("");
/**
* <p>Sender is unavailable for messaging.</p>
*/
Type UNAVAILABLE = new Type("unavailable");
/**
* <p>Sender is available for message reciept but presence should not be broadcast to roster members.</p>
*/
Type INVISIBLE = new Type("invisible");
/**
* <p>Sender wishes to subscribe to recipient's roster.</p>
*/
Type SUBSCRIBE = new Type("subscribe");
/**
* <p>Indicates the sender should be unsubscribed from the recipient's roster.</p>
*/
Type UNSUBSCRIBE = new Type("unsubscribe");
/**
* <p>Sent to indicate a pending subcription request has been filled.</p>
*/
Type SUBSCRIBED = new Type("subscribed");
/**
* <p>Sent to indicate a pending subscription removal request has been filled.</p>
*/
Type UNSUBSCRIBED = new Type("unsubscribed");
/**
* <p>Used when the sender wants to know the recipient's presence.</p>
*/
Type PROBE = new Type("probe");
int NO_PRIORITY = -10;
public static final int STATUS_ONLINE = 0;
public static final int STATUS_IDLE = 1;
public static final int STATUS_OFFLINE = 4;
public static final int STATUS_PROBE = -1;
/**
* Available to chat show state
*/
public static final int SHOW_CHAT = 100;
/**
* No show state
*/
public static final int SHOW_NONE = 101;
/**
* Away show state
*/
public static final int SHOW_AWAY = 102;
/**
* "Extended away" show state
*/
public static final int SHOW_XA = 103;
/**
* Do not disturb show state
*/
public static final int SHOW_DND = 104;
/**
* The online/offline status of the user. Being available indicates that the node can be
* sent packets and does not imply how the presence is propogated or presented to users.
*
* @return True if the node is available for messaging
*/
public boolean isAvailable();
/**
* Sets the online/offline status of the user.
*
* @param online True if the node is available for messaging
*/
public void setAvailable(boolean online) throws UnauthorizedException;
/**
* Gets the visibility of the user. Invisible nodes can be sent packets, but don't
* automatically propagate presence to subscribers.
*
* @return True if the user is visible
* (presence should be automatically propagated to subscribers)
*/
public boolean isVisible();
/**
* Sets the visibility of the user. Invisible nodes can be sent packets, but don't
* automatically propagate presence to subscribers.
*
* @param visible True if the node is visible (presence is broadcast)
* @throws UnauthorizedException If the caller doesn't have permission
*/
public void setVisible(boolean visible) throws UnauthorizedException;
/**
* Returns the unique ID for this status. The ID in the default implmentation is the user's
* session ID, which is unique within a single JVM.
*
* @return the unique ID for the presence.
*/
public String getID();
/**
* Return the user owning the presence.
*
* @return the presence owner.
*/
public String getUsername();
/**
* Return the time when the presence was created.
*
* @return the time when the presence was created.
*/
public Date getLoginTime();
/**
* Return the time when the presence was last updated (when the user last visited).
*
* @return the time when the presence was last updated (when the user last visited).
*/
public Date getLastUpdateTime();
/**
* Set the time when the presence was last updated (when the user last visited).
*
* @param time the time of the last update.
* @throws UnauthorizedException If the caller doesn't have permissions to make this modification
*/
public void setLastUpdateTime(Date time) throws UnauthorizedException;
/**
* Returns the status of the presence.
*
* @return the status of the presence.
*/
public int getShow();
/**
* Sets the status of the user.
*
* @param status the status of the user.
* @throws UnauthorizedException If the caller doesn't have permissions to make this modification
*/
public void setShow(int status) throws UnauthorizedException;
/**
* Gets the free text status of the user. (e.g. "out to lunch").
*
* @return The status text for the user or null if none has been set
*/
public String getStatus();
/**
* Sets the free text status of the user. (e.g. "out to lunch").
*
* @param status The new status or null if none is set
* @throws UnauthorizedException
*/
public void setStatus(String status) throws UnauthorizedException;
/**
* Obtain the priority associated with this presence if any
*
* @return The priority of this presence or -1 to indicate none set
*/
public int getPriority();
/**
* Sets the new priority for this presence
*
* @param priority The new priority value
* @throws UnauthorizedException If the caller doesn't have the appropriate authorization
*/
public void setPriority(int priority) throws UnauthorizedException;
}
\ No newline at end of file
...@@ -13,6 +13,9 @@ package org.jivesoftware.messenger; ...@@ -13,6 +13,9 @@ package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.User; import org.jivesoftware.messenger.user.User;
import org.xmpp.packet.Presence;
import org.xmpp.packet.JID;
import java.util.Collection; import java.util.Collection;
/** /**
...@@ -106,11 +109,10 @@ public interface PresenceManager { ...@@ -106,11 +109,10 @@ public interface PresenceManager {
* servlet session id. * servlet session id.
* *
* @param user the user to create a presence for. * @param user the user to create a presence for.
* @param uid a unique string.
* @return the presence for the user. * @return the presence for the user.
* @throws UnauthorizedException if not the user. * @throws UnauthorizedException if not the user.
*/ */
public Presence createPresence(User user, String uid) throws UnauthorizedException; public Presence createPresence(User user) throws UnauthorizedException;
/** /**
* Sets a presence to be offline which causes the presence to be removed from the system. * Sets a presence to be offline which causes the presence to be removed from the system.
...@@ -126,7 +128,7 @@ public interface PresenceManager { ...@@ -126,7 +128,7 @@ public interface PresenceManager {
* @param jid the user to set to be offline. * @param jid the user to set to be offline.
* @throws UnauthorizedException if not the user. * @throws UnauthorizedException if not the user.
*/ */
public void setOffline(XMPPAddress jid) throws UnauthorizedException; public void setOffline(JID jid) throws UnauthorizedException;
/** /**
* Probes the presence of the given XMPPAddress and attempts to send it to the given user. * Probes the presence of the given XMPPAddress and attempts to send it to the given user.
...@@ -134,7 +136,7 @@ public interface PresenceManager { ...@@ -134,7 +136,7 @@ public interface PresenceManager {
* @param prober The user requesting the probe * @param prober The user requesting the probe
* @param probee The XMPPAddress whos presence we would like sent have have probed * @param probee The XMPPAddress whos presence we would like sent have have probed
*/ */
public void probePresence(String prober, XMPPAddress probee) throws UnauthorizedException; public void probePresence(String prober, JID probee) throws UnauthorizedException;
/** /**
* Probes the presence of the given XMPPAddress and attempts to send it to the given user. * Probes the presence of the given XMPPAddress and attempts to send it to the given user.
...@@ -142,5 +144,5 @@ public interface PresenceManager { ...@@ -142,5 +144,5 @@ public interface PresenceManager {
* @param prober The user requesting the probe * @param prober The user requesting the probe
* @param probee The XMPPAddress whos presence we would like sent have have probed * @param probee The XMPPAddress whos presence we would like sent have have probed
*/ */
public void probePresence(XMPPAddress prober, XMPPAddress probee) throws UnauthorizedException; public void probePresence(JID prober, JID probee) throws UnauthorizedException;
} }
\ No newline at end of file
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger;
/**
* <p>Implements the resourceprep stringprep profile according to
* the XMPP specification.</p>
*
* @author Iain Shigeoka
*/
public class ResourcePrep {
/**
* <p>Returns the given resource name according to the resource
* prep profile. See the XMPP 1.0 specification for specifics.</p>
*
* @param resource The resource name to prepare
* @return The prepared name
*/
public static String prep(String resource) {
String prep = resource;
return prep;
}
}
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.xmpp.packet.JID;
/** /**
* *
* *
...@@ -26,5 +28,5 @@ public interface RoutableChannelHandler extends ChannelHandler { ...@@ -26,5 +28,5 @@ public interface RoutableChannelHandler extends ChannelHandler {
* *
* @return the XMPP address. * @return the XMPP address.
*/ */
public XMPPAddress getAddress(); public JID getAddress();
} }
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.xmpp.packet.JID;
import java.util.Iterator; import java.util.Iterator;
/** /**
...@@ -83,7 +85,7 @@ public interface RoutingTable { ...@@ -83,7 +85,7 @@ public interface RoutingTable {
* @param destination The destination object for this route * @param destination The destination object for this route
* @return The destination object previously registered under the given address, or null if none existed * @return The destination object previously registered under the given address, or null if none existed
*/ */
ChannelHandler addRoute(XMPPAddress node, RoutableChannelHandler destination); ChannelHandler addRoute(JID node, RoutableChannelHandler destination);
/** /**
* <p>Obtain a route to a packet handler for the given node.</p> * <p>Obtain a route to a packet handler for the given node.</p>
...@@ -93,7 +95,7 @@ public interface RoutingTable { ...@@ -93,7 +95,7 @@ public interface RoutingTable {
* @return The handler corresponding to the route, or null indicating no route exists * @return The handler corresponding to the route, or null indicating no route exists
* @throws NoSuchRouteException If the requested route does not exist * @throws NoSuchRouteException If the requested route does not exist
*/ */
RoutableChannelHandler getRoute(XMPPAddress node) throws NoSuchRouteException; RoutableChannelHandler getRoute(JID node) throws NoSuchRouteException;
/** /**
* <p>Obtain all child routes for the given node.</p> * <p>Obtain all child routes for the given node.</p>
...@@ -103,7 +105,7 @@ public interface RoutingTable { ...@@ -103,7 +105,7 @@ public interface RoutingTable {
* @param node The address we want a route to * @param node The address we want a route to
* @return An iterator over all applicable routes * @return An iterator over all applicable routes
*/ */
Iterator getRoutes(XMPPAddress node); Iterator getRoutes(JID node);
/** /**
* <p>Obtain a route to a handler at the given node falling back to a user branch if no resource leaf exists.</p> * <p>Obtain a route to a handler at the given node falling back to a user branch if no resource leaf exists.</p>
...@@ -136,7 +138,7 @@ public interface RoutingTable { ...@@ -136,7 +138,7 @@ public interface RoutingTable {
* @return The Session corresponding to the route, or null indicating no route exists * @return The Session corresponding to the route, or null indicating no route exists
* @throws NoSuchRouteException If the requested route does not exist * @throws NoSuchRouteException If the requested route does not exist
*/ */
ChannelHandler getBestRoute(XMPPAddress node) throws NoSuchRouteException; ChannelHandler getBestRoute(JID node) throws NoSuchRouteException;
/** /**
* <p>Remove a route from the routing table.</p> * <p>Remove a route from the routing table.</p>
...@@ -145,5 +147,5 @@ public interface RoutingTable { ...@@ -145,5 +147,5 @@ public interface RoutingTable {
* @param node The address we want a route to * @param node The address we want a route to
* @return The destination object previously registered under the given address, or null if none existed * @return The destination object previously registered under the given address, or null if none existed
*/ */
ChannelHandler removeRoute(XMPPAddress node); ChannelHandler removeRoute(JID node);
} }
...@@ -15,6 +15,10 @@ import org.jivesoftware.messenger.auth.AuthToken; ...@@ -15,6 +15,10 @@ import org.jivesoftware.messenger.auth.AuthToken;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserManager; import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.messenger.user.UserNotFoundException;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
import org.xmpp.packet.Packet;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Date; import java.util.Date;
...@@ -24,11 +28,11 @@ import javax.xml.stream.XMLStreamWriter; ...@@ -24,11 +28,11 @@ import javax.xml.stream.XMLStreamWriter;
public class ServerSession implements Session { public class ServerSession implements Session {
private StreamID streamID; private StreamID streamID;
private XMPPAddress address; private JID address;
private Date creationDate; private Date creationDate;
private Connection connection = new ServerConnection(); private Connection connection = new ServerConnection();
public ServerSession(XMPPAddress address, StreamID streamID) { public ServerSession(JID address, StreamID streamID) {
this.address = address; this.address = address;
this.streamID = streamID; this.streamID = streamID;
creationDate = new Date(); creationDate = new Date();
...@@ -112,11 +116,11 @@ public class ServerSession implements Session { ...@@ -112,11 +116,11 @@ public class ServerSession implements Session {
public void incrementConflictCount() { public void incrementConflictCount() {
} }
public XMPPAddress getAddress() { public JID getAddress() {
return address; return address;
} }
public void process(XMPPPacket packet) { public void process(Packet packet) {
} }
private class ServerConnection implements Connection { private class ServerConnection implements Connection {
...@@ -159,7 +163,7 @@ public class ServerSession implements Session { ...@@ -159,7 +163,7 @@ public class ServerSession implements Session {
return null; return null;
} }
public void deliver(XMPPPacket packet) public void deliver(Packet packet)
throws UnauthorizedException { throws UnauthorizedException {
} }
......
...@@ -15,6 +15,9 @@ import org.jivesoftware.messenger.auth.AuthToken; ...@@ -15,6 +15,9 @@ import org.jivesoftware.messenger.auth.AuthToken;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserManager; import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.messenger.user.UserNotFoundException;
import org.xmpp.packet.Presence;
import org.xmpp.packet.JID;
import java.util.Date; import java.util.Date;
/** /**
...@@ -46,7 +49,7 @@ public interface Session extends RoutableChannelHandler { ...@@ -46,7 +49,7 @@ public interface Session extends RoutableChannelHandler {
* *
* @return the address of the packet handler. * @return the address of the packet handler.
*/ */
public XMPPAddress getAddress(); public JID getAddress();
/** /**
* Returns the connection associated with this Session. * Returns the connection associated with this Session.
......
This diff is collapsed.
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger;
import org.jivesoftware.util.XPPWriter;
import org.jivesoftware.messenger.spi.AbstractFragment;
import java.util.Iterator;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
/**
* Stores the fragment in a dom4j DOM model. Efficiency of the fragment is
* relatively low but is the most flexible way to store fragment information.
*
* @author Iain Shigeoka
*/
public class XMPPDOMFragment extends AbstractFragment implements XMPPFragment {
/**
* The document holding this fragment's data.
*/
private Element root;
/**
* Constructor using a given Document to represent the packet.
*/
public XMPPDOMFragment(Element root) {
this.root = root;
name = root.getName();
namespace = root.getNamespaceURI();
}
/**
* Obtain the root element of the DOM tree representing the data in this fragment.
*
* @return the root element of the DOM tree or null if none has been set
*/
public Element getRootElement() {
return root;
}
public void send(XMLStreamWriter xmlSerializer, int version) throws
XMLStreamException {
XPPWriter.write(root, xmlSerializer);
}
public XMPPFragment createDeepCopy() {
XMPPFragment frag = new XMPPDOMFragment((Element)root.clone());
Iterator frags = getFragments();
while (frags.hasNext()) {
frag.addFragment((XMPPFragment)frags.next());
}
return frag;
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger;
import org.jivesoftware.messenger.spi.AbstractFragment;
import java.util.Iterator;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
/**
* A error object representing an XMPP error. Error packets are tricky because
* Jabber (old style) and XMPP errors are completely different. This class does
* it's best to abstract the entire error generation process. The packet will
* serialize to XML according to the underlying session version (none indicating
* Jabber, v 1.0 indicating XMPP.</p>
*
* @author Iain Shigeoka
*/
public class XMPPError extends AbstractFragment {
/**
* The mandatory error message.
*/
private Code code;
/**
* Create an error with the given code.
*
* @param code The error code
*/
public XMPPError(Code code) {
this.code = code;
}
/**
* Returns the error code for this error. XMPP defines several standard error
* codes that MUST be included in the 'error' attribute of error packets.
*
* @return the error code.
*/
Code getCode() {
return code;
}
/**
* Set the error code for this error. XMPP defines several standard error codes
* that MUST be included in the 'error' attribute of error packets.
*
* @param code The error code
*/
void setCode(Code code) {
this.code = code;
}
public void send(XMLStreamWriter xmlSerializer, int version) throws XMLStreamException {
xmlSerializer.writeStartElement("jabber:client", "error");
xmlSerializer.writeAttribute("code", Integer.toString(code.getValue()));
xmlSerializer.writeEndElement();
}
public XMPPFragment createDeepCopy() {
XMPPError error = new XMPPError(code);
Iterator frags = getFragments();
while (frags.hasNext()) {
error.addFragment((XMPPFragment)frags.next());
}
return error;
}
/**
* Represents an error code.
*/
public enum Code {
NONE(-1),
REDIRECT(302),
BAD_REQUEST(400),
UNAUTHORIZED(401),
PAYMENT_REQUIRED(402),
FORBIDDEN(403),
NOT_FOUND(404),
NOT_ALLOWED(405),
NOT_ACCEPTABLE(406),
REGISTRATION_REQUIRED(407),
REQUEST_TIMEOUT(408),
CONFLICT(409),
INTERNAL_SERVER_ERROR(500),
NOT_IMPLEMENTED(501),
REMOTE_SERVER_ERROR(502),
SERVICE_UNAVAILABLE(503),
REMOTE_SERVER_TIMEOUT(504);
private int value;
/**
* Create a code with the given integer error code value.
*
* @param value the error value of the code
*/
private Code(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger;
import java.util.Iterator;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
/**
* <p>Represents an XML fragment with particular meaning in XMPP.</p>
* <p>XMPP systems will be dealing with many XML fragments and this class
* allows the system to generically handle fragments without particular knowledge
* of what they contain (and hiding optimizations in representing, storing,
* and sending these fragments). The most common fragments the system deals
* with are XMPP packets of the three cardinal types: Message, Presence,
* and IQ. However, these packets can contain protocol specific, or custom
* meta-data represented by additional fragments.</p>
* <p>Fragments allows parsers to breakdown XMPP packets into fragment object
* models. A higher abstraction level than XML DOM's that must create a node
* for every XML element. However, they also may be implemented as simple
* wrappers around raw XML DOM's if necessary.</p>
*
* @author Iain Shigeoka
*/
public interface XMPPFragment {
/**
* <p>Returns a namespace associated with this meta-data or null if none has been associated.</p>
*
* @return the namespace associated with this meta-data.
*/
public String getNamespace();
/**
* <p>Sets a namespace associated with this meta-data or null if none has been associated.</p>
*
* @param namespace the namespace associated with this meta-data.
*/
public void setNamespace(String namespace);
/**
* <p>Returns a name associated with this meta-data or null if none has been associated.</p>
*
* @return the name associated with this meta-data.
*/
public String getName();
/**
* Sets a namespace associated with this meta-data or null if none has been associated.
*
* @param name The namespace associated with this meta-data
*/
public void setName(String name);
/**
* <p>Sends the fragment as a string to the given writer.</p>
* <p>A fragment will always be written as a completely self
* contained, well-formed XML fragment.</p>
*
* @param xmlSerializer The serializer to send the jabber packet
* @param version The XMPP version for the stream (0 is old Jabber, 1 is XMPP 1.0)
* @throws XMLStreamException If there is a problem with the connection
*/
void send(XMLStreamWriter xmlSerializer, int version) throws XMLStreamException;
/**
* <p>Generates an independent, deep copy of this packet.</p>
*
* @return The deep copy of the packet
*/
XMPPFragment createDeepCopy();
/**
* <p>Adds another fragment as a child fragment of this one.</p>
* <p>Child fragments can be used to build a DOM like tree of fragments. However,
* the typical use case in Messenger packets is to store meta-data as child fragments
* and standard data as member fields accessed via standard setter/getters.</p>
*
* @param fragment the fragment to add to this packet.
*/
void addFragment(XMPPFragment fragment);
/**
* <p>Obtain an iterator of child fragments.</p>
*
* @return An iterator over all child fragments.
*/
Iterator getFragments();
/**
* Returns the fragment whose name and namespace matches the requested ones or <tt>null</tt> if
* none. It is assumed that there is at most one fragment per name and namespace.
*
* @param name the name of the fragment to search.
* @param namespace the namespace of the fragment to search.
* @return the fragment whose name and namespace matches the requested ones or <tt>null</tt> if
* none.
*/
XMPPFragment getFragment(String name, String namespace);
/**
* Remove any child fragments from this fragment.
*/
void clearFragments();
/**
* <p>Make a best guess estimate on size in bytes of an XML string representation of
* this fragment.</p>
* <p>There are several server operations that can be helped by hints on fragment sizes
* such as offline storage, auditing, caching, etc. To this end, this method provides
* a guess where speed of calculation and lowest resource impact are highest priorities
* (you should not generate the XML string and count the bytes).</p>
*
* @return an estimate in bytes of the size of this fragment as an XML string
* (assume UTF-8 encoding)
*/
int getSize();
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
/**
* A packet is a routeable XML fragment containing information on sender,
* recipient, and XMPP standard packet type.
*
* @author Iain Shigeoka
*/
public interface XMPPPacket extends XMPPFragment {
public static final Type ERROR = new Type("error");
/**
* <p>Obtain the flag indicating whether this packet is being
* sent (true) or received (false) by the server.</p>
* <p/>
* <p>The same packet may be received by the server at a c2s
* connection making isSending() false, then the server routes
* the packet and sets the isSending() to true for delivery
* out another c2s connection.</p>
*
* @return true if the packet is in the process of being sent.
*/
boolean isSending();
/**
* <p>Set a flag indicating whether this packet is being
* sent (true) or received (false) by the server.</p>
*
* @param isSending true if the packet is in the process of being sent.
*/
void setSending(boolean isSending);
/**
* <p>Returns the priority of the packet for routing and handling.</p>
* <p>Valid values are <tt>XMPPPacket.ROUTE_PRIORITY_HIGH</tt>,
* <tt>XMPPPacket.ROUTE_PRIORITY_NORMAL</tt> or
* <tt>XMPPPacket.ROUTE_PRIORITY_LOW</tt>. The
* priority determines how quickly a packet will be routed through
* a Channel, with higher priority packet being handled first. Any
* ChannelHandler can set the priority of a packet. Subsequently,
* that priority should apply for all future channels until a
* new priority setting is made.</p>
*
* @return the routing priority of the packet.
*/
RoutePriority getRoutePriority();
/**
* <p>Sets the priority of the packet for routing and handling.</p>
* <p>Valid values are <tt>XMPPPacket.ROUTE_PRIORITY_HIGH</tt>,
* <tt>XMPPPacket.ROUTE_PRIORITY_NORMAL</tt> or
* <tt>XMPPPacket.ROUTE_PRIORITY_LOW</tt>. The
* priority determines how quickly a packet will be routed
* through a Channel, with higher priority packet being
* handled first. Any ChannelHandler can set the priority
* of a packet. Subsequently, that priority should apply
* for all future channels until a new priority setting is made.</p>
*
* @param priority the routing priority of the packet.
*/
void setRoutePriority(RoutePriority priority);
/**
* <p>Makes this packet an error packet and sets it's error
* code to the given value.</p>
* <p/>
* <p>Errors are generically handled for XMPP 1.0 errors and
* old Jabber style errors.</p>
*
* @param errorCode The new error code for this packet
*/
void setError(XMPPError.Code errorCode);
/**
* <p>Get the error for this packet if the packet is of type 'error'.</p>
* <p>Packets of type 'error' MUST have an error payload. If the error
* packet is of type 'error' and no error object is currenly set, this method
* MUST return an unknown error (not null). Similarly, if the packet type is
* not 'error' this method will always return null.</p>
*
* @return error The error payload for this packet or null if none exists
*/
XMPPError getError();
/**
* <p>Obtain the id attribute of the packet.</p>
* <p/>
* <p>IDs are used to identify related packets. In IQ request-response
* pairs, the ID on the request is always set to the same value on
* the response to make matching of the two possible.</p>
*
* @return The ID of the packet or null if none is set
*/
String getID();
/**
* <p>Set the id attribute of the packet.</p>
*
* @param id The ID of the packet or null if none is set
* @see #getID
*/
void setID(String id);
/**
* Get the recipient JID for this packet. This taken from the "to" attribute
* of incoming packets or set if you want to force a destination.
*
* @return The recipient's JID
*/
XMPPAddress getRecipient();
/**
* <p>Set the recipient JID for this packet (will be used with the 'to'
* attribute of the packet).</p>
* <p/>
* <p>Setting the recipient to null leaves the 'to' attribute blank
* and eliminates the ability for the server to route the packet by
* recipient address. In other words, a packet with null recipient
* will not be routed automatically by the server.</p>
*
* @param recipient The address of the recipient of this packet or
* null to leave the field blank.
*/
void setRecipient(XMPPAddress recipient);
/**
* <p>Sets the sender JID for this packet (will be used with the 'from'
* attribute of the packet).</p>
* <p/>
* <p>The sender can be null, in which case the server will attempt to
* set the from field using the address associated with the originating
* session. If the originating session is null, or does not have an
* address, then the from attribute is not set on the packet.</p>
*
* @param sender The sender of this packet
*/
void setSender(XMPPAddress sender);
/**
* Get the sender's JID for this packet. This forced to be the originating
* sender on c2s packets or taken from the "from" attribute on
* of incoming s2s packets. The value of the "from" attribute is set
* to match the sender on outgoing packets regardless
* of the presence or value of the "from" attribute.
*
* @return the sender's JID.
*/
XMPPAddress getSender();
/**
* Gets the session that created this packet. The default is null
* which indicates that the packet was created by the server.
* The distinction between sender and originating session is needed
* for server and s2s generated packets.
*
* @return the session that created this packet.
*/
Session getOriginatingSession();
/**
* <p>Sets the session that created this packet.</p>
*
* @param session the session that created this packet or null if
* the server sent the packet
*/
void setOriginatingSession(Session session);
/**
* <p>Parse the packet from the given parser.</p>
* <p>The XPP parser MUST be set to the start tag of the packet's root element
* before calling this method and will always return with the xpp parser
* on the end tag token of the packet's root element.</p>
*
* @param xpp the XPP to pull the packet from.
*/
void parse(XMLStreamReader xpp) throws XMLStreamException;
/**
* <p>Obtain the type-safe type attribute from a string.</p>
*
* @param type the string type (may be null).
* @return the corrresponding type.
*/
Type typeFromString(String type);
/**
* Sets the type of packet. The type is used in the 'type'
* attribute of the packet and for determining output formatting
* such as whether to use an Error packet to decorate this packet.
*
* @param type the type of this packet.
*/
void setType(Type type);
/**
* Obtain the type of this packet.
*
* @return the type of this packet.
*/
Type getType();
/**
* Represents the type-safe 'type' attribute of a packet.
*/
class Type {
String value;
protected Type(String value) {
this.value = value;
}
public String toString() {
return value;
}
}
/**
* Routing priority of a packet.
*/
public enum RoutePriority {
high, normal, low;
}
}
\ No newline at end of file
...@@ -13,6 +13,7 @@ package org.jivesoftware.messenger; ...@@ -13,6 +13,7 @@ package org.jivesoftware.messenger;
import org.jivesoftware.messenger.container.Module; import org.jivesoftware.messenger.container.Module;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.JID;
/** /**
* The XMPP server definition. An interface allows us to implement the * The XMPP server definition. An interface allows us to implement the
...@@ -42,7 +43,7 @@ public interface XMPPServer extends XMPPServerMBean, Module { ...@@ -42,7 +43,7 @@ public interface XMPPServer extends XMPPServerMBean, Module {
* *
* @return true if the address is a local address to this server. * @return true if the address is a local address to this server.
*/ */
public boolean isLocal(XMPPAddress jid); public boolean isLocal(JID jid);
/** /**
* Creates an XMPPAddress local to this server. * Creates an XMPPAddress local to this server.
...@@ -51,7 +52,7 @@ public interface XMPPServer extends XMPPServerMBean, Module { ...@@ -51,7 +52,7 @@ public interface XMPPServer extends XMPPServerMBean, Module {
* @param resource the resource portion of the id or null to indicate none is needed. * @param resource the resource portion of the id or null to indicate none is needed.
* @return an XMPPAddress for the server. * @return an XMPPAddress for the server.
*/ */
public XMPPAddress createAddress(String username, String resource); public JID createJID(String username, String resource);
/** /**
* Obtain the session representing a packet stream originating from the server. * Obtain the session representing a packet stream originating from the server.
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
package org.jivesoftware.messenger.audit; package org.jivesoftware.messenger.audit;
import org.jivesoftware.messenger.XMPPPacket; import org.xmpp.packet.Packet;
/** /**
* <p>Use auditors to audit events and messages on the server.</p> * <p>Use auditors to audit events and messages on the server.</p>
...@@ -29,7 +29,7 @@ public interface Auditor { ...@@ -29,7 +29,7 @@ public interface Auditor {
* *
* @param packet the packet being audited * @param packet the packet being audited
*/ */
void audit(XMPPPacket packet); void audit(Packet packet);
/** /**
* Audit any packet that was dropped (undeliverables, etc). * Audit any packet that was dropped (undeliverables, etc).
......
...@@ -13,11 +13,12 @@ package org.jivesoftware.messenger.auth.spi; ...@@ -13,11 +13,12 @@ package org.jivesoftware.messenger.auth.spi;
import org.jivesoftware.database.DbConnectionManager; import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.NodePrep;
import org.jivesoftware.messenger.auth.AuthFactory; import org.jivesoftware.messenger.auth.AuthFactory;
import org.jivesoftware.messenger.auth.AuthProvider; import org.jivesoftware.messenger.auth.AuthProvider;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.stringprep.Stringprep;
import org.jivesoftware.stringprep.StringprepException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
...@@ -72,7 +73,12 @@ public class DbAuthProvider implements AuthProvider { ...@@ -72,7 +73,12 @@ public class DbAuthProvider implements AuthProvider {
if (username == null || password == null) { if (username == null || password == null) {
throw new UnauthorizedException(); throw new UnauthorizedException();
} }
username = NodePrep.prep(username); try {
username = Stringprep.nodeprep(username);
}
catch (StringprepException se) {
throw new UnauthorizedException("Illegal username: " + se.getMessage());
}
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
try { try {
...@@ -119,7 +125,12 @@ public class DbAuthProvider implements AuthProvider { ...@@ -119,7 +125,12 @@ public class DbAuthProvider implements AuthProvider {
if (username == null || token == null || digest == null) { if (username == null || token == null || digest == null) {
throw new UnauthorizedException(); throw new UnauthorizedException();
} }
username = NodePrep.prep(username); try {
username = Stringprep.nodeprep(username);
}
catch (StringprepException se) {
throw new UnauthorizedException("Illegal username: " + se.getMessage());
}
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
try { try {
...@@ -167,7 +178,12 @@ public class DbAuthProvider implements AuthProvider { ...@@ -167,7 +178,12 @@ public class DbAuthProvider implements AuthProvider {
if (username == null || password == null) { if (username == null || password == null) {
throw new UnauthorizedException(); throw new UnauthorizedException();
} }
username = NodePrep.prep(username); try {
username = Stringprep.nodeprep(username);
}
catch (StringprepException se) {
throw new UnauthorizedException("Illegal username: " + se.getMessage());
}
Connection con = null; Connection con = null;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
try { try {
......
...@@ -12,8 +12,9 @@ ...@@ -12,8 +12,9 @@
package org.jivesoftware.messenger.disco; package org.jivesoftware.messenger.disco;
import org.jivesoftware.messenger.forms.XDataForm; import org.jivesoftware.messenger.forms.XDataForm;
import org.jivesoftware.messenger.XMPPAddress;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.JID;
import java.util.Iterator; import java.util.Iterator;
/** /**
...@@ -38,7 +39,7 @@ public interface DiscoInfoProvider { ...@@ -38,7 +39,7 @@ public interface DiscoInfoProvider {
* @param senderJID the XMPPAddress of user that sent the disco info request. * @param senderJID the XMPPAddress of user that sent the disco info request.
* @return an Iterator (of Element) with the target entity's identities. * @return an Iterator (of Element) with the target entity's identities.
*/ */
public abstract Iterator getIdentities(String name, String node, XMPPAddress senderJID); public abstract Iterator getIdentities(String name, String node, JID senderJID);
/** /**
* Returns an Iterator (of String) with the supported features. The features to include are the * Returns an Iterator (of String) with the supported features. The features to include are the
...@@ -50,7 +51,7 @@ public interface DiscoInfoProvider { ...@@ -50,7 +51,7 @@ public interface DiscoInfoProvider {
* @param senderJID the XMPPAddress of user that sent the disco info request. * @param senderJID the XMPPAddress of user that sent the disco info request.
* @return an Iterator (of String) with the supported features. * @return an Iterator (of String) with the supported features.
*/ */
public abstract Iterator getFeatures(String name, String node, XMPPAddress senderJID); public abstract Iterator getFeatures(String name, String node, JID senderJID);
/** /**
* Returns an XDataForm with the extended information about the entity or null if none. Each bit * Returns an XDataForm with the extended information about the entity or null if none. Each bit
...@@ -61,7 +62,7 @@ public interface DiscoInfoProvider { ...@@ -61,7 +62,7 @@ public interface DiscoInfoProvider {
* @param senderJID the XMPPAddress of user that sent the disco info request. * @param senderJID the XMPPAddress of user that sent the disco info request.
* @return an XDataForm with the extended information about the entity or null if none. * @return an XDataForm with the extended information about the entity or null if none.
*/ */
public abstract XDataForm getExtendedInfo(String name, String node, XMPPAddress senderJID); public abstract XDataForm getExtendedInfo(String name, String node, JID senderJID);
/** /**
* Returns true if we can provide information related to the requested name and node. For * Returns true if we can provide information related to the requested name and node. For
...@@ -75,6 +76,6 @@ public interface DiscoInfoProvider { ...@@ -75,6 +76,6 @@ public interface DiscoInfoProvider {
* @return true if we can provide information related to the requested name and node. * @return true if we can provide information related to the requested name and node.
* @throws UnauthorizedException if the senderJID is not authorized to discover information. * @throws UnauthorizedException if the senderJID is not authorized to discover information.
*/ */
public abstract boolean hasInfo(String name, String node, XMPPAddress senderJID) public abstract boolean hasInfo(String name, String node, JID senderJID)
throws UnauthorizedException; throws UnauthorizedException;
} }
...@@ -11,8 +11,9 @@ ...@@ -11,8 +11,9 @@
package org.jivesoftware.messenger.disco; package org.jivesoftware.messenger.disco;
import org.jivesoftware.messenger.XMPPAddress;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.JID;
import java.util.Iterator; import java.util.Iterator;
/** /**
...@@ -40,7 +41,7 @@ public interface DiscoItemsProvider { ...@@ -40,7 +41,7 @@ public interface DiscoItemsProvider {
* @return an Iterator (of Element) with the target entity's items or null if none. * @return an Iterator (of Element) with the target entity's items or null if none.
* @throws UnauthorizedException if the senderJID is not authorized to discover items. * @throws UnauthorizedException if the senderJID is not authorized to discover items.
*/ */
public abstract Iterator getItems(String name, String node, XMPPAddress senderJID) public abstract Iterator getItems(String name, String node, JID senderJID)
throws UnauthorizedException; throws UnauthorizedException;
} }
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.forms;
import org.jivesoftware.messenger.XMPPFragment;
import org.dom4j.Element;
/**
* The standard XMPP DataForm packet.
*
* @author Gaston Dombiak
*/
public interface XDataForm extends DataForm, XMPPFragment {
/**
* Obtain the data form as an XML DOM element.
*
* @return The data form as an XML DOM element.
*/
public Element asXMLElement();
}
...@@ -12,8 +12,6 @@ ...@@ -12,8 +12,6 @@
package org.jivesoftware.messenger.forms.spi; package org.jivesoftware.messenger.forms.spi;
import org.jivesoftware.messenger.forms.FormField; import org.jivesoftware.messenger.forms.FormField;
import org.jivesoftware.messenger.forms.XDataForm;
import org.jivesoftware.messenger.XMPPFragment;
import org.jivesoftware.util.ConcurrentHashSet; import org.jivesoftware.util.ConcurrentHashSet;
import java.util.*; import java.util.*;
...@@ -48,7 +46,7 @@ import org.dom4j.QName; ...@@ -48,7 +46,7 @@ import org.dom4j.QName;
* *
* @author gdombiak * @author gdombiak
*/ */
public class XDataFormImpl implements XDataForm { public class XDataFormImpl {
private String type; private String type;
private String title; private String title;
......
...@@ -143,7 +143,7 @@ public class IQAuthHandler extends IQHandler implements IQAuthInfo { ...@@ -143,7 +143,7 @@ public class IQAuthHandler extends IQHandler implements IQAuthInfo {
Session session, Session session,
String digest) String digest)
throws UnauthorizedException, UserNotFoundException { throws UnauthorizedException, UserNotFoundException {
XMPPAddress jid = localServer.createAddress(username, iq.element("resource").getTextTrim()); XMPPAddress jid = localServer.createJID(username, iq.element("resource").getTextTrim());
// If a session already exists with the requested JID, then check to see // If a session already exists with the requested JID, then check to see
......
...@@ -17,6 +17,10 @@ import org.jivesoftware.util.LocaleUtils; ...@@ -17,6 +17,10 @@ import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.*; import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.IQ;
import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketError;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
/** /**
...@@ -47,8 +51,8 @@ public abstract class IQHandler extends BasicModule implements ChannelHandler { ...@@ -47,8 +51,8 @@ public abstract class IQHandler extends BasicModule implements ChannelHandler {
this.router = router; this.router = router;
} }
public void process(XMPPPacket xmppPacket) throws UnauthorizedException, PacketException { public void process(Packet packet) throws UnauthorizedException, PacketException {
IQ iq = (IQ)xmppPacket; IQ iq = (IQ)packet;
try { try {
iq = handleIQ(iq); iq = handleIQ(iq);
if (iq != null) { if (iq != null) {
...@@ -58,8 +62,8 @@ public abstract class IQHandler extends BasicModule implements ChannelHandler { ...@@ -58,8 +62,8 @@ public abstract class IQHandler extends BasicModule implements ChannelHandler {
catch (org.jivesoftware.messenger.auth.UnauthorizedException e) { catch (org.jivesoftware.messenger.auth.UnauthorizedException e) {
if (iq != null) { if (iq != null) {
try { try {
XMPPPacket response = iq.createResult(); IQ response = IQ.createResultIQ(iq);
response.setError(XMPPError.Code.UNAUTHORIZED); response.setError(PacketError.Condition.not_authorized);
Session session = iq.getOriginatingSession(); Session session = iq.getOriginatingSession();
if (!session.getConnection().isClosed()) { if (!session.getConnection().isClosed()) {
session.getConnection().deliver(response); session.getConnection().deliver(response);
......
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
package org.jivesoftware.messenger.muc; package org.jivesoftware.messenger.muc;
import org.jivesoftware.messenger.IQ; import org.xmpp.packet.Message;
import org.jivesoftware.messenger.Message; import org.xmpp.packet.Presence;
import org.jivesoftware.messenger.Presence; import org.xmpp.packet.IQ;
/** /**
* Interface for any object that can accept chat messages and presence * Interface for any object that can accept chat messages and presence
...@@ -22,6 +22,7 @@ import org.jivesoftware.messenger.Presence; ...@@ -22,6 +22,7 @@ import org.jivesoftware.messenger.Presence;
* @author Gaston Dombiak * @author Gaston Dombiak
*/ */
public interface ChatDeliverer { public interface ChatDeliverer {
/** /**
* Sends a packet to the user. * Sends a packet to the user.
* *
......
...@@ -22,8 +22,6 @@ import java.util.TimeZone; ...@@ -22,8 +22,6 @@ import java.util.TimeZone;
import org.jivesoftware.messenger.muc.spi.MUCRoleImpl; import org.jivesoftware.messenger.muc.spi.MUCRoleImpl;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.Message;
import org.jivesoftware.messenger.MetaDataFragment;
/** /**
* Represents the amount of history requested by an occupant while joining a room. There are * Represents the amount of history requested by an occupant while joining a room. There are
......
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
package org.jivesoftware.messenger.muc; package org.jivesoftware.messenger.muc;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.Message;
import org.jivesoftware.messenger.JiveGlobals; import org.jivesoftware.messenger.JiveGlobals;
import org.xmpp.packet.Message;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
......
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
package org.jivesoftware.messenger.muc; package org.jivesoftware.messenger.muc;
import org.jivesoftware.messenger.MetaDataFragment; import org.xmpp.packet.JID;
import org.jivesoftware.messenger.Presence; import org.xmpp.packet.Presence;
import org.jivesoftware.messenger.XMPPAddress; import org.dom4j.Element;
/** /**
* Defines the permissions and actions that a MUCUser may use in * Defines the permissions and actions that a MUCUser may use in
...@@ -82,7 +82,7 @@ public interface MUCRole extends ChatDeliverer { ...@@ -82,7 +82,7 @@ public interface MUCRole extends ChatDeliverer {
* @return the extended presence information that includes information about roles, * @return the extended presence information that includes information about roles,
* affiliations. * affiliations.
*/ */
MetaDataFragment getExtendedPresenceInformation(); Element getExtendedPresenceInformation();
/** /**
* Set the current presence status of a user in a chatroom. * Set the current presence status of a user in a chatroom.
...@@ -183,5 +183,5 @@ public interface MUCRole extends ChatDeliverer { ...@@ -183,5 +183,5 @@ public interface MUCRole extends ChatDeliverer {
* *
* @return The Jabber ID that represents this role in the room. * @return The Jabber ID that represents this role in the room.
*/ */
XMPPAddress getRoleAddress(); JID getRoleAddress();
} }
...@@ -18,13 +18,12 @@ import java.util.Collection; ...@@ -18,13 +18,12 @@ import java.util.Collection;
import org.jivesoftware.messenger.muc.spi.IQAdminHandler; import org.jivesoftware.messenger.muc.spi.IQAdminHandler;
import org.jivesoftware.messenger.muc.spi.IQOwnerHandler; import org.jivesoftware.messenger.muc.spi.IQOwnerHandler;
import org.jivesoftware.util.NotFoundException; import org.jivesoftware.util.NotFoundException;
import org.jivesoftware.messenger.Message;
import org.jivesoftware.messenger.Presence;
import org.jivesoftware.messenger.Session;
import org.jivesoftware.messenger.XMPPAddress;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserAlreadyExistsException; import org.jivesoftware.messenger.user.UserAlreadyExistsException;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.messenger.user.UserNotFoundException;
import org.xmpp.packet.Presence;
import org.xmpp.packet.Message;
import org.xmpp.packet.JID;
/** /**
...@@ -212,7 +211,7 @@ public interface MUCRoom extends ChatDeliverer { ...@@ -212,7 +211,7 @@ public interface MUCRoom extends ChatDeliverer {
* @return The new presence * @return The new presence
* @throws UnauthorizedException If the user doesn't have permission to leave the room * @throws UnauthorizedException If the user doesn't have permission to leave the room
*/ */
Presence createPresence(int presenceStatus) throws UnauthorizedException; Presence createPresence(Presence.Type type) throws UnauthorizedException;
/** /**
* Broadcast a given message to all members of this chat room. The sender is always set to * Broadcast a given message to all members of this chat room. The sender is always set to
...@@ -340,7 +339,7 @@ public interface MUCRoom extends ChatDeliverer { ...@@ -340,7 +339,7 @@ public interface MUCRoom extends ChatDeliverer {
* an existing occupant. * an existing occupant.
* @throws ForbiddenException If the user is not allowed to grant moderator privileges. * @throws ForbiddenException If the user is not allowed to grant moderator privileges.
*/ */
public Presence addModerator(String fullJID, MUCRole senderRole) throws ForbiddenException; public Presence addModerator(JID fullJID, MUCRole senderRole) throws ForbiddenException;
/** /**
* Changes the role of the user within the room to participant. A participant is allowed to send * Changes the role of the user within the room to participant. A participant is allowed to send
...@@ -355,7 +354,7 @@ public interface MUCRoom extends ChatDeliverer { ...@@ -355,7 +354,7 @@ public interface MUCRoom extends ChatDeliverer {
* @throws NotAllowedException If trying to change the moderator role to an owner or an admin. * @throws NotAllowedException If trying to change the moderator role to an owner or an admin.
* @throws ForbiddenException If the user is not allowed to grant participant privileges. * @throws ForbiddenException If the user is not allowed to grant participant privileges.
*/ */
public Presence addParticipant(String fullJID, String reason, MUCRole senderRole) public Presence addParticipant(JID fullJID, String reason, MUCRole senderRole)
throws NotAllowedException, ForbiddenException; throws NotAllowedException, ForbiddenException;
/** /**
...@@ -363,14 +362,14 @@ public interface MUCRoom extends ChatDeliverer { ...@@ -363,14 +362,14 @@ public interface MUCRoom extends ChatDeliverer {
* is not allowed to send messages to the room (i.e. does not has voice) and may invite others * is not allowed to send messages to the room (i.e. does not has voice) and may invite others
* to the room. * to the room.
* *
* @param fullJID The full JID of the occupant to change to visitor. * @param jid the full JID of the occupant to change to visitor.
* @param senderRole The role of the user that is changing the role to visitor. * @param senderRole the role of the user that is changing the role to visitor.
* @return the updated presence of the occupant or <tt>null</tt> if the JID does not belong to * @return the updated presence of the occupant or <tt>null</tt> if the JID does not belong to
* an existing occupant. * an existing occupant.
* @throws NotAllowedException If trying to change the moderator role to an owner or an admin. * @throws NotAllowedException if trying to change the moderator role to an owner or an admin.
* @throws ForbiddenException If the user is not a moderator. * @throws ForbiddenException if the user is not a moderator.
*/ */
public Presence addVisitor(String fullJID, MUCRole senderRole) throws NotAllowedException, public Presence addVisitor(JID jid, MUCRole senderRole) throws NotAllowedException,
ForbiddenException; ForbiddenException;
/** /**
...@@ -449,7 +448,7 @@ public interface MUCRoom extends ChatDeliverer { ...@@ -449,7 +448,7 @@ public interface MUCRoom extends ChatDeliverer {
* @return the updated presence of the kicked user or null if the user was not in the room. * @return the updated presence of the kicked user or null if the user was not in the room.
* @throws NotAllowedException Thrown if trying to ban an owner or an administrator. * @throws NotAllowedException Thrown if trying to ban an owner or an administrator.
*/ */
public Presence kickOccupant(String fullJID, String actorJID, String reason) public Presence kickOccupant(JID fullJID, JID actorJID, String reason)
throws NotAllowedException; throws NotAllowedException;
public IQOwnerHandler getIQOwnerHandler(); public IQOwnerHandler getIQOwnerHandler();
...@@ -785,13 +784,12 @@ public interface MUCRoom extends ChatDeliverer { ...@@ -785,13 +784,12 @@ public interface MUCRoom extends ChatDeliverer {
* need the originating session so that the offline strategy could potentially bounce the * need the originating session so that the offline strategy could potentially bounce the
* message with the invitation. * message with the invitation.
* *
* @param to the bare JID of the user that is being invited. * @param to the JID of the user that is being invited.
* @param reason the reason of the invitation or null if none. * @param reason the reason of the invitation or null if none.
* @param role the role of the occupant that sent the invitation. * @param role the role of the occupant that sent the invitation.
* @param session the originating session that the occupant used for sending the invitation.
* @throws ForbiddenException If the user is not allowed to send the invitation. * @throws ForbiddenException If the user is not allowed to send the invitation.
*/ */
public void sendInvitation(String to, String reason, MUCRole role, Session session) public void sendInvitation(JID to, String reason, MUCRole role)
throws ForbiddenException; throws ForbiddenException;
/** /**
...@@ -801,11 +799,9 @@ public interface MUCRoom extends ChatDeliverer { ...@@ -801,11 +799,9 @@ public interface MUCRoom extends ChatDeliverer {
* moment we need the originating session so that the offline strategy could potentially bounce * moment we need the originating session so that the offline strategy could potentially bounce
* the message with the rejection. * the message with the rejection.
* *
* @param to the bare JID of the user that is originated the invitation. * @param to the JID of the user that is originated the invitation.
* @param reason the reason for the rejection or null if none. * @param reason the reason for the rejection or null if none.
* @param sender the address of the invitee that is rejecting the invitation. * @param from the JID of the invitee that is rejecting the invitation.
* @param session the originating session that the invitee used for rejecting the invitation.
*/ */
public void sendInvitationRejection(String to, String reason, XMPPAddress sender, public void sendInvitationRejection(JID to, String reason, JID from);
Session session);
} }
\ No newline at end of file
...@@ -17,11 +17,10 @@ import java.util.Iterator; ...@@ -17,11 +17,10 @@ import java.util.Iterator;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.TimeZone; import java.util.TimeZone;
import org.jivesoftware.messenger.Message;
import org.jivesoftware.messenger.MetaDataFragment;
import org.jivesoftware.messenger.XMPPAddress;
import org.jivesoftware.messenger.spi.MessageImpl;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.messenger.user.UserNotFoundException;
import org.xmpp.packet.Message;
import org.xmpp.packet.JID;
import org.dom4j.Element;
/** /**
* Represent the data model for one <code>MUCRoom</code> history. Including chat transcript, * Represent the data model for one <code>MUCRoom</code> history. Including chat transcript,
...@@ -51,16 +50,12 @@ public final class MUCRoomHistory { ...@@ -51,16 +50,12 @@ public final class MUCRoomHistory {
public void addMessage(Message packet) { public void addMessage(Message packet) {
// Don't keep messages whose sender is the room itself (thus address without resource) // Don't keep messages whose sender is the room itself (thus address without resource)
// unless the message is changing the room's subject // unless the message is changing the room's subject
if ((packet.getSender().getResourcePrep() == null if ((packet.getFrom() == null
|| packet.getSender().getResourcePrep().length() == 0) && || packet.getFrom().toString().length() == 0) &&
packet.getSubject() == null) { packet.getSubject() == null) {
return; return;
} }
Message packetToAdd = (Message) packet.createDeepCopy(); Message packetToAdd = (Message) packet.createCopy();
// Clean the originating session of this message. We will need to deliver this message even
// after the user that sent it has logged off. Otherwise, it won't be delivered since
// messenger expects senders of messages to be authenticated when delivering their messages.
packetToAdd.setOriginatingSession(null);
// TODO Analyze concurrency (on the LinkList) when adding many messages simultaneously // TODO Analyze concurrency (on the LinkList) when adding many messages simultaneously
...@@ -69,47 +64,46 @@ public final class MUCRoomHistory { ...@@ -69,47 +64,46 @@ public final class MUCRoomHistory {
isNonAnonymousRoom = room.canAnyoneDiscoverJID(); isNonAnonymousRoom = room.canAnyoneDiscoverJID();
// Update the "from" attribute of the delay information in the history // Update the "from" attribute of the delay information in the history
Message message; Message message;
MetaDataFragment frag; Element delayElement;
// TODO Make this update in a separate thread // TODO Make this update in a separate thread
for (Iterator it = getMessageHistory(); it.hasNext();) { for (Iterator it = getMessageHistory(); it.hasNext();) {
message = (Message) it.next(); message = (Message) it.next();
frag = (MetaDataFragment) message.getFragment("x", "jabber:x:delay"); delayElement = message.getChildElement("x", "jabber:x:delay");
if (room.canAnyoneDiscoverJID()) { if (room.canAnyoneDiscoverJID()) {
// Set the Full JID as the "from" attribute // Set the Full JID as the "from" attribute
try { try {
MUCRole role = room.getOccupant(message.getSender().getResourcePrep()); MUCRole role = room.getOccupant(message.getFrom().getResource());
frag.setProperty("x:from", role.getChatUser().getAddress().toStringPrep()); delayElement.addAttribute("from", role.getChatUser().getAddress().toString());
} }
catch (UserNotFoundException e) { catch (UserNotFoundException e) {
} }
} }
else { else {
// Set the Room JID as the "from" attribute // Set the Room JID as the "from" attribute
frag.setProperty("x:from", message.getSender().toStringPrep()); delayElement.addAttribute("from", message.getFrom().toString());
} }
} }
} }
// Add the delay information to the message // Add the delay information to the message
MetaDataFragment delayInformation = new MetaDataFragment("jabber:x:delay", "x"); Element delayInformation = packetToAdd.addChildElement("x", "jabber:x:delay");
Date current = new Date(); Date current = new Date();
delayInformation.setProperty("x:stamp", UTC_FORMAT.format(current)); delayInformation.addAttribute("stamp", UTC_FORMAT.format(current));
if (room.canAnyoneDiscoverJID()) { if (room.canAnyoneDiscoverJID()) {
// Set the Full JID as the "from" attribute // Set the Full JID as the "from" attribute
try { try {
MUCRole role = room.getOccupant(packet.getSender().getResourcePrep()); MUCRole role = room.getOccupant(packet.getFrom().getResource());
delayInformation.setProperty("x:from", role.getChatUser().getAddress() delayInformation.addAttribute("from", role.getChatUser().getAddress()
.toStringPrep()); .toString());
} }
catch (UserNotFoundException e) { catch (UserNotFoundException e) {
} }
} }
else { else {
// Set the Room JID as the "from" attribute // Set the Room JID as the "from" attribute
delayInformation.setProperty("x:from", packet.getSender().toStringPrep()); delayInformation.addAttribute("from", packet.getFrom().toString());
} }
packetToAdd.addFragment(delayInformation);
historyStrategy.addMessage(packetToAdd); historyStrategy.addMessage(packetToAdd);
} }
...@@ -140,36 +134,36 @@ public final class MUCRoomHistory { ...@@ -140,36 +134,36 @@ public final class MUCRoomHistory {
* @param body the body of the message. * @param body the body of the message.
*/ */
public void addOldMessage(String senderJID, String nickname, Date sentDate, String subject, public void addOldMessage(String senderJID, String nickname, Date sentDate, String subject,
String body) { String body)
Message packetToAdd = new MessageImpl(); {
packetToAdd.setType(Message.GROUP_CHAT); Message message = new Message();
packetToAdd.setSubject(subject); message.setType(Message.Type.groupchat);
packetToAdd.setBody(body); message.setSubject(subject);
message.setBody(body);
// Set the sender of the message // Set the sender of the message
if (nickname != null && nickname.trim().length() > 0) { if (nickname != null && nickname.trim().length() > 0) {
XMPPAddress roomJID = room.getRole().getRoleAddress(); JID roomJID = room.getRole().getRoleAddress();
// Recreate the sender address based on the nickname and room's JID // Recreate the sender address based on the nickname and room's JID
packetToAdd.setSender(new XMPPAddress(roomJID.getNamePrep(), roomJID.getHostPrep(), message.setFrom(new JID(roomJID.getNode(), roomJID.getDomain(),
nickname)); nickname));
} }
else { else {
// Set the room as the sender of the message // Set the room as the sender of the message
packetToAdd.setSender(room.getRole().getRoleAddress()); message.setFrom(room.getRole().getRoleAddress());
} }
// Add the delay information to the message // Add the delay information to the message
MetaDataFragment delayInformation = new MetaDataFragment("jabber:x:delay", "x"); Element delayInformation = message.addChildElement("x", "jabber:x:deley");
delayInformation.setProperty("x:stamp", UTC_FORMAT.format(sentDate)); delayInformation.addAttribute("stamp", UTC_FORMAT.format(sentDate));
if (room.canAnyoneDiscoverJID()) { if (room.canAnyoneDiscoverJID()) {
// Set the Full JID as the "from" attribute // Set the Full JID as the "from" attribute
delayInformation.setProperty("x:from", senderJID); delayInformation.addAttribute("from", senderJID);
} }
else { else {
// Set the Room JID as the "from" attribute // Set the Room JID as the "from" attribute
delayInformation.setProperty("x:from", room.getRole().getRoleAddress().toStringPrep()); delayInformation.addAttribute("from", room.getRole().getRoleAddress().toString());
} }
packetToAdd.addFragment(delayInformation); historyStrategy.addMessage(message);
historyStrategy.addMessage(packetToAdd);
} }
/** /**
......
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
package org.jivesoftware.messenger.muc; package org.jivesoftware.messenger.muc;
import org.jivesoftware.util.NotFoundException; import org.jivesoftware.util.NotFoundException;
import org.jivesoftware.messenger.XMPPAddress;
import org.jivesoftware.messenger.ChannelHandler; import org.jivesoftware.messenger.ChannelHandler;
import org.xmpp.packet.JID;
import java.util.Iterator; import java.util.Iterator;
...@@ -47,7 +47,7 @@ public interface MUCUser extends ChannelHandler { ...@@ -47,7 +47,7 @@ public interface MUCUser extends ChannelHandler {
* *
* @return the address of the packet handler. * @return the address of the packet handler.
*/ */
public XMPPAddress getAddress(); public JID getAddress();
/** /**
* Obtain the role of the user in a particular room. * Obtain the role of the user in a particular room.
......
...@@ -16,7 +16,8 @@ import java.util.Collection; ...@@ -16,7 +16,8 @@ import java.util.Collection;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.messenger.*; import org.xmpp.packet.Message;
import org.xmpp.packet.JID;
/** /**
* Manages groupchat conversations, chatrooms, and users. This class is designed to operate * Manages groupchat conversations, chatrooms, and users. This class is designed to operate
...@@ -192,7 +193,7 @@ public interface MultiUserChatServer { ...@@ -192,7 +193,7 @@ public interface MultiUserChatServer {
* @return The chatroom for the given name. * @return The chatroom for the given name.
* @throws UnauthorizedException If the caller doesn't have permission to create a new room. * @throws UnauthorizedException If the caller doesn't have permission to create a new room.
*/ */
MUCRoom getChatRoom(String roomName, XMPPAddress userjid) throws UnauthorizedException; MUCRoom getChatRoom(String roomName, JID userjid) throws UnauthorizedException;
/** /**
* Obtains a chatroom by name. If the chatroom does not exists then null will be returned. * Obtains a chatroom by name. If the chatroom does not exists then null will be returned.
...@@ -230,7 +231,7 @@ public interface MultiUserChatServer { ...@@ -230,7 +231,7 @@ public interface MultiUserChatServer {
* *
* @param jabberID The user's normal jid, not the chat nickname jid. * @param jabberID The user's normal jid, not the chat nickname jid.
*/ */
void removeUser(XMPPAddress jabberID); void removeUser(JID jabberID);
/** /**
* Obtain a chat user by XMPPAddress. * Obtain a chat user by XMPPAddress.
...@@ -239,7 +240,7 @@ public interface MultiUserChatServer { ...@@ -239,7 +240,7 @@ public interface MultiUserChatServer {
* @return The chatuser corresponding to that XMPPAddress. * @return The chatuser corresponding to that XMPPAddress.
* @throws UserNotFoundException If the user is not found and can't be auto-created. * @throws UserNotFoundException If the user is not found and can't be auto-created.
*/ */
MUCUser getChatUser(XMPPAddress userjid) throws UserNotFoundException; MUCUser getChatUser(JID userjid) throws UserNotFoundException;
/** /**
* Broadcast a given message to all members of this chat room. The sender is always set to be * Broadcast a given message to all members of this chat room. The sender is always set to be
...@@ -271,5 +272,5 @@ public interface MultiUserChatServer { ...@@ -271,5 +272,5 @@ public interface MultiUserChatServer {
* @param message the message to log as part of the conversation in the room. * @param message the message to log as part of the conversation in the room.
* @param sender the real XMPPAddress of the sender (e.g. john@example.org). * @param sender the real XMPPAddress of the sender (e.g. john@example.org).
*/ */
void logConversation(MUCRoom room, Message message, XMPPAddress sender); void logConversation(MUCRoom room, Message message, JID sender);
} }
\ No newline at end of file
...@@ -14,8 +14,8 @@ package org.jivesoftware.messenger.muc.spi; ...@@ -14,8 +14,8 @@ package org.jivesoftware.messenger.muc.spi;
import java.util.Date; import java.util.Date;
import org.jivesoftware.messenger.muc.MUCRoom; import org.jivesoftware.messenger.muc.MUCRoom;
import org.jivesoftware.messenger.Message; import org.xmpp.packet.Message;
import org.jivesoftware.messenger.XMPPAddress; import org.xmpp.packet.JID;
/** /**
* Represents an entry in the conversation log of a room. An entry basically obtains the necessary * Represents an entry in the conversation log of a room. An entry basically obtains the necessary
...@@ -31,7 +31,7 @@ class ConversationLogEntry { ...@@ -31,7 +31,7 @@ class ConversationLogEntry {
private String body; private String body;
private XMPPAddress sender; private JID sender;
private String nickname; private String nickname;
...@@ -46,13 +46,13 @@ class ConversationLogEntry { ...@@ -46,13 +46,13 @@ class ConversationLogEntry {
* @param message the message to log as part of the conversation in the room. * @param message the message to log as part of the conversation in the room.
* @param sender the real XMPPAddress of the sender (e.g. john@example.org). * @param sender the real XMPPAddress of the sender (e.g. john@example.org).
*/ */
public ConversationLogEntry(Date date, MUCRoom room, Message message, XMPPAddress sender) { public ConversationLogEntry(Date date, MUCRoom room, Message message, JID sender) {
this.date = date; this.date = date;
this.subject = message.getSubject(); this.subject = message.getSubject();
this.body = message.getBody(); this.body = message.getBody();
this.sender = sender; this.sender = sender;
this.roomID = room.getID(); this.roomID = room.getID();
this.nickname = message.getSender().getResourcePrep(); this.nickname = message.getFrom().getResource();
} }
/** /**
...@@ -69,7 +69,7 @@ class ConversationLogEntry { ...@@ -69,7 +69,7 @@ class ConversationLogEntry {
* *
* @return the XMPP address of the logged message's sender. * @return the XMPP address of the logged message's sender.
*/ */
public XMPPAddress getSender() { public JID getSender() {
return sender; return sender;
} }
......
...@@ -12,15 +12,15 @@ ...@@ -12,15 +12,15 @@
package org.jivesoftware.messenger.muc.spi; package org.jivesoftware.messenger.muc.spi;
import org.jivesoftware.messenger.muc.*; import org.jivesoftware.messenger.muc.*;
import org.jivesoftware.messenger.IQ;
import org.jivesoftware.messenger.Message;
import org.jivesoftware.messenger.MetaDataFragment;
import org.jivesoftware.messenger.PacketRouter; import org.jivesoftware.messenger.PacketRouter;
import org.jivesoftware.messenger.Presence;
import org.jivesoftware.messenger.XMPPAddress;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.xmpp.packet.Presence;
import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.IQ;
import org.dom4j.Element;
/** /**
* Simple in-memory implementation of a role in a chatroom * Simple in-memory implementation of a role in a chatroom
...@@ -73,12 +73,12 @@ public class MUCRoleImpl implements MUCRole { ...@@ -73,12 +73,12 @@ public class MUCRoleImpl implements MUCRole {
/** /**
* The address of the person masquerading in this role. * The address of the person masquerading in this role.
*/ */
private XMPPAddress rJID; private JID rJID;
/** /**
* A fragment containing the x-extension for non-anonymous rooms. * A fragment containing the x-extension for non-anonymous rooms.
*/ */
private MetaDataFragment extendedInformation; private Element extendedInformation;
/** /**
* Create a new role. * Create a new role.
...@@ -93,13 +93,10 @@ public class MUCRoleImpl implements MUCRole { ...@@ -93,13 +93,10 @@ public class MUCRoleImpl implements MUCRole {
* @throws UnauthorizedException if the role could not be created due to security or permission * @throws UnauthorizedException if the role could not be created due to security or permission
* violations * violations
*/ */
public MUCRoleImpl(MultiUserChatServer chatserver, public MUCRoleImpl(MultiUserChatServer chatserver, MUCRoomImpl chatroom,
MUCRoomImpl chatroom, String nickname, int role, int affiliation, MUCUserImpl chatuser,
String nickname, PacketRouter packetRouter) throws UnauthorizedException
int role, {
int affiliation,
MUCUserImpl chatuser,
PacketRouter packetRouter) throws UnauthorizedException {
this.room = chatroom; this.room = chatroom;
this.nick = nickname; this.nick = nickname;
this.user = chatuser; this.user = chatuser;
...@@ -109,22 +106,22 @@ public class MUCRoleImpl implements MUCRole { ...@@ -109,22 +106,22 @@ public class MUCRoleImpl implements MUCRole {
this.affiliation = affiliation; this.affiliation = affiliation;
extendedInformation = new MetaDataFragment("http://jabber.org/protocol/muc#user", "x"); extendedInformation = new MetaDataFragment("http://jabber.org/protocol/muc#user", "x");
calculateExtendedInformation(); calculateExtendedInformation();
rJID = new XMPPAddress(room.getName(), server.getServiceName(), nick); rJID = new JID(room.getName(), server.getServiceName(), nick);
setPresence(room.createPresence(Presence.STATUS_ONLINE)); setPresence(room.createPresence(null));
} }
public Presence getPresence() { public Presence getPresence() {
return presence; return presence;
} }
public MetaDataFragment getExtendedPresenceInformation() { public Element getExtendedPresenceInformation() {
return extendedInformation; return extendedInformation;
} }
public void setPresence(Presence newPresence) { public void setPresence(Presence newPresence) {
this.presence = newPresence; this.presence = newPresence;
if (extendedInformation != null) { if (extendedInformation != null) {
presence.addFragment(extendedInformation); presence.getElement().add(extendedInformation.createCopy());
} }
} }
...@@ -144,13 +141,7 @@ public class MUCRoleImpl implements MUCRole { ...@@ -144,13 +141,7 @@ public class MUCRoleImpl implements MUCRole {
role = newRole; role = newRole;
if (MUCRole.NONE_ROLE == role) { if (MUCRole.NONE_ROLE == role) {
try { presence.setType(Presence.Type.unavailable);
presence.setAvailable(false);
presence.setVisible(false);
}
catch (UnauthorizedException e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
} }
calculateExtendedInformation(); calculateExtendedInformation();
} }
...@@ -214,7 +205,7 @@ public class MUCRoleImpl implements MUCRole { ...@@ -214,7 +205,7 @@ public class MUCRoleImpl implements MUCRole {
public void changeNickname(String nickname) { public void changeNickname(String nickname) {
this.nick = nickname; this.nick = nickname;
rJID = new XMPPAddress(room.getName(), server.getServiceName(), nick); rJID = new JID(room.getName(), server.getServiceName(), nick);
} }
public MUCUser getChatUser() { public MUCUser getChatUser() {
...@@ -225,30 +216,31 @@ public class MUCRoleImpl implements MUCRole { ...@@ -225,30 +216,31 @@ public class MUCRoleImpl implements MUCRole {
return room; return room;
} }
public XMPPAddress getRoleAddress() { public JID getRoleAddress() {
return rJID; return rJID;
} }
public void send(Presence packet) { public void send(Presence packet) {
packet.setRecipient(user.getAddress()); packet.setTo(user.getAddress());
router.route(packet); router.route(packet);
} }
public void send(Message packet) { public void send(Message packet) {
packet.setRecipient(user.getAddress()); packet.setTo(user.getAddress());
router.route(packet); router.route(packet);
} }
public void send(IQ packet) { public void send(IQ packet) {
packet.setRecipient(user.getAddress()); packet.setTo(user.getAddress());
router.route(packet); router.route(packet);
} }
/** /**
* Calculates and sets the extended presence information to add to the presence. The information * Calculates and sets the extended presence information to add to the presence.
* to add contains the user's jid, affiliation and role. * The information to add contains the user's jid, affiliation and role.
*/ */
private void calculateExtendedInformation() { private void calculateExtendedInformation() {
extendedInformation.setProperty("x.item:jid", user.getAddress().toString()); extendedInformation.setProperty("x.item:jid", user.getAddress().toString());
extendedInformation.setProperty("x.item:affiliation", getAffiliationAsString()); extendedInformation.setProperty("x.item:affiliation", getAffiliationAsString());
extendedInformation.setProperty("x.item:role", getRoleAsString()); extendedInformation.setProperty("x.item:role", getRoleAsString());
......
...@@ -22,6 +22,7 @@ import org.jivesoftware.messenger.*; ...@@ -22,6 +22,7 @@ import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserAlreadyExistsException; import org.jivesoftware.messenger.user.UserAlreadyExistsException;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.messenger.user.UserNotFoundException;
import org.xmpp.packet.*;
/** /**
* Implementation of MUCUser. There will be a MUCUser per user that is connected to one or more * Implementation of MUCUser. There will be a MUCUser per user that is connected to one or more
...@@ -35,7 +36,7 @@ public class MUCUserImpl implements MUCUser { ...@@ -35,7 +36,7 @@ public class MUCUserImpl implements MUCUser {
private MultiUserChatServer server; private MultiUserChatServer server;
/** Real system XMPPAddress for the user. */ /** Real system XMPPAddress for the user. */
private XMPPAddress realjid; private JID realjid;
/** Table: key roomName.toLowerCase(); value MUCRole. */ /** Table: key roomName.toLowerCase(); value MUCRole. */
private Map<String, MUCRole> roles = new ConcurrentHashMap<String, MUCRole>(); private Map<String, MUCRole> roles = new ConcurrentHashMap<String, MUCRole>();
...@@ -55,7 +56,7 @@ public class MUCUserImpl implements MUCUser { ...@@ -55,7 +56,7 @@ public class MUCUserImpl implements MUCUser {
* @param packetRouter the router for sending packets from this user. * @param packetRouter the router for sending packets from this user.
* @param jid the real address of the user * @param jid the real address of the user
*/ */
MUCUserImpl(MultiUserChatServerImpl chatserver, PacketRouter packetRouter, XMPPAddress jid) { MUCUserImpl(MultiUserChatServerImpl chatserver, PacketRouter packetRouter, JID jid) {
this.realjid = jid; this.realjid = jid;
this.router = packetRouter; this.router = packetRouter;
this.server = chatserver; this.server = chatserver;
...@@ -89,22 +90,21 @@ public class MUCUserImpl implements MUCUser { ...@@ -89,22 +90,21 @@ public class MUCUserImpl implements MUCUser {
* Generate a conflict packet to indicate that the nickname being requested/used is already in * Generate a conflict packet to indicate that the nickname being requested/used is already in
* use by another user. * use by another user.
* *
* @param packet The packet to be bounced. * @param packet the packet to be bounced.
*/ */
private void sendErrorPacket(XMPPPacket packet, XMPPError.Code errorCode) { private void sendErrorPacket(Packet packet, PacketError error) {
packet = (XMPPPacket) packet.createDeepCopy(); packet = packet.createCopy();
packet.setError(errorCode); packet.setError(error);
XMPPAddress sender = packet.getSender(); packet.setFrom(packet.getTo());
packet.setSender(packet.getRecipient()); packet.setTo(packet.getFrom());
packet.setRecipient(sender);
router.route(packet); router.route(packet);
} }
public XMPPAddress getAddress() { public JID getAddress() {
return realjid; return realjid;
} }
public void process(XMPPPacket packet) throws UnauthorizedException, PacketException { public void process(Packet packet) throws UnauthorizedException, PacketException {
if (packet instanceof IQ) { if (packet instanceof IQ) {
process((IQ)packet); process((IQ)packet);
} }
...@@ -132,8 +132,8 @@ public class MUCUserImpl implements MUCUser { ...@@ -132,8 +132,8 @@ public class MUCUserImpl implements MUCUser {
*/ */
public void process(Message packet) { public void process(Message packet) {
lastPacketTime = System.currentTimeMillis(); lastPacketTime = System.currentTimeMillis();
XMPPAddress recipient = packet.getRecipient(); JID recipient = packet.getTo();
String group = recipient.getName(); String group = recipient.getNode();
if (group == null) { if (group == null) {
// Ignore packets to the groupchat server // Ignore packets to the groupchat server
// In the future, we'll need to support TYPE_IQ queries to the server for MUC // In the future, we'll need to support TYPE_IQ queries to the server for MUC
...@@ -145,14 +145,13 @@ public class MUCUserImpl implements MUCUser { ...@@ -145,14 +145,13 @@ public class MUCUserImpl implements MUCUser {
if (role == null) { if (role == null) {
if (server.hasChatRoom(group)) { if (server.hasChatRoom(group)) {
boolean declinedInvitation = false; boolean declinedInvitation = false;
XMPPDOMFragment userInfo = null; Element userInfo = null;
if (Message.NORMAL == packet.getType()) { if (Message.Type.normal == packet.getType()) {
// An user that is not an occupant could be declining an invitation // An user that is not an occupant could be declining an invitation
userInfo = (XMPPDOMFragment) packet.getFragment( userInfo = packet.getChildElement(
"x", "x", "http://jabber.org/protocol/muc#user");
"http://jabber.org/protocol/muc#user");
if (userInfo != null if (userInfo != null
&& userInfo.getRootElement().element("decline") != null) { && userInfo.element("decline") != null) {
// A user has declined an invitation to a room // A user has declined an invitation to a room
// WARNING: Potential fraud if someone fakes the "from" of the // WARNING: Potential fraud if someone fakes the "from" of the
// message with the JID of a member and sends a "decline" // message with the JID of a member and sends a "decline"
...@@ -160,12 +159,11 @@ public class MUCUserImpl implements MUCUser { ...@@ -160,12 +159,11 @@ public class MUCUserImpl implements MUCUser {
} }
} }
if (declinedInvitation) { if (declinedInvitation) {
Element info = userInfo.getRootElement().element("decline"); Element info = userInfo.element("decline");
server.getChatRoom(group).sendInvitationRejection( server.getChatRoom(group).sendInvitationRejection(
info.attributeValue("to"), info.attributeValue("to"),
info.elementTextTrim("reason"), info.elementTextTrim("reason"),
packet.getSender(), packet.getFrom());
packet.getOriginatingSession());
} }
else { else {
// The sender is not an occupant of the room // The sender is not an occupant of the room
......
...@@ -34,6 +34,10 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -34,6 +34,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.Element; import org.dom4j.Element;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
import org.xmpp.packet.Packet;
import org.xmpp.packet.Message;
/** /**
* Implements the chat server as a cached memory resident chat server. The server is also * Implements the chat server as a cached memory resident chat server. The server is also
...@@ -92,7 +96,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -92,7 +96,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
* the chat service's hostname * the chat service's hostname
*/ */
private String chatServiceName = null; private String chatServiceName = null;
private XMPPAddress chatServiceAddress = null; private JID chatServiceAddress = null;
/** /**
* chatrooms managed by this manager, table: key room name (String); value ChatRoom * chatrooms managed by this manager, table: key room name (String); value ChatRoom
...@@ -102,7 +106,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -102,7 +106,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
/** /**
* chat users managed by this manager, table: key user jid (XMPPAddress); value ChatUser * chat users managed by this manager, table: key user jid (XMPPAddress); value ChatUser
*/ */
private Map<XMPPAddress, MUCUser> users = new ConcurrentHashMap<XMPPAddress, MUCUser>(); private Map<JID, MUCUser> users = new ConcurrentHashMap<JID, MUCUser>();
private HistoryStrategy historyStrategy; private HistoryStrategy historyStrategy;
private RoutingTable routingTable = null; private RoutingTable routingTable = null;
...@@ -196,7 +200,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -196,7 +200,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
room = role.getChatRoom(); room = role.getChatRoom();
try { try {
kickedPresence = kickedPresence =
room.kickOccupant(user.getAddress().toStringPrep(), null, null); room.kickOccupant(user.getAddress(), null, null);
// Send the updated presence to the room occupants // Send the updated presence to the room occupants
room.send(kickedPresence); room.send(kickedPresence);
} }
...@@ -254,7 +258,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -254,7 +258,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
} }
} }
public MUCRoom getChatRoom(String roomName, XMPPAddress userjid) throws UnauthorizedException { public MUCRoom getChatRoom(String roomName, JID userjid) throws UnauthorizedException {
MUCRoom room = null; MUCRoom room = null;
synchronized (rooms) { synchronized (rooms) {
room = rooms.get(roomName.toLowerCase()); room = rooms.get(roomName.toLowerCase());
...@@ -270,15 +274,15 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -270,15 +274,15 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
// The room does not exist so check for creation permissions // The room does not exist so check for creation permissions
// Room creation is always allowed for sysadmin // Room creation is always allowed for sysadmin
if (isRoomCreationRestricted() && if (isRoomCreationRestricted() &&
!sysadmins.contains(userjid.toBareStringPrep())) { !sysadmins.contains(userjid.toBareJID())) {
// The room creation is only allowed for certain JIDs // The room creation is only allowed for certain JIDs
if (!allowedToCreate.contains(userjid.toBareStringPrep())) { if (!allowedToCreate.contains(userjid.toBareJID())) {
// The user is not in the list of allowed JIDs to create a room so raise // The user is not in the list of allowed JIDs to create a room so raise
// an exception // an exception
throw new UnauthorizedException(); throw new UnauthorizedException();
} }
} }
room.addFirstOwner(userjid.toBareStringPrep()); room.addFirstOwner(userjid.toBareJID());
} }
rooms.put(roomName.toLowerCase(), room); rooms.put(roomName.toLowerCase(), room);
} }
...@@ -314,7 +318,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -314,7 +318,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
return historyStrategy; return historyStrategy;
} }
public void removeUser(XMPPAddress jabberID) { public void removeUser(JID jabberID) {
MUCUser user = users.remove(jabberID); MUCUser user = users.remove(jabberID);
if (user != null) { if (user != null) {
Iterator<MUCRole> roles = user.getRoles(); Iterator<MUCRole> roles = user.getRoles();
...@@ -330,7 +334,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -330,7 +334,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
} }
} }
public MUCUser getChatUser(XMPPAddress userjid) throws UserNotFoundException { public MUCUser getChatUser(JID userjid) throws UserNotFoundException {
if (router == null) { if (router == null) {
throw new IllegalStateException("Not initialized"); throw new IllegalStateException("Not initialized");
} }
...@@ -585,7 +589,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -585,7 +589,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
if (serverName != null) { if (serverName != null) {
chatServiceName += "." + serverName; chatServiceName += "." + serverName;
} }
chatServiceAddress = new XMPPAddress(null, chatServiceName, null); chatServiceAddress = new JID(null, chatServiceName, null);
// Run through the users every 5 minutes after a 5 minutes server startup delay (default // Run through the users every 5 minutes after a 5 minutes server startup delay (default
// values) // values)
userTimeoutTask = new UserTimeoutTask(); userTimeoutTask = new UserTimeoutTask();
...@@ -619,16 +623,16 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -619,16 +623,16 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
} }
} }
public XMPPAddress getAddress() { public JID getAddress() {
if (chatServiceAddress == null) { if (chatServiceAddress == null) {
throw new IllegalStateException("Not initialized"); throw new IllegalStateException("Not initialized");
} }
return chatServiceAddress; return chatServiceAddress;
} }
public void process(XMPPPacket packet) { public void process(Packet packet) {
try { try {
MUCUser user = getChatUser(packet.getSender()); MUCUser user = getChatUser(packet.getFrom());
user.process(packet); user.process(packet);
} }
catch (Exception e) { catch (Exception e) {
...@@ -640,7 +644,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -640,7 +644,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
return totalChatTime; return totalChatTime;
} }
public void logConversation(MUCRoom room, Message message, XMPPAddress sender) { public void logConversation(MUCRoom room, Message message, JID sender) {
logQueue.add(new ConversationLogEntry(new Date(), room, message, sender)); logQueue.add(new ConversationLogEntry(new Date(), room, message, sender));
} }
...@@ -675,7 +679,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -675,7 +679,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
return items.iterator(); return items.iterator();
} }
public Iterator getIdentities(String name, String node, XMPPAddress senderJID) { public Iterator getIdentities(String name, String node, JID senderJID) {
// TODO Improve performance by not creating objects each time // TODO Improve performance by not creating objects each time
ArrayList identities = new ArrayList(); ArrayList identities = new ArrayList();
if (name == null && node == null) { if (name == null && node == null) {
...@@ -703,7 +707,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -703,7 +707,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
// Answer reserved nickname for the sender of the disco request in the requested room // Answer reserved nickname for the sender of the disco request in the requested room
MUCRoom room = getChatRoom(name); MUCRoom room = getChatRoom(name);
if (room != null) { if (room != null) {
String reservedNick = room.getReservedNickname(senderJID.toBareStringPrep()); String reservedNick = room.getReservedNickname(senderJID.toBareJID());
if (reservedNick != null) { if (reservedNick != null) {
Element identity = DocumentHelper.createElement("identity"); Element identity = DocumentHelper.createElement("identity");
identity.addAttribute("category", "conference"); identity.addAttribute("category", "conference");
...@@ -717,7 +721,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -717,7 +721,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
return identities.iterator(); return identities.iterator();
} }
public Iterator getFeatures(String name, String node, XMPPAddress senderJID) { public Iterator getFeatures(String name, String node, JID senderJID) {
ArrayList features = new ArrayList(); ArrayList features = new ArrayList();
if (name == null && node == null) { if (name == null && node == null) {
// Answer the features of the MUC service // Answer the features of the MUC service
...@@ -768,7 +772,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -768,7 +772,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
return features.iterator(); return features.iterator();
} }
public XDataForm getExtendedInfo(String name, String node, XMPPAddress senderJID) { public XDataForm getExtendedInfo(String name, String node, JID senderJID) {
if (name != null && node == null) { if (name != null && node == null) {
// Answer the extended info of a given room // Answer the extended info of a given room
// TODO lock the room while gathering this info??? // TODO lock the room while gathering this info???
...@@ -808,7 +812,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -808,7 +812,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
return null; return null;
} }
public boolean hasInfo(String name, String node, XMPPAddress senderJID) public boolean hasInfo(String name, String node, JID senderJID)
throws UnauthorizedException { throws UnauthorizedException {
if (name == null && node == node) { if (name == null && node == node) {
// We always have info about the MUC service // We always have info about the MUC service
...@@ -825,7 +829,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -825,7 +829,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
return false; return false;
} }
public Iterator getItems(String name, String node, XMPPAddress senderJID) public Iterator getItems(String name, String node, JID senderJID)
throws UnauthorizedException { throws UnauthorizedException {
List answer = new ArrayList(); List answer = new ArrayList();
if (name == null && node == null) { if (name == null && node == null) {
...@@ -834,7 +838,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -834,7 +838,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
for (MUCRoom room : rooms.values()) { for (MUCRoom room : rooms.values()) {
if (room.isPublicRoom()) { if (room.isPublicRoom()) {
item = DocumentHelper.createElement("item"); item = DocumentHelper.createElement("item");
item.addAttribute("jid", room.getRole().getRoleAddress().toStringPrep()); item.addAttribute("jid", room.getRole().getRoleAddress().toString());
item.addAttribute("name", room.getNaturalLanguageName()); item.addAttribute("name", room.getNaturalLanguageName());
answer.add(item); answer.add(item);
...@@ -849,7 +853,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha ...@@ -849,7 +853,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
for (MUCRole role : room.getOccupants()) { for (MUCRole role : room.getOccupants()) {
// TODO Should we filter occupants that are invisible (presence is not broadcasted)? // TODO Should we filter occupants that are invisible (presence is not broadcasted)?
item = DocumentHelper.createElement("item"); item = DocumentHelper.createElement("item");
item.addAttribute("jid", role.getRoleAddress().toStringPrep()); item.addAttribute("jid", role.getRoleAddress().toString());
answer.add(item); answer.add(item);
} }
......
...@@ -16,6 +16,10 @@ import org.jivesoftware.util.Log; ...@@ -16,6 +16,10 @@ import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.*; import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.audit.Auditor; import org.jivesoftware.messenger.audit.Auditor;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.Presence;
import org.xmpp.packet.Message;
import org.xmpp.packet.IQ;
import java.io.EOFException; import java.io.EOFException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.Socket; import java.net.Socket;
...@@ -113,16 +117,10 @@ public class SocketReadThread extends Thread { ...@@ -113,16 +117,10 @@ public class SocketReadThread extends Thread {
Presence presence = session.getPresence(); Presence presence = session.getPresence();
if (presence != null) { if (presence != null) {
// Simulate an unavailable presence sent by the user. // Simulate an unavailable presence sent by the user.
Presence packet = (Presence) presence.createDeepCopy(); Presence packet = presence.createCopy();
packet.setType(Presence.UNAVAILABLE); packet.setType(Presence.Type.unavailable);
try { packet.setType(null);
packet.setAvailable(false); packet.setFrom(session.getAddress());
packet.setVisible(false);
}
catch (UnauthorizedException e) {}
packet.setOriginatingSession(session);
packet.setSender(session.getAddress());
packet.setSending(false);
router.route(packet); router.route(packet);
clearSignout = true; clearSignout = true;
} }
...@@ -190,29 +188,23 @@ public class SocketReadThread extends Thread { ...@@ -190,29 +188,23 @@ public class SocketReadThread extends Thread {
if ("message".equals(tag)) { if ("message".equals(tag)) {
Message packet = packetFactory.getMessage(xpp); Message packet = packetFactory.getMessage(xpp);
packet.setOriginatingSession(session); packet.setFrom(session.getAddress());
packet.setSender(session.getAddress());
packet.setSending(false);
auditor.audit(packet); auditor.audit(packet);
router.route(packet); router.route(packet);
session.incrementClientPacketCount(); session.incrementClientPacketCount();
} }
else if ("presence".equals(tag)) { else if ("presence".equals(tag)) {
Presence packet = packetFactory.getPresence(xpp); Presence packet = packetFactory.getPresence(xpp);
packet.setOriginatingSession(session); packet.setFrom(session.getAddress());
packet.setSender(session.getAddress());
packet.setSending(false);
auditor.audit(packet); auditor.audit(packet);
router.route(packet); router.route(packet);
session.incrementClientPacketCount(); session.incrementClientPacketCount();
// Update the flag that indicates if the user made a clean sign out // Update the flag that indicates if the user made a clean sign out
clearSignout = (Presence.UNAVAILABLE == packet.getType() ? true : false); clearSignout = (Presence.Type.unavailable == packet.getType() ? true : false);
} }
else if ("iq".equals(tag)) { else if ("iq".equals(tag)) {
IQ packet = packetFactory.getIQ(xpp); IQ packet = packetFactory.getIQ(xpp);
packet.setOriginatingSession(session); packet.setFrom(session.getAddress());
packet.setSender(session.getAddress());
packet.setSending(false);
auditor.audit(packet); auditor.audit(packet);
router.route(packet); router.route(packet);
session.incrementClientPacketCount(); session.incrementClientPacketCount();
......
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.spi;
import org.jivesoftware.messenger.XMPPFragment;
import java.util.*;
abstract public class AbstractFragment implements XMPPFragment {
protected LinkedList fragments;
protected String namespace = "";
protected String name = "";
/**
* <p>Returns a namespace associated with this meta-data or null if none has been associated.</p>
*
* @return The namespace associated with this meta-data
*/
public String getNamespace() {
return namespace;
}
/**
* <p>Sets a namespace associated with this meta-data or null if none has been associated.</p>
*
* @param namespace The namespace associated with this meta-data
*/
public void setNamespace(String namespace) {
this.namespace = namespace;
}
/**
* <p>Returns a name associated with this meta-data or null if none has been associated.</p>
*
* @return The name associated with this meta-data
*/
public String getName() {
return name;
}
/**
* <p>Sets a namespace associated with this meta-data or null if none has been associated.</p>
*
* @param name The namespace associated with this meta-data
*/
public void setName(String name) {
this.name = name;
}
public int getSize() {
// estimate it to be something smaller than a packet
return 20;
}
public void addFragment(XMPPFragment fragment) {
if (fragments == null) {
fragments = new LinkedList();
}
else {
// inspect for circular parent-child relationship
if (fragment.equals(this)) {
throw new IllegalArgumentException("Circular parent-child relationship");
}
Iterator frags = fragment.getFragments();
while (frags.hasNext()) {
if (frags.next().equals(this)) {
throw new IllegalArgumentException("Circular parent-child relationship");
}
}
}
fragments.addLast(fragment);
}
public Iterator getFragments() {
if (fragments == null) {
return Collections.EMPTY_LIST.iterator();
}
else {
return fragments.iterator();
}
}
public XMPPFragment getFragment(String name, String namespace) {
if (fragments == null) {
return null;
}
XMPPFragment frag;
for (Iterator frags = fragments.iterator(); frags.hasNext();) {
frag = (XMPPFragment)frags.next();
if (name.equals(frag.getName()) && namespace.equals(frag.getNamespace())) {
return frag;
}
}
return null;
}
public void clearFragments() {
if (fragments != null) {
fragments.clear();
}
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.spi;
import org.jivesoftware.messenger.*;
import java.util.Iterator;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
abstract public class AbstractPacket extends AbstractFragment implements XMPPPacket {
XMPPPacket.RoutePriority routePriority = XMPPPacket.RoutePriority.normal;
XMPPError error;
String id;
Session session;
XMPPAddress sender;
XMPPAddress recipient;
XMPPPacket.Type type;
protected boolean sending;
public boolean isSending() {
return sending;
}
public void setSending(boolean isSending) {
this.sending = isSending;
}
public XMPPPacket.RoutePriority getRoutePriority() {
return routePriority;
}
public void setRoutePriority(XMPPPacket.RoutePriority priority) {
routePriority = priority;
}
public void setError(XMPPError.Code errorCode) {
this.error = new XMPPError(errorCode);
type = ERROR;
}
public XMPPError getError() {
return error;
}
public String getID() {
return id;
}
public void setID(String id) {
this.id = id;
}
public void setOriginatingSession(Session session) {
this.session = session;
}
public Session getOriginatingSession() {
return session;
}
public void setSender(XMPPAddress sender) {
this.sender = sender;
}
public XMPPAddress getSender() {
return sender;
}
public void setRecipient(XMPPAddress recipient) {
this.recipient = recipient;
}
public XMPPAddress getRecipient() {
return recipient;
}
public XMPPPacket.Type typeFromString(String type) {
if (ERROR.toString().equals(type)) {
return ERROR;
}
return null;
}
public void setType(XMPPPacket.Type type) {
this.type = type;
}
public XMPPPacket.Type getType() {
return type;
}
protected void copyAttributes(AbstractPacket packet) {
packet.routePriority = routePriority;
packet.error = error;
packet.id = id;
packet.session = session;
packet.sender = sender;
packet.recipient = recipient;
packet.type = type;
}
protected void deepCopy(AbstractPacket packet) {
copyAttributes(packet);
Iterator frags = getFragments();
while (frags.hasNext()) {
packet.addFragment(((XMPPFragment)frags.next()).createDeepCopy());
}
}
/**
* <p>Sends the opening tag and the error sub-packet (if applicable).</p>
* <p>The serializer is left ready to send the next subpacket.</p>
*
* @param xmlSerializer the serializer to use.
* @param version the XMPP version to follow.
* @param elementName the element name of the packet (iq,message,presence).
* @param ignoreType the type (if any) to ignore (Message.NORMAL,Presence.AVAILABLE) or
* null to ignore
*/
public void sendRoot(XMLStreamWriter xmlSerializer, int version, String elementName,
XMPPPacket.Type ignoreType) throws XMLStreamException
{
xmlSerializer.writeStartElement("jabber:client", elementName);
if (sender != null && sender.getHost() != null) {
xmlSerializer.writeAttribute("from", sender.toString());
}
else {
if (session != null
&& session.getAddress() != null
&& session.getAddress().getHost() != null) {
xmlSerializer.writeAttribute("from", session.getAddress().toString());
}
}
if (recipient != null && recipient.getHost() != null) {
xmlSerializer.writeAttribute("to", recipient.toString());
}
if (id != null && !"".equals(id)) {
xmlSerializer.writeAttribute("id", id);
}
if (type != null && type != ignoreType) {
xmlSerializer.writeAttribute("type", type.toString());
if (type.equals(ERROR) && error != null) {
error.send(xmlSerializer, version);
}
}
}
public int getSize() {
// No sense even trying to calculate it, just provide a rough average packet size
return 50;
}
/**
* <p>Parses the standard root element attributes without moving
* the xpp position and sets the current packet up for the given
* packet type.</p>
*
* @param xpp The XML pull parser to obtain the root attributes
*/
protected void parseRootAttributes(XMLStreamReader xpp) {
setSender(XMPPAddress.parseJID(xpp.getAttributeValue("", "from")));
setRecipient(XMPPAddress.parseJID(xpp.getAttributeValue("", "to")));
setType(typeFromString(xpp.getAttributeValue("", "type")));
setID(xpp.getAttributeValue("", "id"));
}
}
\ No newline at end of file
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.spi;
import org.jivesoftware.messenger.Session;
import org.jivesoftware.messenger.XMPPAddress;
import org.jivesoftware.messenger.XMPPError;
import org.jivesoftware.messenger.XMPPPacket;
import org.jivesoftware.messenger.auth.AuthToken;
import org.jivesoftware.messenger.auth.Permissions;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
abstract public class AbstractPacketProxy extends FragmentProxy implements XMPPPacket {
protected XMPPPacket packet;
public AbstractPacketProxy(XMPPPacket packet, AuthToken token, Permissions permissions) {
super(packet, token, permissions);
this.packet = packet;
}
public boolean isSending() {
return packet.isSending();
}
public void setSending(boolean isSending) {
packet.setSending(isSending);
}
public XMPPPacket.RoutePriority getRoutePriority() {
return packet.getRoutePriority();
}
public void setRoutePriority(XMPPPacket.RoutePriority priority) {
packet.setRoutePriority(priority);
}
public void setError(XMPPError.Code errorCode) {
packet.setError(errorCode);
}
public XMPPError getError() {
return packet.getError();
}
public String getID() {
return packet.getID();
}
public void setID(String id) {
packet.setID(id);
}
public void setOriginatingSession(Session session) {
packet.setOriginatingSession(session);
}
public XMPPAddress getRecipient() {
return packet.getRecipient();
}
public void setRecipient(XMPPAddress recipient) {
packet.setRecipient(recipient);
}
public void setSender(XMPPAddress sender) {
packet.setSender(sender);
}
public XMPPAddress getSender() {
return packet.getSender();
}
public Session getOriginatingSession() {
return packet.getOriginatingSession();
}
public void parse(XMLStreamReader xpp) throws XMLStreamException {
packet.parse(xpp);
}
public XMPPPacket.Type typeFromString(String type) {
return packet.typeFromString(type);
}
public void setType(XMPPPacket.Type type) {
packet.setType(type);
}
public XMPPPacket.Type getType() {
return packet.getType();
}
}
...@@ -19,6 +19,8 @@ import org.jivesoftware.util.Log; ...@@ -19,6 +19,8 @@ import org.jivesoftware.util.Log;
import org.jivesoftware.util.Version; import org.jivesoftware.util.Version;
import org.jivesoftware.messenger.*; import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.JID;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.*; import java.util.*;
...@@ -63,19 +65,19 @@ public class BasicServer extends BasicModule implements XMPPServer, BasicServerM ...@@ -63,19 +65,19 @@ public class BasicServer extends BasicModule implements XMPPServer, BasicServerM
return new XMPPServerInfoImpl(name, version, startDate, stopDate, ports); return new XMPPServerInfoImpl(name, version, startDate, stopDate, ports);
} }
public boolean isLocal(XMPPAddress jid) { public boolean isLocal(JID jid) {
boolean local = false; boolean local = false;
if (jid != null && name != null && name.equalsIgnoreCase(jid.getHost())) { if (jid != null && name != null && name.equalsIgnoreCase(jid.getDomain())) {
local = true; local = true;
} }
return local; return local;
} }
public XMPPAddress createAddress(String username, String resource) { public JID createJID(String username, String resource) {
return new XMPPAddress(username, name, resource); return new JID(username, name, resource);
} }
private Session serverSession = new ServerSession(new XMPPAddress(null, name, null), private Session serverSession = new ServerSession(new JID(null, name, null),
new BasicStreamIDFactory().createStreamID(name)); new BasicStreamIDFactory().createStreamID(name));
public Session getSession() { public Session getSession() {
...@@ -95,7 +97,7 @@ public class BasicServer extends BasicModule implements XMPPServer, BasicServerM ...@@ -95,7 +97,7 @@ public class BasicServer extends BasicModule implements XMPPServer, BasicServerM
name = "127.0.0.1"; name = "127.0.0.1";
} }
version = new Version(2, 0, 1, Version.ReleaseStatus.Release, -1); version = new Version(2, 1, 0, Version.ReleaseStatus.Beta, -1);
initialized = true; initialized = true;
} }
catch (UnauthorizedException e) { catch (UnauthorizedException e) {
......
This diff is collapsed.
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.spi;
import org.jivesoftware.messenger.IQ;
import org.jivesoftware.messenger.XMPPFragment;
import org.jivesoftware.messenger.auth.AuthToken;
import org.jivesoftware.messenger.auth.Permissions;
import org.dom4j.Element;
public class IQProxy extends AbstractPacketProxy implements IQ {
protected IQ iq;
public IQProxy(IQ iq, AuthToken authToken, Permissions permissions) {
super(iq, authToken, permissions);
this.iq = iq;
}
public String getChildNamespace() {
return iq.getChildNamespace();
}
public void setChildNamespace(String namespace) {
iq.setChildNamespace(namespace);
}
public String getChildName() {
return iq.getChildName();
}
public void setChildName(String name) {
iq.setChildName(name);
}
public XMPPFragment getChildFragment() {
return iq.getChildFragment();
}
public void setChildFragment(XMPPFragment fragment) {
iq.setChildFragment(fragment);
}
public IQ createResult(Element body) {
return iq.createResult(body);
}
public IQ createResult() {
return iq.createResult();
}
}
...@@ -56,8 +56,8 @@ public class XMPPServerProxy implements XMPPServer { ...@@ -56,8 +56,8 @@ public class XMPPServerProxy implements XMPPServer {
return server.isLocal(jid); return server.isLocal(jid);
} }
public XMPPAddress createAddress(String username, String resource) { public XMPPAddress createJID(String username, String resource) {
return server.createAddress(username, resource); return server.createJID(username, resource);
} }
public Session getSession() throws UnauthorizedException { public Session getSession() throws UnauthorizedException {
......
...@@ -206,7 +206,7 @@ public class CachedRosterImpl extends BasicRoster implements CachedRoster { ...@@ -206,7 +206,7 @@ public class CachedRosterImpl extends BasicRoster implements CachedRoster {
if (server == null) { if (server == null) {
server = (XMPPServer)ServiceLookupFactory.getLookup().lookup(XMPPServer.class); server = (XMPPServer)ServiceLookupFactory.getLookup().lookup(XMPPServer.class);
} }
XMPPAddress recipient = server.createAddress(username, null); XMPPAddress recipient = server.createJID(username, null);
roster.setRecipient(recipient); roster.setRecipient(recipient);
roster.setOriginatingSession(server.getSession()); roster.setOriginatingSession(server.getSession());
if (sessionManager == null) { if (sessionManager == null) {
......
...@@ -111,7 +111,7 @@ public class OfflineMessageStrategyImpl extends BasicModule implements OfflineMe ...@@ -111,7 +111,7 @@ public class OfflineMessageStrategyImpl extends BasicModule implements OfflineMe
Message response = packetFactory.getMessage(); Message response = packetFactory.getMessage();
response.setOriginatingSession(xmppServer.getSession()); response.setOriginatingSession(xmppServer.getSession());
response.setRecipient(message.getSender()); response.setRecipient(message.getSender());
response.setSender(xmppServer.createAddress(null, null)); response.setSender(xmppServer.createJID(null, null));
response.setBody("Message could not be delivered to " + message.getRecipient() + ". User is offline or unreachable."); response.setBody("Message could not be delivered to " + message.getRecipient() + ". User is offline or unreachable.");
message.getOriginatingSession().getConnection().deliver(response); message.getOriginatingSession().getConnection().deliver(response);
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
<%@ page import="java.io.*, <%@ page import="java.io.*,
org.jivesoftware.util.ParamUtils, org.jivesoftware.util.ParamUtils,
org.jivesoftware.util.Version,
org.jivesoftware.messenger.JiveGlobals, org.jivesoftware.messenger.JiveGlobals,
org.jivesoftware.messenger.auth.UnauthorizedException, org.jivesoftware.messenger.auth.UnauthorizedException,
org.jivesoftware.messenger.user.UserNotFoundException, org.jivesoftware.messenger.user.UserNotFoundException,
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
org.jivesoftware.messenger.container.ServiceLookupFactory, org.jivesoftware.messenger.container.ServiceLookupFactory,
org.jivesoftware.messenger.container.ServiceLookup, org.jivesoftware.messenger.container.ServiceLookup,
org.jivesoftware.messenger.JiveGlobals, org.jivesoftware.messenger.JiveGlobals,
org.jivesoftware.util.Version,
org.jivesoftware.util.Log, org.jivesoftware.util.Log,
org.jivesoftware.admin.AdminConsole" org.jivesoftware.admin.AdminConsole"
errorPage="error.jsp" errorPage="error.jsp"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment