package org.jboss.mq.sm.file;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import javax.jms.InvalidClientIDException;
import javax.jms.JMSException;
import javax.jms.JMSSecurityException;
import org.jboss.mq.DurableSubscriptionID;
import org.jboss.mq.SpyJMSException;
import org.jboss.mq.SpyTopic;
import org.jboss.mq.server.JMSDestinationManager;
import org.jboss.mq.server.JMSTopic;
import org.jboss.mq.sm.StateManager;
import org.jboss.mq.xml.XElement;
import org.jboss.mq.xml.XElementException;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.system.server.ServerConfigLocator;
public class OldStateManager
extends ServiceMBeanSupport
implements StateManager, OldStateManagerMBean
{
XElement stateConfig;
private final Set loggedOnClientIds = new HashSet();
private String stateFile = "conf/default/jbossmq-state.xml";
private URL systemConfigURL;
public OldStateManager() throws XElementException
{
}
protected void createService() throws Exception {
systemConfigURL = ServerConfigLocator.locate().getServerConfigURL();
}
public void setStateFile(String newStateFile)
{
stateFile = newStateFile.trim();
}
public StateManager getInstance()
{
return this;
}
public void setDurableSubscription(JMSDestinationManager server, DurableSubscriptionID sub, SpyTopic topic)
throws JMSException
{
boolean debug = log.isDebugEnabled();
if (debug)
log.debug("Checking durable subscription: " + sub + ", on topic: " + topic);
try
{
Enumeration enumeration = stateConfig.getElementsNamed("User");
while (enumeration.hasMoreElements())
{
XElement user = (XElement)enumeration.nextElement();
if (!user.containsField("Id") || !user.getField("Id").equals(sub.getClientID()))
{
continue;
}
if (debug)
log.debug("Found a matching ClientID configuration section.");
XElement subscription = null;
Enumeration enum2 = user.getElementsNamed("DurableSubscription");
while (enum2.hasMoreElements())
{
XElement t = (XElement)enum2.nextElement();
if (t.getField("Name").equals(sub.getSubscriptionName()))
{
subscription = t;
break;
}
}
if (subscription == null)
{
if (debug)
log.debug("The subscription was not previously registered.");
if (topic == null)
{
return;
}
JMSTopic dest = (JMSTopic)server.getJMSDestination(topic);
dest.createDurableSubscription(sub);
subscription = new XElement("DurableSubscription");
subscription.addField("Name", sub.getSubscriptionName());
subscription.addField("TopicName", topic.getName());
user.addElement(subscription);
saveConfig();
}
else
{
if (debug)
log.debug("The subscription was previously registered.");
if (topic == null)
{
SpyTopic prevTopic = new SpyTopic(subscription.getField("TopicName"));
JMSTopic dest = (JMSTopic)server.getJMSDestination(prevTopic);
dest.destroyDurableSubscription(sub);
subscription.removeFromParent();
saveConfig();
}
else if (!subscription.getField("TopicName").equals(topic.getName()))
{
if (debug)
log.debug("But the topic was different, changing the subscription.");
SpyTopic prevTopic = new SpyTopic(subscription.getField("TopicName"));
JMSTopic dest = (JMSTopic)server.getJMSDestination(prevTopic);
dest.destroyDurableSubscription(sub);
dest = (JMSTopic)server.getJMSDestination(topic);
dest.createDurableSubscription(sub);
subscription.setField("TopicName", topic.getName());
saveConfig();
}
}
return;
}
throw new JMSException("ClientID '" + sub.getClientID() +
"' cannot create durable subscriptions.");
}
catch (IOException e)
{
JMSException newE = new SpyJMSException("Could not setup the durable subscription");
newE.setLinkedException(e);
throw newE;
}
catch (XElementException e)
{
JMSException newE = new SpyJMSException("Could not setup the durable subscription");
newE.setLinkedException(e);
throw newE;
}
}
public SpyTopic getDurableTopic(DurableSubscriptionID sub) throws JMSException
{
try {
XElement subscription = getSubscription(sub);
if (subscription == null)
throw new JMSException("No durable subscription found for subscription: " + sub.getSubscriptionName());
return new SpyTopic(subscription.getField("TopicName"));
}catch(XElementException e)
{
JMSException newE = new SpyJMSException("Could not find durable subscription");
newE.setLinkedException(e);
throw newE;
}
}
private XElement getSubscription(DurableSubscriptionID sub) throws JMSException,XElementException {
boolean debug = log.isDebugEnabled();
XElement subscription = null;
Enumeration enumeration = stateConfig.getElementsNamed("User");
while (enumeration.hasMoreElements())
{
XElement user = (XElement)enumeration.nextElement();
if (!user.containsField("Id") || !user.getField("Id").equals(sub.getClientID()))
{
continue;
}
if (debug)
log.debug("Found a matching ClientID configuration section.");
Enumeration enum2 = user.getElementsNamed("DurableSubscription");
while (enum2.hasMoreElements())
{
XElement t = (XElement)enum2.nextElement();
if (t.getField("Name").equals(sub.getSubscriptionName()))
{
subscription = t;
return subscription;
}
}
}
return subscription;
}
public String getStateFile()
{
return stateFile;
}
public String checkUser(String login, String passwd) throws JMSException
{
try
{
synchronized (stateConfig)
{
Enumeration enumeration = stateConfig.getElementsNamed("User");
while (enumeration.hasMoreElements())
{
XElement element = (XElement)enumeration.nextElement();
String name = element.getField("Name");
if (!name.equals(login))
{
continue;
}
String pw = element.getField("Password");
if (!passwd.equals(pw))
{
throw new JMSException("Bad password");
}
String clientId = null;
if (element.containsField("Id"))
{
clientId = element.getField("Id");
}
if (clientId != null)
{
synchronized (loggedOnClientIds)
{
if (loggedOnClientIds.contains(clientId))
{
throw new JMSSecurityException
("The login id has an assigned client id. " +
"That client id is already connected to the server!");
}
loggedOnClientIds.add(clientId);
}
}
return clientId;
}
throw new JMSSecurityException("This user does not exist");
}
}
catch (XElementException e)
{
log.error(e);
throw new JMSException("Invalid server user configuration.");
}
}
public void addLoggedOnClientId(String ID) throws JMSException
{
synchronized (loggedOnClientIds)
{
if (loggedOnClientIds.contains(ID))
{
throw new InvalidClientIDException("This loggedOnClientIds is already registered !");
}
}
synchronized (stateConfig)
{
Enumeration enumeration = stateConfig.getElementsNamed("User");
while (enumeration.hasMoreElements())
{
XElement element = (XElement)enumeration.nextElement();
try
{
if (element.containsField("Id") && element.getField("Id").equals(ID))
{
throw new InvalidClientIDException("This loggedOnClientIds is password protected !");
}
}
catch (XElementException ignore)
{
}
}
}
synchronized (loggedOnClientIds)
{
loggedOnClientIds.add(ID);
}
}
public void removeLoggedOnClientId(String ID)
{
synchronized (loggedOnClientIds)
{
loggedOnClientIds.remove(ID);
}
}
public void startService() throws Exception
{
loadConfig();
}
public Collection getDurableSubscriptionIdsForTopic(SpyTopic topic)
throws JMSException
{
Collection durableSubs = new ArrayList();
try
{
Enumeration enumeration = stateConfig.getElementsNamed("User/DurableSubscription");
while (enumeration.hasMoreElements())
{
XElement element = (XElement)enumeration.nextElement();
String clientId = element.getField("../Id");
String name = element.getField("Name");
String topicName = element.getField("TopicName");
if (topic.getName().equals(topicName))
{
durableSubs.add(new DurableSubscriptionID(clientId, name, null));
}
}
}
catch (XElementException e)
{
JMSException jmse = new JMSException("Error in statemanager xml");
jmse.setLinkedException(e);
throw jmse;
} return durableSubs;
}
public void loadConfig() throws IOException, XElementException
{
URL configURL = new URL(systemConfigURL, stateFile);
if (log.isDebugEnabled()) {
log.debug("Loading config from: " + configURL);
}
InputStream in = new BufferedInputStream(configURL.openStream());
try {
stateConfig = XElement.createFrom(in);
}
finally {
in.close();
}
}
public void saveConfig() throws IOException
{
URL configURL = new URL(systemConfigURL, stateFile);
if (configURL.getProtocol().equals("file")) {
File file = new File(configURL.getFile());
if (log.isDebugEnabled()) {
log.debug("Saving config to: " + file);
}
PrintStream stream = new PrintStream(new FileOutputStream(file));
try {
stream.print(stateConfig.toXML(true));
}
finally {
stream.close();
}
}
else {
log.error("Can not save configuration to non-file URL: " + configURL);
}
}
public String displayStateConfig() throws Exception
{
return stateConfig.toString();
}
}