Commit 2ad7f021 authored by Matt Tucker's avatar Matt Tucker Committed by matt

Converted to Whack Component interfaces. Needs additional work.


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@956 b35dd754-fafc-0310-a699-88a17e54d16e
parent 019f4db5
/**
* $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;
/**
* Interface for Components.
*
* @see ComponentManager
* @author Derek DeMoro
*/
public interface Component extends RoutableChannelHandler {
/**
* Returns the service name of this component. The service name is usually the part before the
* dot before the server address in a JID. For example, given this JID jdoe@broadcast.localhost
* the service name would be broadcast.<p>
*
* This information is useful when adding or removing the component from the ComponentManager.
*
* @return the service name of this component.
*/
public String getServiceName();
}
......@@ -12,6 +12,8 @@ package org.jivesoftware.messenger;
import org.xmpp.packet.Packet;
import org.xmpp.packet.JID;
import org.xmpp.component.*;
import org.xmpp.component.ComponentManager;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.auth.AuthFactory;
import org.jivesoftware.util.Log;
......@@ -47,7 +49,8 @@ public class ComponentSession extends Session {
*/
public static Session createSession(String serverName, XPPPacketReader reader,
Connection connection) throws UnauthorizedException, IOException,
XmlPullParserException {
XmlPullParserException
{
XmlPullParser xpp = reader.getXPPParser();
Session session;
String domain = xpp.getAttributeValue("", "to");
......@@ -95,7 +98,7 @@ public class ComponentSession extends Session {
return null;
}
// Check that the requested domain is not already in use
if (ComponentManager.getInstance().getComponent(domain) != null) {
if (InternalComponentManager.getInstance().getComponent(domain) != null) {
// Domain already occupied so return a conflict error and close the connection
// Include the conflict error in the response
sb.append("<stream:error>");
......@@ -155,7 +158,7 @@ public class ComponentSession extends Session {
else {
// Bind the domain to this component
ExternalComponent component = ((ComponentSession) session).getExternalComponent();
ComponentManager.getInstance().addComponent(domain, component);
InternalComponentManager.getInstance().addComponent(domain, component);
// Set the service name to the component
component.setServiceName(domain);
// Component has authenticated fine
......@@ -181,7 +184,7 @@ public class ComponentSession extends Session {
public void process(Packet packet) throws UnauthorizedException, PacketException {
// Since ComponentSessions are not being stored in the RoutingTable this messages is very
// unlikely to be sent
component.process(packet);
component.processPacket(packet);
}
public ExternalComponent getExternalComponent() {
......@@ -202,7 +205,7 @@ public class ComponentSession extends Session {
private String serviceName;
public void process(Packet packet) {
public void processPacket(Packet packet) {
if (conn != null && !conn.isClosed()) {
try {
conn.deliver(packet);
......@@ -218,6 +221,22 @@ public class ComponentSession extends Session {
}
}
public String getName() {
return null;
}
public String getDescription() {
return null;
}
public void initialize(JID jid, ComponentManager componentManager) {
}
public void shutdown() {
}
public JID getAddress() {
return ComponentSession.this.getAddress();
}
......@@ -230,4 +249,4 @@ public class ComponentSession extends Session {
this.serviceName = serviceName;
}
}
}
}
\ No newline at end of file
......@@ -20,6 +20,7 @@ import org.jivesoftware.util.Log;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
import org.xmpp.component.Component;
import java.util.ArrayList;
import java.util.List;
......@@ -40,7 +41,7 @@ public class IQRouter extends BasicModule {
private List<IQHandler> iqHandlers = new ArrayList<IQHandler>();
private Map<String, IQHandler> namespace2Handlers = new ConcurrentHashMap<String, IQHandler>();
private SessionManager sessionManager;
private ComponentManager componentManager;
private InternalComponentManager componentManager;
/**
* Creates a packet router.
......@@ -124,7 +125,7 @@ public class IQRouter extends BasicModule {
routingTable = server.getRoutingTable();
iqHandlers.addAll(server.getIQHandlers());
sessionManager = server.getSessionManager();
componentManager = ComponentManager.getInstance();
componentManager = InternalComponentManager.getInstance();
}
/**
......@@ -149,7 +150,7 @@ public class IQRouter extends BasicModule {
}
if (component != null) {
// A component was found that can handle the Packet
component.process(packet);
component.processPacket(packet);
}
else if (isLocalServer(recipientJID)) {
// Let the server handle the Packet
......
......@@ -15,6 +15,7 @@ import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
import org.xmpp.packet.Presence;
import org.xmpp.component.*;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
......@@ -27,57 +28,44 @@ import java.util.concurrent.ConcurrentHashMap;
*
* @author Derek DeMoro
*/
public class ComponentManager {
public class InternalComponentManager implements ComponentManager {
private Map<String, Component> components = new ConcurrentHashMap<String, Component>();
private Map<JID, JID> presenceMap = new ConcurrentHashMap<JID, JID>();
private static ComponentManager instance = new ComponentManager();
private static InternalComponentManager instance;
static {
instance = new InternalComponentManager();
ComponentManagerFactory.setComponentManager(instance);
}
/**
* Returns the singleton instance of <CODE>ComponentManager</CODE>,
* creating it if necessary.
* <p/>
*
* @return the singleton instance of <Code>ComponentManager</CODE>
*/
public static ComponentManager getInstance() {
public static InternalComponentManager getInstance() {
return instance;
}
private ComponentManager() {
private InternalComponentManager() {
}
/**
* Registers a <code>Component</code> with the server and maps
* to particular jid. A route for the new Component will be added to
* the <code>RoutingTable</code> based on the address of the component.
* Note: The address of the component will be a JID wih empties node and resource.
*
* @param jid the jid to map to.
* @param component the <code>Component</code> to register.
*/
public void addComponent(String jid, Component component) {
jid = new JID(jid).toBareJID();
components.put(jid, component);
public void addComponent(String subdomain, Component component) {
components.put(subdomain, component);
JID componentJID = new JID(subdomain + "." +
XMPPServer.getInstance().getServerInfo().getName());
// Add the route to the new service provided by the component
XMPPServer.getInstance().getRoutingTable().addRoute(component.getAddress(), component);
XMPPServer.getInstance().getRoutingTable().addRoute(componentJID,
new RoutableComponent(componentJID, component));
// Check for potential interested users.
checkPresences();
}
/**
* Removes a <code>Component</code> from the server. The route for the new Component
* will be removed from the <code>RoutingTable</code>.
*
* @param jid the jid mapped to the particular component.
*/
public void removeComponent(String jid) {
JID componentJID = new JID(jid);
components.remove(componentJID.toBareJID());
public void removeComponent(String subdomain) {
components.remove(subdomain);
JID componentJID = new JID(subdomain + "." +
XMPPServer.getInstance().getServerInfo().getName());
// Remove the route for the service provided by the component
if (XMPPServer.getInstance().getRoutingTable() != null) {
......@@ -85,6 +73,30 @@ public class ComponentManager {
}
}
public void sendPacket(Component component, Packet packet) {
PacketRouter router;
router = XMPPServer.getInstance().getPacketRouter();
if (router != null) {
router.route(packet);
}
}
public String getProperty(String name) {
return JiveGlobals.getProperty(name);
}
public void setProperty(String name, String value) {
//To change body of implemented methods use File | Settings | File Templates.
}
public boolean isExternalMode() {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
public Log getLog() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
/**
* Retrieves the <code>Component</code> which is mapped
* to the specified JID.
......@@ -118,20 +130,6 @@ public class ComponentManager {
presenceMap.put(prober, probee);
}
/**
* 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;
router = XMPPServer.getInstance().getPacketRouter();
if (router != null) {
router.route(packet);
}
}
private void checkPresences() {
for (JID prober : presenceMap.keySet()) {
JID probee = presenceMap.get(prober);
......@@ -141,17 +139,33 @@ public class ComponentManager {
Presence presence = new Presence();
presence.setFrom(prober);
presence.setTo(probee);
try {
component.process(presence);
// No reason to hold onto prober reference.
presenceMap.remove(prober);
}
catch (UnauthorizedException e) {
// Do nothing. This error should never occur
}
component.processPacket(presence);
// No reason to hold onto prober reference.
presenceMap.remove(prober);
}
}
}
/**
* Exposes a Component as a RoutableChannelHandler.
*/
public static class RoutableComponent implements RoutableChannelHandler {
private JID jid;
private Component component;
public RoutableComponent(JID jid, Component component) {
this.jid = jid;
this.component = component;
}
public JID getAddress() {
return jid;
}
public void process(Packet packet) throws UnauthorizedException, PacketException {
component.processPacket(packet);
}
}
}
\ No newline at end of file
......@@ -979,7 +979,7 @@ public class SessionManager extends BasicModule {
try {
ComponentSession session = (ComponentSession)handback;
// Unbind the domain for this external component
ComponentManager.getInstance().removeComponent(session.getAddress().getDomain());
InternalComponentManager.getInstance().removeComponent(session.getAddress().getDomain());
// Remove the session
componentsSessions.remove(session);
}
......
......@@ -16,9 +16,9 @@ import java.util.Collection;
import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.messenger.Component;
import org.xmpp.packet.Message;
import org.xmpp.packet.JID;
import org.xmpp.component.Component;
/**
* Manages groupchat conversations, chatrooms, and users. This class is designed to operate
......@@ -30,13 +30,21 @@ import org.xmpp.packet.JID;
public interface MultiUserChatServer extends Component {
/**
* Obtain the domain of this chat service. The domain is composed by the service name and the
* name of the xmpp server where the service is running.
* Returns the fully-qualifed domain name of this chat service.
* The domain is composed by the service name and the
* name of the XMPP server where the service is running.
*
* @return The chat server domain (service name + host name).
* @return the chat server domain (service name + host name).
*/
String getServiceDomain();
/**
* Returns the subdomain of the chat service.
*
* @return the subdomain of the chat service.
*/
String getServiceName();
/**
* Set the name of this chat service. The new name won't go into effect until the server is
* restarted.
......
......@@ -45,6 +45,7 @@ import org.xmpp.packet.JID;
import org.xmpp.packet.Message;
import org.xmpp.packet.Packet;
import org.xmpp.packet.Presence;
import org.xmpp.component.ComponentManager;
/**
* Implements the chat server as a cached memory resident chat server. The server is also
......@@ -97,7 +98,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
* the chat service's hostname
*/
private String chatServiceName = null;
private JID chatServiceAddress = null;
/**
* chatrooms managed by this manager, table: key room name (String); value ChatRoom
......@@ -110,7 +110,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
private Map<JID, MUCUser> users = new ConcurrentHashMap<JID, MUCUser>();
private HistoryStrategy historyStrategy;
private RoutingTable routingTable = null;
/**
* The packet router for the server.
*/
......@@ -186,6 +185,34 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
historyStrategy = new HistoryStrategy(null);
}
public String getDescription() {
return null;
}
public void processPacket(Packet packet) {
try {
MUCUser user = getChatUser(packet.getFrom());
user.process(packet);
}
catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
public void initialize(JID jid, ComponentManager componentManager) {
}
public void shutdown() {
}
public String getServiceDomain() {
return chatServiceName + "." + XMPPServer.getInstance().getServerInfo().getName();
}
/**
* Probes the presence of any user who's last packet was sent more than 5 minute ago.
*/
......@@ -377,10 +404,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
return chatServiceName;
}
public String getServiceDomain() {
return chatServiceAddress.getDomain();
}
public HistoryStrategy getHistoryStrategy() {
return historyStrategy;
}
......@@ -645,12 +668,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
if (chatServiceName == null) {
chatServiceName = "conference";
}
String serverName = server.getServerInfo().getName();
String domain = chatServiceName;
if (serverName != null) {
domain = chatServiceName + "." + serverName;
}
chatServiceAddress = new JID(null, domain, null);
// Run through the users every 5 minutes after a 5 minutes server startup delay (default
// values)
userTimeoutTask = new UserTimeoutTask();
......@@ -663,21 +680,12 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
cleanupTask = new CleanupTask();
timer.schedule(cleanupTask, cleanup_frequency, cleanup_frequency);
routingTable = server.getRoutingTable();
router = server.getPacketRouter();
// TODO Remove the tracking for IQRegisterHandler when the component JEP gets implemented.
registerHandler = server.getIQRegisterHandler();
registerHandler.addDelegate(getServiceDomain(), new IQMUCRegisterHandler(this));
}
public void start() {
super.start();
// Add the route to this service
routingTable.addRoute(chatServiceAddress, this);
ArrayList params = new ArrayList();
params.clear();
params.add(chatServiceAddress.getDomain());
Log.info(LocaleUtils.getLocalizedString("startup.starting.muc", params));
InternalComponentManager.getInstance().addComponent(chatServiceName, this);
// Load all the persistent rooms to memory
for (MUCRoom room : MUCPersistenceManager.loadRoomsFromDB(this, this.getCleanupDate(),
router)) {
......@@ -688,7 +696,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
public void stop() {
super.stop();
// Remove the route to this service
routingTable.removeRoute(chatServiceAddress);
InternalComponentManager.getInstance().removeComponent(chatServiceName);
timer.cancel();
logAllConversation();
if (registerHandler != null) {
......@@ -696,23 +704,6 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
}
}
public JID getAddress() {
if (chatServiceAddress == null) {
throw new IllegalStateException("Not initialized");
}
return chatServiceAddress;
}
public void process(Packet packet) {
try {
MUCUser user = getChatUser(packet.getFrom());
user.process(packet);
}
catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
public long getTotalChatTime() {
return totalChatTime;
}
......@@ -726,7 +717,7 @@ public class MultiUserChatServerImpl extends BasicModule implements MultiUserCha
items.add(new DiscoServerItem() {
public String getJID() {
return chatServiceAddress.getDomain();
return getServiceDomain();
}
public String getName() {
......
......@@ -22,6 +22,7 @@ import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence;
import org.xmpp.component.Component;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
......@@ -46,13 +47,13 @@ public class PresenceManagerImpl extends BasicModule implements PresenceManager
private XMPPServer server;
private PacketDeliverer deliverer;
private ComponentManager componentManager;
private InternalComponentManager componentManager;
public PresenceManagerImpl() {
super("Presence manager");
// Use component manager for Presence Updates.
componentManager = ComponentManager.getInstance();
componentManager = InternalComponentManager.getInstance();
}
private void initializeCaches() {
......@@ -306,7 +307,7 @@ public class PresenceManagerImpl extends BasicModule implements PresenceManager
presence.setType(Presence.Type.probe);
presence.setFrom(server.createJID(prober, ""));
presence.setTo(probee);
component.process(presence);
component.processPacket(presence);
}
else {
Presence presence = (Presence) foreignUserCache.get(probee.toBareJID());
......
......@@ -52,7 +52,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable {
routeLock.writeLock().lock();
try {
if (routes.isEmpty() || destination instanceof Component) {
if (routes.isEmpty() || destination instanceof InternalComponentManager.RoutableComponent) {
routes.put(node.getDomain(), destination);
}
else {
......
......@@ -23,6 +23,9 @@ import org.xmpp.packet.Message;
import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketError;
import org.xmpp.packet.JID;
import org.xmpp.component.Component;
import org.xmpp.component.ComponentManager;
import org.xmpp.component.ComponentManagerFactory;
import java.io.File;
import java.util.Collection;
......@@ -46,7 +49,7 @@ public class BroadcastPlugin implements Plugin, Component {
private GroupManager groupManager;
private List<JID> allowedUsers;
private boolean groupMembersAllowed;
private JID serviceJID;
private ComponentManager componentManager;
/**
* Constructs a new broadcast plugin.
......@@ -56,8 +59,6 @@ public class BroadcastPlugin implements Plugin, Component {
groupMembersAllowed = JiveGlobals.getBooleanProperty(
"plugin.broadcast.groupMembersAllowed", true);
allowedUsers = stringToList(JiveGlobals.getProperty("plugin.broadcast.allowedUsers", ""));
serviceJID =
new JID(serviceName + "." + XMPPServer.getInstance().getServerInfo().getName());
}
// Plugin Interface
......@@ -83,20 +84,39 @@ public class BroadcastPlugin implements Plugin, Component {
groupManager = GroupManager.getInstance();
// Register as a component.
ComponentManager.getInstance().addComponent(serviceName, this);
componentManager = ComponentManagerFactory.getComponentManager();
try {
componentManager.addComponent(serviceName, this);
}
catch (Exception e) {
componentManager.getLog().error(e);
}
}
public void destroy() {
// Unregister component.
ComponentManager.getInstance().removeComponent(serviceName);
try {
componentManager.removeComponent(serviceName);
}
catch (Exception e) {
componentManager.getLog().error(e);
}
sessionManager = null;
groupManager = null;
allowedUsers.clear();
}
public void initialize(JID jid, ComponentManager componentManager) {
}
public void shutdown() {
}
// Component Interface
public void process(Packet packet) {
public void processPacket(Packet packet) {
// Only respond to incoming messages. TODO: handle disco, presence, etc.
if (packet instanceof Message) {
Message message = (Message)packet;
......@@ -118,7 +138,7 @@ public class BroadcastPlugin implements Plugin, Component {
error.setSubject("Error sending broadcast message");
error.setBody("Not allowed to send a broadcast message to " +
message.getTo());
ComponentManager.getInstance().sendPacket(error);
InternalComponentManager.getInstance().sendPacket(this, error);
return;
}
}
......@@ -141,7 +161,7 @@ public class BroadcastPlugin implements Plugin, Component {
Message newMessage = message.createCopy();
JID userJID = XMPPServer.getInstance().createJID(user, null);
newMessage.setTo(userJID);
ComponentManager.getInstance().sendPacket(newMessage);
InternalComponentManager.getInstance().sendPacket(this, newMessage);
}
}
else {
......@@ -155,7 +175,7 @@ public class BroadcastPlugin implements Plugin, Component {
error.setSubject("Error sending broadcast message");
error.setBody("Not allowed to send a broadcast message to " +
message.getTo());
ComponentManager.getInstance().sendPacket(error);
InternalComponentManager.getInstance().sendPacket(this, error);
}
}
catch (GroupNotFoundException gnfe) {
......@@ -169,7 +189,7 @@ public class BroadcastPlugin implements Plugin, Component {
error.setSubject("Error sending broadcast message");
error.setBody("Address not valid: " +
message.getTo());
ComponentManager.getInstance().sendPacket(error);
InternalComponentManager.getInstance().sendPacket(this, error);
}
}
}
......@@ -186,10 +206,6 @@ public class BroadcastPlugin implements Plugin, Component {
return serviceName;
}
public JID getAddress() {
return serviceJID;
}
/**
* Sets the service name of this component, which is "broadcast" by default.
*
......@@ -204,11 +220,19 @@ public class BroadcastPlugin implements Plugin, Component {
}
JiveGlobals.setProperty("plugin.broadcast.serviceName", serviceName);
// Re-register the service.
ComponentManager.getInstance().removeComponent(this.serviceName);
ComponentManager.getInstance().addComponent(serviceName, this);
try {
componentManager.removeComponent(this.serviceName);
}
catch (Exception e) {
componentManager.getLog().error(e);
}
try {
componentManager.addComponent(serviceName, this);
}
catch (Exception e) {
componentManager.getLog().error(e);
}
this.serviceName = serviceName;
serviceJID =
new JID(serviceName + "." + XMPPServer.getInstance().getServerInfo().getName());
}
/**
......
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