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 @@
<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/whack.jar!/" />
<root url="jar://$PROJECT_DIR$/build/lib/merge/whack.jar!/" />
<root url="jar://$PROJECT_DIR$/build/lib/merge/jdic.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
......
......@@ -14,6 +14,7 @@ package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.LocaleUtils;
import org.xmpp.packet.Packet;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
......@@ -38,7 +39,7 @@ import java.util.concurrent.LinkedBlockingQueue;
*
* @author Matt Tucker
*/
public class Channel<T extends XMPPPacket> {
public class Channel<T extends Packet> {
private String name;
private ChannelHandler channelHandler;
......@@ -83,6 +84,7 @@ public class Channel<T extends XMPPPacket> {
catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
try {
packet.getOriginatingSession().getConnection().close();
}
catch (UnauthorizedException e1) {
......
......@@ -12,13 +12,14 @@
package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.Packet;
/**
* Interface to handle packets delivered by Channels.
*
* @author Matt Tucker
*/
public interface ChannelHandler<T extends XMPPPacket> {
public interface ChannelHandler<T extends Packet> {
/**
* Process an XMPP packet.
......
package org.jivesoftware.messenger;
import org.xmpp.packet.Packet;
public interface Component {
void processPacket(XMPPPacket packet);
void processPacket(Packet packet);
}
package org.jivesoftware.messenger;
import java.io.StringReader;
import java.util.Map;
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.container.ServiceLookupFactory;
import org.jivesoftware.messenger.spi.PacketFactoryImpl;
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.StringUtils;
import org.xmpp.packet.Packet;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
/**
* <p>Manages the registration and delegation of Components.</p>
......@@ -29,7 +23,7 @@ import org.xmpp.packet.Packet;
public class ComponentManager {
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;
private final static Object LOCK = new Object();
......@@ -110,7 +104,7 @@ public class ComponentManager {
* @param prober the jid probing.
* @param probee the presence being probed.
*/
public void addPresenceRequest(XMPPAddress prober, XMPPAddress probee) {
public void addPresenceRequest(JID prober, JID probee) {
presenceMap.put(prober, probee);
}
......@@ -120,7 +114,7 @@ public class ComponentManager {
*
* @param packet the packet to send.
*/
public void sendPacket(XMPPPacket packet) {
public void sendPacket(Packet packet) {
PacketRouter router;
try {
router = (PacketRouterImpl)ServiceLookupFactory.getLookup().lookup(PacketRouterImpl.class);
......@@ -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) {
jid = jid.trim().toLowerCase();
return jid;
}
private void checkPresences() {
for (XMPPAddress prober : presenceMap.keySet()) {
XMPPAddress probee = presenceMap.get(prober);
for (JID prober : presenceMap.keySet()) {
JID probee = presenceMap.get(prober);
Component component = getComponent(probee.toBareStringPrep());
Component component = getComponent(probee.toBareJID());
if (component != null) {
Presence presence = new PresenceImpl();
presence.setSender(prober);
presence.setRecipient(probee);
Presence presence = new Presence();
presence.setFrom(prober);
presence.setTo(probee);
component.processPacket(presence);
// No reason to hold onto prober reference.
......@@ -178,53 +148,4 @@ public class ComponentManager {
}
}
}
/**
* 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;
}
}
}
}
\ No newline at end of file
......@@ -12,6 +12,8 @@
package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.Packet;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.xml.stream.XMLStreamException;
......@@ -128,5 +130,5 @@ public interface Connection {
* @throws UnauthorizedException If caller doesn't have permission to access this resource
* @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 @@
package org.jivesoftware.messenger;
import org.xmpp.packet.IQ;
/**
* <p>Route iq packets throughout the server.</p>
* <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 @@
package org.jivesoftware.messenger;
import org.xmpp.packet.Message;
/**
* <p>Route message packets throughout the server.</p>
* <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 @@
package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserNotFoundException;
import java.util.Iterator;
import org.jivesoftware.database.SequenceManager;
import org.jivesoftware.database.DbConnectionManager;
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
......@@ -21,40 +28,154 @@ import java.util.Iterator;
* 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
* 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
*/
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
* later delivery.
* Adds a message to this message store. Messages will be stored and made
* available for later delivery.
*
* @param message The message to store (messages are standard XMPP message XML)
* @throws UnauthorizedException If the user is not allowed to store messages, or they have exceeded their quota
* @param message the message to store.
*/
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>
* <p>Remove messages using the iterator.remove() method. Otherwise
* messages stay in the message store and will be available to other
* users of getMessages().</p>
* Returns a Collection of all messages in the store for a user.
* Messages are deleted after being selected from the database.
*
* @param username the username of the user who's messages you'd like to receive
* @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
* @return The approximate size of messages stored in bytes
* @param username the username of the user.
* @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;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserNotFoundException;
import org.xmpp.packet.Message;
/**
* <p>Configures and controls the server's offline message storage strategy.</p>
......
......@@ -12,6 +12,8 @@
package org.jivesoftware.messenger;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.Packet;
import javax.xml.stream.XMLStreamException;
/**
......@@ -32,6 +34,6 @@ public interface PacketDeliverer {
* @param packet The packet to route
* @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;
}
......@@ -11,6 +11,10 @@
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.XMLStreamReader;
......
......@@ -11,6 +11,8 @@
package org.jivesoftware.messenger;
import org.xmpp.packet.Packet;
/**
* <p>An uber router that can handle any packet type.</p>
* <p>The interface is provided primarily as a convenience for services
......@@ -30,5 +32,5 @@ public interface PacketRouter extends IQRouter, MessageRouter, PresenceRouter {
* @throws NullPointerException If the packet is null
* @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;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.User;
import org.xmpp.packet.Presence;
import org.xmpp.packet.JID;
import java.util.Collection;
/**
......@@ -106,11 +109,10 @@ public interface PresenceManager {
* servlet session id.
*
* @param user the user to create a presence for.
* @param uid a unique string.
* @return the presence for 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.
......@@ -126,7 +128,7 @@ public interface PresenceManager {
* @param jid the user to set to be offline.
* @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.
......@@ -134,7 +136,7 @@ public interface PresenceManager {
* @param prober The user requesting the probe
* @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.
......@@ -142,5 +144,5 @@ public interface PresenceManager {
* @param prober The user requesting the probe
* @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 @@
package org.jivesoftware.messenger;
import org.xmpp.packet.JID;
/**
*
*
......@@ -26,5 +28,5 @@ public interface RoutableChannelHandler extends ChannelHandler {
*
* @return the XMPP address.
*/
public XMPPAddress getAddress();
public JID getAddress();
}
......@@ -11,6 +11,8 @@
package org.jivesoftware.messenger;
import org.xmpp.packet.JID;
import java.util.Iterator;
/**
......@@ -83,7 +85,7 @@ public interface RoutingTable {
* @param destination The destination object for this route
* @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>
......@@ -93,7 +95,7 @@ public interface RoutingTable {
* @return The handler corresponding to the route, or null indicating no route exists
* @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>
......@@ -103,7 +105,7 @@ public interface RoutingTable {
* @param node The address we want a route to
* @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>
......@@ -136,7 +138,7 @@ public interface RoutingTable {
* @return The Session corresponding to the route, or null indicating no route exists
* @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>
......@@ -145,5 +147,5 @@ public interface RoutingTable {
* @param node The address we want a route to
* @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;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserManager;
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.UnknownHostException;
import java.util.Date;
......@@ -24,11 +28,11 @@ import javax.xml.stream.XMLStreamWriter;
public class ServerSession implements Session {
private StreamID streamID;
private XMPPAddress address;
private JID address;
private Date creationDate;
private Connection connection = new ServerConnection();
public ServerSession(XMPPAddress address, StreamID streamID) {
public ServerSession(JID address, StreamID streamID) {
this.address = address;
this.streamID = streamID;
creationDate = new Date();
......@@ -112,11 +116,11 @@ public class ServerSession implements Session {
public void incrementConflictCount() {
}
public XMPPAddress getAddress() {
public JID getAddress() {
return address;
}
public void process(XMPPPacket packet) {
public void process(Packet packet) {
}
private class ServerConnection implements Connection {
......@@ -159,7 +163,7 @@ public class ServerSession implements Session {
return null;
}
public void deliver(XMPPPacket packet)
public void deliver(Packet packet)
throws UnauthorizedException {
}
......
......@@ -15,6 +15,9 @@ import org.jivesoftware.messenger.auth.AuthToken;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.messenger.user.UserNotFoundException;
import org.xmpp.packet.Presence;
import org.xmpp.packet.JID;
import java.util.Date;
/**
......@@ -46,7 +49,7 @@ public interface Session extends RoutableChannelHandler {
*
* @return the address of the packet handler.
*/
public XMPPAddress getAddress();
public JID getAddress();
/**
* 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;
import org.jivesoftware.messenger.container.Module;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.JID;
/**
* The XMPP server definition. An interface allows us to implement the
......@@ -42,7 +43,7 @@ public interface XMPPServer extends XMPPServerMBean, Module {
*
* @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.
......@@ -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.
* @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.
......
......@@ -11,7 +11,7 @@
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>
......@@ -29,7 +29,7 @@ public interface Auditor {
*
* @param packet the packet being audited
*/
void audit(XMPPPacket packet);
void audit(Packet packet);
/**
* Audit any packet that was dropped (undeliverables, etc).
......
......@@ -13,11 +13,12 @@ package org.jivesoftware.messenger.auth.spi;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.NodePrep;
import org.jivesoftware.messenger.auth.AuthFactory;
import org.jivesoftware.messenger.auth.AuthProvider;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.stringprep.Stringprep;
import org.jivesoftware.stringprep.StringprepException;
import java.sql.Connection;
import java.sql.PreparedStatement;
......@@ -72,7 +73,12 @@ public class DbAuthProvider implements AuthProvider {
if (username == null || password == null) {
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;
PreparedStatement pstmt = null;
try {
......@@ -119,7 +125,12 @@ public class DbAuthProvider implements AuthProvider {
if (username == null || token == null || digest == null) {
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;
PreparedStatement pstmt = null;
try {
......@@ -167,7 +178,12 @@ public class DbAuthProvider implements AuthProvider {
if (username == null || password == null) {
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;
PreparedStatement pstmt = null;
try {
......
......@@ -12,8 +12,9 @@
package org.jivesoftware.messenger.disco;
import org.jivesoftware.messenger.forms.XDataForm;
import org.jivesoftware.messenger.XMPPAddress;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.JID;
import java.util.Iterator;
/**
......@@ -38,7 +39,7 @@ public interface DiscoInfoProvider {
* @param senderJID the XMPPAddress of user that sent the disco info request.
* @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
......@@ -50,7 +51,7 @@ public interface DiscoInfoProvider {
* @param senderJID the XMPPAddress of user that sent the disco info request.
* @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
......@@ -61,7 +62,7 @@ public interface DiscoInfoProvider {
* @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.
*/
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
......@@ -75,6 +76,6 @@ public interface DiscoInfoProvider {
* @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.
*/
public abstract boolean hasInfo(String name, String node, XMPPAddress senderJID)
public abstract boolean hasInfo(String name, String node, JID senderJID)
throws UnauthorizedException;
}
......@@ -11,8 +11,9 @@
package org.jivesoftware.messenger.disco;
import org.jivesoftware.messenger.XMPPAddress;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.JID;
import java.util.Iterator;
/**
......@@ -40,7 +41,7 @@ public interface DiscoItemsProvider {
* @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.
*/
public abstract Iterator getItems(String name, String node, XMPPAddress senderJID)
public abstract Iterator getItems(String name, String node, JID senderJID)
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 @@
package org.jivesoftware.messenger.forms.spi;
import org.jivesoftware.messenger.forms.FormField;
import org.jivesoftware.messenger.forms.XDataForm;
import org.jivesoftware.messenger.XMPPFragment;
import org.jivesoftware.util.ConcurrentHashSet;
import java.util.*;
......@@ -48,7 +46,7 @@ import org.dom4j.QName;
*
* @author gdombiak
*/
public class XDataFormImpl implements XDataForm {
public class XDataFormImpl {
private String type;
private String title;
......
......@@ -143,7 +143,7 @@ public class IQAuthHandler extends IQHandler implements IQAuthInfo {
Session session,
String digest)
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
......
......@@ -17,6 +17,10 @@ import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.*;
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;
/**
......@@ -47,8 +51,8 @@ public abstract class IQHandler extends BasicModule implements ChannelHandler {
this.router = router;
}
public void process(XMPPPacket xmppPacket) throws UnauthorizedException, PacketException {
IQ iq = (IQ)xmppPacket;
public void process(Packet packet) throws UnauthorizedException, PacketException {
IQ iq = (IQ)packet;
try {
iq = handleIQ(iq);
if (iq != null) {
......@@ -58,8 +62,8 @@ public abstract class IQHandler extends BasicModule implements ChannelHandler {
catch (org.jivesoftware.messenger.auth.UnauthorizedException e) {
if (iq != null) {
try {
XMPPPacket response = iq.createResult();
response.setError(XMPPError.Code.UNAUTHORIZED);
IQ response = IQ.createResultIQ(iq);
response.setError(PacketError.Condition.not_authorized);
Session session = iq.getOriginatingSession();
if (!session.getConnection().isClosed()) {
session.getConnection().deliver(response);
......
......@@ -11,9 +11,9 @@
package org.jivesoftware.messenger.muc;
import org.jivesoftware.messenger.IQ;
import org.jivesoftware.messenger.Message;
import org.jivesoftware.messenger.Presence;
import org.xmpp.packet.Message;
import org.xmpp.packet.Presence;
import org.xmpp.packet.IQ;
/**
* Interface for any object that can accept chat messages and presence
......@@ -22,6 +22,7 @@ import org.jivesoftware.messenger.Presence;
* @author Gaston Dombiak
*/
public interface ChatDeliverer {
/**
* Sends a packet to the user.
*
......
......@@ -22,8 +22,6 @@ import java.util.TimeZone;
import org.jivesoftware.messenger.muc.spi.MUCRoleImpl;
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
......
......@@ -12,8 +12,8 @@
package org.jivesoftware.messenger.muc;
import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.Message;
import org.jivesoftware.messenger.JiveGlobals;
import org.xmpp.packet.Message;
import java.util.Iterator;
import java.util.LinkedList;
......
......@@ -11,9 +11,9 @@
package org.jivesoftware.messenger.muc;
import org.jivesoftware.messenger.MetaDataFragment;
import org.jivesoftware.messenger.Presence;
import org.jivesoftware.messenger.XMPPAddress;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
import org.dom4j.Element;
/**
* Defines the permissions and actions that a MUCUser may use in
......@@ -82,7 +82,7 @@ public interface MUCRole extends ChatDeliverer {
* @return the extended presence information that includes information about roles,
* affiliations.
*/
MetaDataFragment getExtendedPresenceInformation();
Element getExtendedPresenceInformation();
/**
* Set the current presence status of a user in a chatroom.
......@@ -183,5 +183,5 @@ public interface MUCRole extends ChatDeliverer {
*
* @return The Jabber ID that represents this role in the room.
*/
XMPPAddress getRoleAddress();
JID getRoleAddress();
}
......@@ -18,13 +18,12 @@ import java.util.Collection;
import org.jivesoftware.messenger.muc.spi.IQAdminHandler;
import org.jivesoftware.messenger.muc.spi.IQOwnerHandler;
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.user.UserAlreadyExistsException;
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 {
* @return The new presence
* @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
......@@ -340,7 +339,7 @@ public interface MUCRoom extends ChatDeliverer {
* an existing occupant.
* @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
......@@ -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 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;
/**
......@@ -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
* to the room.
*
* @param fullJID 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 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.
* @return the updated presence of the occupant or <tt>null</tt> if the JID does not belong to
* an existing occupant.
* @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 NotAllowedException if trying to change the moderator role to an owner or an admin.
* @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;
/**
......@@ -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.
* @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;
public IQOwnerHandler getIQOwnerHandler();
......@@ -785,13 +784,12 @@ public interface MUCRoom extends ChatDeliverer {
* need the originating session so that the offline strategy could potentially bounce the
* 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 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.
*/
public void sendInvitation(String to, String reason, MUCRole role, Session session)
public void sendInvitation(JID to, String reason, MUCRole role)
throws ForbiddenException;
/**
......@@ -801,11 +799,9 @@ public interface MUCRoom extends ChatDeliverer {
* moment we need the originating session so that the offline strategy could potentially bounce
* 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 sender the address of the invitee that is rejecting the invitation.
* @param session the originating session that the invitee used for rejecting the invitation.
* @param from the JID of the invitee that is rejecting the invitation.
*/
public void sendInvitationRejection(String to, String reason, XMPPAddress sender,
Session session);
public void sendInvitationRejection(JID to, String reason, JID from);
}
\ No newline at end of file
......@@ -17,11 +17,10 @@ import java.util.Iterator;
import java.util.ListIterator;
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.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,
......@@ -51,16 +50,12 @@ public final class MUCRoomHistory {
public void addMessage(Message packet) {
// Don't keep messages whose sender is the room itself (thus address without resource)
// unless the message is changing the room's subject
if ((packet.getSender().getResourcePrep() == null
|| packet.getSender().getResourcePrep().length() == 0) &&
if ((packet.getFrom() == null
|| packet.getFrom().toString().length() == 0) &&
packet.getSubject() == null) {
return;
}
Message packetToAdd = (Message) packet.createDeepCopy();
// 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);
Message packetToAdd = (Message) packet.createCopy();
// TODO Analyze concurrency (on the LinkList) when adding many messages simultaneously
......@@ -69,47 +64,46 @@ public final class MUCRoomHistory {
isNonAnonymousRoom = room.canAnyoneDiscoverJID();
// Update the "from" attribute of the delay information in the history
Message message;
MetaDataFragment frag;
Element delayElement;
// TODO Make this update in a separate thread
for (Iterator it = getMessageHistory(); it.hasNext();) {
message = (Message) it.next();
frag = (MetaDataFragment) message.getFragment("x", "jabber:x:delay");
delayElement = message.getChildElement("x", "jabber:x:delay");
if (room.canAnyoneDiscoverJID()) {
// Set the Full JID as the "from" attribute
try {
MUCRole role = room.getOccupant(message.getSender().getResourcePrep());
frag.setProperty("x:from", role.getChatUser().getAddress().toStringPrep());
MUCRole role = room.getOccupant(message.getFrom().getResource());
delayElement.addAttribute("from", role.getChatUser().getAddress().toString());
}
catch (UserNotFoundException e) {
}
}
else {
// 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
MetaDataFragment delayInformation = new MetaDataFragment("jabber:x:delay", "x");
Element delayInformation = packetToAdd.addChildElement("x", "jabber:x:delay");
Date current = new Date();
delayInformation.setProperty("x:stamp", UTC_FORMAT.format(current));
delayInformation.addAttribute("stamp", UTC_FORMAT.format(current));
if (room.canAnyoneDiscoverJID()) {
// Set the Full JID as the "from" attribute
try {
MUCRole role = room.getOccupant(packet.getSender().getResourcePrep());
delayInformation.setProperty("x:from", role.getChatUser().getAddress()
.toStringPrep());
MUCRole role = room.getOccupant(packet.getFrom().getResource());
delayInformation.addAttribute("from", role.getChatUser().getAddress()
.toString());
}
catch (UserNotFoundException e) {
}
}
else {
// 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);
}
......@@ -140,36 +134,36 @@ public final class MUCRoomHistory {
* @param body the body of the message.
*/
public void addOldMessage(String senderJID, String nickname, Date sentDate, String subject,
String body) {
Message packetToAdd = new MessageImpl();
packetToAdd.setType(Message.GROUP_CHAT);
packetToAdd.setSubject(subject);
packetToAdd.setBody(body);
String body)
{
Message message = new Message();
message.setType(Message.Type.groupchat);
message.setSubject(subject);
message.setBody(body);
// Set the sender of the message
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
packetToAdd.setSender(new XMPPAddress(roomJID.getNamePrep(), roomJID.getHostPrep(),
message.setFrom(new JID(roomJID.getNode(), roomJID.getDomain(),
nickname));
}
else {
// 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
MetaDataFragment delayInformation = new MetaDataFragment("jabber:x:delay", "x");
delayInformation.setProperty("x:stamp", UTC_FORMAT.format(sentDate));
Element delayInformation = message.addChildElement("x", "jabber:x:deley");
delayInformation.addAttribute("stamp", UTC_FORMAT.format(sentDate));
if (room.canAnyoneDiscoverJID()) {
// Set the Full JID as the "from" attribute
delayInformation.setProperty("x:from", senderJID);
delayInformation.addAttribute("from", senderJID);
}
else {
// 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(packetToAdd);
historyStrategy.addMessage(message);
}
/**
......
......@@ -12,8 +12,8 @@
package org.jivesoftware.messenger.muc;
import org.jivesoftware.util.NotFoundException;
import org.jivesoftware.messenger.XMPPAddress;
import org.jivesoftware.messenger.ChannelHandler;
import org.xmpp.packet.JID;
import java.util.Iterator;
......@@ -47,7 +47,7 @@ public interface MUCUser extends ChannelHandler {
*
* @return the address of the packet handler.
*/
public XMPPAddress getAddress();
public JID getAddress();
/**
* Obtain the role of the user in a particular room.
......
......@@ -16,7 +16,8 @@ import java.util.Collection;
import org.jivesoftware.messenger.auth.UnauthorizedException;
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
......@@ -192,7 +193,7 @@ public interface MultiUserChatServer {
* @return The chatroom for the given name.
* @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.
......@@ -230,7 +231,7 @@ public interface MultiUserChatServer {
*
* @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.
......@@ -239,7 +240,7 @@ public interface MultiUserChatServer {
* @return The chatuser corresponding to that XMPPAddress.
* @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
......@@ -271,5 +272,5 @@ public interface MultiUserChatServer {
* @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).
*/
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;
import java.util.Date;
import org.jivesoftware.messenger.muc.MUCRoom;
import org.jivesoftware.messenger.Message;
import org.jivesoftware.messenger.XMPPAddress;
import org.xmpp.packet.Message;
import org.xmpp.packet.JID;
/**
* Represents an entry in the conversation log of a room. An entry basically obtains the necessary
......@@ -31,7 +31,7 @@ class ConversationLogEntry {
private String body;
private XMPPAddress sender;
private JID sender;
private String nickname;
......@@ -46,13 +46,13 @@ class ConversationLogEntry {
* @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).
*/
public ConversationLogEntry(Date date, MUCRoom room, Message message, XMPPAddress sender) {
public ConversationLogEntry(Date date, MUCRoom room, Message message, JID sender) {
this.date = date;
this.subject = message.getSubject();
this.body = message.getBody();
this.sender = sender;
this.roomID = room.getID();
this.nickname = message.getSender().getResourcePrep();
this.nickname = message.getFrom().getResource();
}
/**
......@@ -69,7 +69,7 @@ class ConversationLogEntry {
*
* @return the XMPP address of the logged message's sender.
*/
public XMPPAddress getSender() {
public JID getSender() {
return sender;
}
......
......@@ -12,15 +12,15 @@
package org.jivesoftware.messenger.muc.spi;
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.Presence;
import org.jivesoftware.messenger.XMPPAddress;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.util.Log;
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
......@@ -73,12 +73,12 @@ public class MUCRoleImpl implements MUCRole {
/**
* 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.
*/
private MetaDataFragment extendedInformation;
private Element extendedInformation;
/**
* Create a new role.
......@@ -93,13 +93,10 @@ public class MUCRoleImpl implements MUCRole {
* @throws UnauthorizedException if the role could not be created due to security or permission
* violations
*/
public MUCRoleImpl(MultiUserChatServer chatserver,
MUCRoomImpl chatroom,
String nickname,
int role,
int affiliation,
MUCUserImpl chatuser,
PacketRouter packetRouter) throws UnauthorizedException {
public MUCRoleImpl(MultiUserChatServer chatserver, MUCRoomImpl chatroom,
String nickname, int role, int affiliation, MUCUserImpl chatuser,
PacketRouter packetRouter) throws UnauthorizedException
{
this.room = chatroom;
this.nick = nickname;
this.user = chatuser;
......@@ -109,22 +106,22 @@ public class MUCRoleImpl implements MUCRole {
this.affiliation = affiliation;
extendedInformation = new MetaDataFragment("http://jabber.org/protocol/muc#user", "x");
calculateExtendedInformation();
rJID = new XMPPAddress(room.getName(), server.getServiceName(), nick);
setPresence(room.createPresence(Presence.STATUS_ONLINE));
rJID = new JID(room.getName(), server.getServiceName(), nick);
setPresence(room.createPresence(null));
}
public Presence getPresence() {
return presence;
}
public MetaDataFragment getExtendedPresenceInformation() {
public Element getExtendedPresenceInformation() {
return extendedInformation;
}
public void setPresence(Presence newPresence) {
this.presence = newPresence;
if (extendedInformation != null) {
presence.addFragment(extendedInformation);
presence.getElement().add(extendedInformation.createCopy());
}
}
......@@ -144,13 +141,7 @@ public class MUCRoleImpl implements MUCRole {
role = newRole;
if (MUCRole.NONE_ROLE == role) {
try {
presence.setAvailable(false);
presence.setVisible(false);
}
catch (UnauthorizedException e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
presence.setType(Presence.Type.unavailable);
}
calculateExtendedInformation();
}
......@@ -214,7 +205,7 @@ public class MUCRoleImpl implements MUCRole {
public void changeNickname(String nickname) {
this.nick = nickname;
rJID = new XMPPAddress(room.getName(), server.getServiceName(), nick);
rJID = new JID(room.getName(), server.getServiceName(), nick);
}
public MUCUser getChatUser() {
......@@ -225,30 +216,31 @@ public class MUCRoleImpl implements MUCRole {
return room;
}
public XMPPAddress getRoleAddress() {
public JID getRoleAddress() {
return rJID;
}
public void send(Presence packet) {
packet.setRecipient(user.getAddress());
packet.setTo(user.getAddress());
router.route(packet);
}
public void send(Message packet) {
packet.setRecipient(user.getAddress());
packet.setTo(user.getAddress());
router.route(packet);
}
public void send(IQ packet) {
packet.setRecipient(user.getAddress());
packet.setTo(user.getAddress());
router.route(packet);
}
/**
* Calculates and sets the extended presence information to add to the presence. The information
* to add contains the user's jid, affiliation and role.
* Calculates and sets the extended presence information to add to the presence.
* The information to add contains the user's jid, affiliation and role.
*/
private void calculateExtendedInformation() {
extendedInformation.setProperty("x.item:jid", user.getAddress().toString());
extendedInformation.setProperty("x.item:affiliation", getAffiliationAsString());
extendedInformation.setProperty("x.item:role", getRoleAsString());
......
......@@ -22,6 +22,7 @@ import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserAlreadyExistsException;
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
......@@ -35,7 +36,7 @@ public class MUCUserImpl implements MUCUser {
private MultiUserChatServer server;
/** Real system XMPPAddress for the user. */
private XMPPAddress realjid;
private JID realjid;
/** Table: key roomName.toLowerCase(); value MUCRole. */
private Map<String, MUCRole> roles = new ConcurrentHashMap<String, MUCRole>();
......@@ -55,7 +56,7 @@ public class MUCUserImpl implements MUCUser {
* @param packetRouter the router for sending packets from this 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.router = packetRouter;
this.server = chatserver;
......@@ -89,22 +90,21 @@ public class MUCUserImpl implements MUCUser {
* Generate a conflict packet to indicate that the nickname being requested/used is already in
* 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) {
packet = (XMPPPacket) packet.createDeepCopy();
packet.setError(errorCode);
XMPPAddress sender = packet.getSender();
packet.setSender(packet.getRecipient());
packet.setRecipient(sender);
private void sendErrorPacket(Packet packet, PacketError error) {
packet = packet.createCopy();
packet.setError(error);
packet.setFrom(packet.getTo());
packet.setTo(packet.getFrom());
router.route(packet);
}
public XMPPAddress getAddress() {
public JID getAddress() {
return realjid;
}
public void process(XMPPPacket packet) throws UnauthorizedException, PacketException {
public void process(Packet packet) throws UnauthorizedException, PacketException {
if (packet instanceof IQ) {
process((IQ)packet);
}
......@@ -132,8 +132,8 @@ public class MUCUserImpl implements MUCUser {
*/
public void process(Message packet) {
lastPacketTime = System.currentTimeMillis();
XMPPAddress recipient = packet.getRecipient();
String group = recipient.getName();
JID recipient = packet.getTo();
String group = recipient.getNode();
if (group == null) {
// Ignore packets to the groupchat server
// 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 {
if (role == null) {
if (server.hasChatRoom(group)) {
boolean declinedInvitation = false;
XMPPDOMFragment userInfo = null;
if (Message.NORMAL == packet.getType()) {
Element userInfo = null;
if (Message.Type.normal == packet.getType()) {
// An user that is not an occupant could be declining an invitation
userInfo = (XMPPDOMFragment) packet.getFragment(
"x",
"http://jabber.org/protocol/muc#user");
userInfo = packet.getChildElement(
"x", "http://jabber.org/protocol/muc#user");
if (userInfo != null
&& userInfo.getRootElement().element("decline") != null) {
&& userInfo.element("decline") != null) {
// A user has declined an invitation to a room
// WARNING: Potential fraud if someone fakes the "from" of the
// message with the JID of a member and sends a "decline"
......@@ -160,12 +159,11 @@ public class MUCUserImpl implements MUCUser {
}
}
if (declinedInvitation) {
Element info = userInfo.getRootElement().element("decline");
Element info = userInfo.element("decline");
server.getChatRoom(group).sendInvitationRejection(
info.attributeValue("to"),
info.elementTextTrim("reason"),
packet.getSender(),
packet.getOriginatingSession());
packet.getFrom());
}
else {
// The sender is not an occupant of the room
......
......@@ -34,6 +34,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
import org.dom4j.DocumentHelper;
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
......@@ -92,7 +96,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
* the chat service's hostname
*/
private String chatServiceName = null;
private XMPPAddress chatServiceAddress = null;
private JID chatServiceAddress = null;
/**
* chatrooms managed by this manager, table: key room name (String); value ChatRoom
......@@ -102,7 +106,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
/**
* 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 RoutingTable routingTable = null;
......@@ -196,7 +200,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
room = role.getChatRoom();
try {
kickedPresence =
room.kickOccupant(user.getAddress().toStringPrep(), null, null);
room.kickOccupant(user.getAddress(), null, null);
// Send the updated presence to the room occupants
room.send(kickedPresence);
}
......@@ -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;
synchronized (rooms) {
room = rooms.get(roomName.toLowerCase());
......@@ -270,15 +274,15 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
// The room does not exist so check for creation permissions
// Room creation is always allowed for sysadmin
if (isRoomCreationRestricted() &&
!sysadmins.contains(userjid.toBareStringPrep())) {
!sysadmins.contains(userjid.toBareJID())) {
// 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
// an exception
throw new UnauthorizedException();
}
}
room.addFirstOwner(userjid.toBareStringPrep());
room.addFirstOwner(userjid.toBareJID());
}
rooms.put(roomName.toLowerCase(), room);
}
......@@ -314,7 +318,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
return historyStrategy;
}
public void removeUser(XMPPAddress jabberID) {
public void removeUser(JID jabberID) {
MUCUser user = users.remove(jabberID);
if (user != null) {
Iterator<MUCRole> roles = user.getRoles();
......@@ -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) {
throw new IllegalStateException("Not initialized");
}
......@@ -585,7 +589,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
if (serverName != null) {
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
// values)
userTimeoutTask = new UserTimeoutTask();
......@@ -619,16 +623,16 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
}
}
public XMPPAddress getAddress() {
public JID getAddress() {
if (chatServiceAddress == null) {
throw new IllegalStateException("Not initialized");
}
return chatServiceAddress;
}
public void process(XMPPPacket packet) {
public void process(Packet packet) {
try {
MUCUser user = getChatUser(packet.getSender());
MUCUser user = getChatUser(packet.getFrom());
user.process(packet);
}
catch (Exception e) {
......@@ -640,7 +644,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
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));
}
......@@ -675,7 +679,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
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
ArrayList identities = new ArrayList();
if (name == null && node == null) {
......@@ -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
MUCRoom room = getChatRoom(name);
if (room != null) {
String reservedNick = room.getReservedNickname(senderJID.toBareStringPrep());
String reservedNick = room.getReservedNickname(senderJID.toBareJID());
if (reservedNick != null) {
Element identity = DocumentHelper.createElement("identity");
identity.addAttribute("category", "conference");
......@@ -717,7 +721,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
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();
if (name == null && node == null) {
// Answer the features of the MUC service
......@@ -768,7 +772,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
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) {
// Answer the extended info of a given room
// TODO lock the room while gathering this info???
......@@ -808,7 +812,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
return null;
}
public boolean hasInfo(String name, String node, XMPPAddress senderJID)
public boolean hasInfo(String name, String node, JID senderJID)
throws UnauthorizedException {
if (name == null && node == node) {
// We always have info about the MUC service
......@@ -825,7 +829,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
return false;
}
public Iterator getItems(String name, String node, XMPPAddress senderJID)
public Iterator getItems(String name, String node, JID senderJID)
throws UnauthorizedException {
List answer = new ArrayList();
if (name == null && node == null) {
......@@ -834,7 +838,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
for (MUCRoom room : rooms.values()) {
if (room.isPublicRoom()) {
item = DocumentHelper.createElement("item");
item.addAttribute("jid", room.getRole().getRoleAddress().toStringPrep());
item.addAttribute("jid", room.getRole().getRoleAddress().toString());
item.addAttribute("name", room.getNaturalLanguageName());
answer.add(item);
......@@ -849,7 +853,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
for (MUCRole role : room.getOccupants()) {
// TODO Should we filter occupants that are invisible (presence is not broadcasted)?
item = DocumentHelper.createElement("item");
item.addAttribute("jid", role.getRoleAddress().toStringPrep());
item.addAttribute("jid", role.getRoleAddress().toString());
answer.add(item);
}
......
......@@ -16,6 +16,10 @@ import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.audit.Auditor;
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.InputStreamReader;
import java.net.Socket;
......@@ -113,16 +117,10 @@ public class SocketReadThread extends Thread {
Presence presence = session.getPresence();
if (presence != null) {
// Simulate an unavailable presence sent by the user.
Presence packet = (Presence) presence.createDeepCopy();
packet.setType(Presence.UNAVAILABLE);
try {
packet.setAvailable(false);
packet.setVisible(false);
}
catch (UnauthorizedException e) {}
packet.setOriginatingSession(session);
packet.setSender(session.getAddress());
packet.setSending(false);
Presence packet = presence.createCopy();
packet.setType(Presence.Type.unavailable);
packet.setType(null);
packet.setFrom(session.getAddress());
router.route(packet);
clearSignout = true;
}
......@@ -190,29 +188,23 @@ public class SocketReadThread extends Thread {
if ("message".equals(tag)) {
Message packet = packetFactory.getMessage(xpp);
packet.setOriginatingSession(session);
packet.setSender(session.getAddress());
packet.setSending(false);
packet.setFrom(session.getAddress());
auditor.audit(packet);
router.route(packet);
session.incrementClientPacketCount();
}
else if ("presence".equals(tag)) {
Presence packet = packetFactory.getPresence(xpp);
packet.setOriginatingSession(session);
packet.setSender(session.getAddress());
packet.setSending(false);
packet.setFrom(session.getAddress());
auditor.audit(packet);
router.route(packet);
session.incrementClientPacketCount();
// 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)) {
IQ packet = packetFactory.getIQ(xpp);
packet.setOriginatingSession(session);
packet.setSender(session.getAddress());
packet.setSending(false);
packet.setFrom(session.getAddress());
auditor.audit(packet);
router.route(packet);
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;
import org.jivesoftware.util.Version;
import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.JID;
import java.text.DateFormat;
import java.util.*;
......@@ -63,19 +65,19 @@ public class BasicServer extends BasicModule implements XMPPServer, BasicServerM
return new XMPPServerInfoImpl(name, version, startDate, stopDate, ports);
}
public boolean isLocal(XMPPAddress jid) {
public boolean isLocal(JID jid) {
boolean local = false;
if (jid != null && name != null && name.equalsIgnoreCase(jid.getHost())) {
if (jid != null && name != null && name.equalsIgnoreCase(jid.getDomain())) {
local = true;
}
return local;
}
public XMPPAddress createAddress(String username, String resource) {
return new XMPPAddress(username, name, resource);
public JID createJID(String username, String 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));
public Session getSession() {
......@@ -95,7 +97,7 @@ public class BasicServer extends BasicModule implements XMPPServer, BasicServerM
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;
}
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 {
return server.isLocal(jid);
}
public XMPPAddress createAddress(String username, String resource) {
return server.createAddress(username, resource);
public XMPPAddress createJID(String username, String resource) {
return server.createJID(username, resource);
}
public Session getSession() throws UnauthorizedException {
......
......@@ -206,7 +206,7 @@ public class CachedRosterImpl extends BasicRoster implements CachedRoster {
if (server == null) {
server = (XMPPServer)ServiceLookupFactory.getLookup().lookup(XMPPServer.class);
}
XMPPAddress recipient = server.createAddress(username, null);
XMPPAddress recipient = server.createJID(username, null);
roster.setRecipient(recipient);
roster.setOriginatingSession(server.getSession());
if (sessionManager == null) {
......
......@@ -111,7 +111,7 @@ public class OfflineMessageStrategyImpl extends BasicModule implements OfflineMe
Message response = packetFactory.getMessage();
response.setOriginatingSession(xmppServer.getSession());
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.");
message.getOriginatingSession().getConnection().deliver(response);
......
......@@ -6,7 +6,6 @@
<%@ page import="java.io.*,
org.jivesoftware.util.ParamUtils,
org.jivesoftware.util.Version,
org.jivesoftware.messenger.JiveGlobals,
org.jivesoftware.messenger.auth.UnauthorizedException,
org.jivesoftware.messenger.user.UserNotFoundException,
......
......@@ -13,7 +13,6 @@
org.jivesoftware.messenger.container.ServiceLookupFactory,
org.jivesoftware.messenger.container.ServiceLookup,
org.jivesoftware.messenger.JiveGlobals,
org.jivesoftware.util.Version,
org.jivesoftware.util.Log,
org.jivesoftware.admin.AdminConsole"
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