package org.buddycloud.channelserver; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Properties; import org.apache.log4j.Logger; import org.buddycloud.channelserver.channel.LocalDomainChecker; import org.buddycloud.channelserver.utils.configuration.ConfigurationException; import org.buddycloud.channelserver.utils.configuration.DatabaseLoader; import org.buddycloud.channelserver.utils.configuration.FileLoader; import org.buddycloud.channelserver.utils.configuration.Loader; import org.xmpp.packet.JID; public class Configuration extends Properties { private static final Logger LOGGER = Logger.getLogger(Configuration.class); private static final long serialVersionUID = 1L; private static final String ARRAY_PROPERTY_SEPARATOR = ";"; private static final String INVALID_NODE = "Illegal node format"; public static final String CONFIGURATION_SERVER_DOMAIN = "server.domain"; public static final String CONFIGURATION_SERVER_CHANNELS_DOMAIN = "server.domain.channels"; public static final String CONFIGURATION_SERVER_TOPICS_DOMAIN = "server.domain.topics"; public static final String CONFIGURATION_LOCAL_DOMAIN_CHECKER = "server.domain.checker"; public static final String CONFIGURATION_ADMIN_USERS = "users.admin"; public static final String CONFIGURATION_CHANNELS_AUTOSUBSCRIBE = "channels.autosubscribe"; public static final String CONFIGURATION_CHANNELS_AUTOSUBSCRIBE_AUTOAPPROVE = "channels.autosubscribe.autoapprove"; public static final String CONFIGURATION_CHANNELS_DEFAULT_AFFILIATION = "channel.configuration.default.affiliation"; public static final String CONFIGURATION_CHANNELS_DEFAULT_ACCESSMODEL = "channel.configuration.default.accessmodel"; public static final String CONFIGURATION_CHANNELS_DEFAULT_DESCRIPTION = "channel.configuration.default.description"; public static final String CONFIGURATION_CHANNELS_DEFAULT_TITLE = "channel.configuration.default.title"; public static final String DISCOVERY_USE_DNS = "discovery.dns.enabled"; public static final String PERSIST_PRESENCE_DATA = "users.presence.persist"; public static final String NOTIFICATIONS_SENDTO = "notifications.sendTo"; public static final String NOTIFICATIONS_CONNECTED = "notifications.connected"; public static final String PURGE_REMOTE_ON_START = "sync.purge-on-start"; public static final String XMPP_PORT = "xmpp.port"; public static final String XMPP_HOST = "xmpp.host"; public static final String DATABASE_ENV = "DATABASE"; public static final String JDBC_CONNECTION_STRING = "jdbc.proxool.driver-url"; public static final String JDBC_PASSWORD = "jdbc.password"; public static final String JDBC_USER = "jdbc.user"; public static final String COMPONENT_STARTUP_DELAY = "component.startup.delay"; private static Configuration instance = null; private Collection<JID> adminUsers = new ArrayList<JID>(); private Collection<JID> autosubscribeChannels = new ArrayList<JID>(); private Properties conf; private boolean collectionsSetup = false; private Configuration() { try { conf = new Properties(); String databaseConnectionString = System.getenv(DATABASE_ENV); Loader loader = null; if (null == databaseConnectionString) { loader = new FileLoader(this); } else { loader = new DatabaseLoader(this, databaseConnectionString); } loader.load(); } catch (ConfigurationException e) { LOGGER.error(e.getMessage()); System.exit(1); } setupCollections(); } private void setupCollections() { if (true == collectionsSetup) { return; } adminUsers = getJIDArrayProperty(CONFIGURATION_ADMIN_USERS); autosubscribeChannels = getJIDArrayProperty(CONFIGURATION_CHANNELS_AUTOSUBSCRIBE); collectionsSetup = true; } public Collection<JID> getAdminUsers() { setupCollections(); return adminUsers; } public Collection<JID> getAutosubscribeChannels() { setupCollections(); return autosubscribeChannels; } public static Configuration getInstance() { if (null == instance) { instance = new Configuration(); } return instance; } public static void reset() { instance = null; } public String getProperty(String key) { return conf.getProperty(key); } @Override public synchronized Object remove(Object key) { return conf.remove(key); } public void clear() { conf.clear(); } public String getProperty(String key, String defaultValue) { return conf.getProperty(key, defaultValue); } public void putProperty(String key, String value) { conf.put(key, value); } private Collection<String> getStringArrayProperty(String key) { String prop = getProperty(key); if (null == prop) { return Collections.emptyList(); } return Arrays.asList(prop.split(ARRAY_PROPERTY_SEPARATOR)); } private Collection<JID> getJIDArrayProperty(String key) { Collection<String> props = getStringArrayProperty(key); Collection<JID> jids = new ArrayList<JID>(props.size()); for (String prop : props) { try { jids.add(new JID(prop)); } catch (IllegalArgumentException e) { LOGGER.error(e); } } return jids; } public ArrayList<JID> getNotificationsList(String event) { ArrayList<JID> notify = new ArrayList<JID>(); if (!getBooleanProperty(event, false)) { return notify; } String[] users = getProperty(NOTIFICATIONS_SENDTO).split(";"); JID userJid; for (String user : users) { try { userJid = new JID(user); notify.add(userJid); } catch (IllegalArgumentException e) { LOGGER.error(e); } } return notify; } public String getServerDomain() { return getProperty(CONFIGURATION_SERVER_DOMAIN); } public String getServerChannelsDomain() { return getProperty(CONFIGURATION_SERVER_CHANNELS_DOMAIN); } public String getServerTopicsDomain() { return getProperty(CONFIGURATION_SERVER_TOPICS_DOMAIN); } public boolean getBooleanProperty(final String key, final boolean defaultValue) { String value = getProperty(key); if (value != null) { return Boolean.valueOf(value); } return defaultValue; } public String getComponentPort() { return this.getProperty(XMPP_PORT, "5347"); } public String getXmppHost() { return this.getProperty(XMPP_HOST, "127.0.0.1"); } public boolean isLocalDomain(String domain) { return LocalDomainChecker.isLocal(domain, this); } public boolean isLocalNode(String nodeId) { if (false == nodeId.matches("/user/.+@.+/.+")) { LOGGER.debug("Node " + nodeId + " has an invalid format"); throw new IllegalArgumentException(INVALID_NODE); } String domain = new JID(nodeId.split("/")[2]).getDomain(); return isLocalDomain(domain); } public boolean isLocalJID(JID jid) { String domain = jid.getDomain(); return isLocalDomain(domain); } public String getDatabaseConnectionUrl() { String url = this.getProperty(JDBC_CONNECTION_STRING); if (this.containsKey(JDBC_USER)) { url += "?user=" + this.getProperty(JDBC_USER) + "&password=" + this.getProperty(JDBC_PASSWORD); } return url; } public boolean containsKey(Object value) { return conf.containsKey(value); } public Object setProperty(String key, String value) { return conf.setProperty(key, value); } public void removeKey(String key) { conf.remove(key); } public void load(InputStream stream) throws IOException { collectionsSetup = false; conf.load(stream); } }