/* * Copyright (c) 2006-2014 DMDirc Developers * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.dmdirc; import com.dmdirc.commandparser.parsers.ServerCommandParser; import com.dmdirc.events.UserErrorEvent; import com.dmdirc.interfaces.CommandController; import com.dmdirc.interfaces.Connection; import com.dmdirc.interfaces.ConnectionManager; import com.dmdirc.interfaces.config.ConfigProvider; import com.dmdirc.interfaces.config.ConfigProviderMigrator; import com.dmdirc.interfaces.config.IdentityController; import com.dmdirc.interfaces.config.IdentityFactory; import com.dmdirc.logger.ErrorLevel; import com.dmdirc.parser.common.ChannelJoinRequest; import com.dmdirc.ui.WindowManager; import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.Executors; import javax.inject.Inject; import javax.inject.Provider; import javax.inject.Singleton; import static com.google.common.base.Preconditions.checkArgument; /** * The ServerManager maintains a list of all servers, and provides methods to search or iterate over * them. */ @Singleton public class ServerManager implements ConnectionManager { /** All servers that currently exist. */ private final Set servers = new CopyOnWriteArraySet<>(); /** The identity controller to use to find profiles. */ private final IdentityController identityController; /** A provider of {@link CommandController}s to pass to servers. */ private final Provider commandController; /** The identity factory to give to servers. */ private final IdentityFactory identityFactory; /** Window manager to add new servers to. */ private final WindowManager windowManager; /** Concrete server factory to use. */ private final ServerFactoryImpl serverFactoryImpl; /** Event bus for servers. */ private final DMDircMBassador eventBus; /** * Creates a new instance of ServerManager. * * @param identityController The identity controller to use to find profiles. * @param identityFactory The factory to use to create new identities. * @param commandController A provider of {@link CommandController}s to pass to servers. * @param windowManager Window manager to add new servers to. * @param serverFactory The factory to use to create servers. * @param eventBus The event bus to pass to servers. */ @Inject public ServerManager( final IdentityController identityController, final IdentityFactory identityFactory, final Provider commandController, final WindowManager windowManager, final ServerFactoryImpl serverFactory, final DMDircMBassador eventBus) { this.identityController = identityController; this.identityFactory = identityFactory; this.commandController = commandController; this.windowManager = windowManager; this.serverFactoryImpl = serverFactory; this.eventBus = eventBus; } @Override public Server createServer(final URI uri, final ConfigProvider profile) { final ConfigProviderMigrator configProvider = identityFactory.createMigratableConfig(uri. getScheme(), "", "", uri.getHost()); final Server server = serverFactoryImpl.getServer( configProvider, new ServerCommandParser(configProvider.getConfigProvider(), commandController.get(), eventBus), Executors.newScheduledThreadPool(1, new ThreadFactoryBuilder().setNameFormat("server-timer-%d").build()), uri, profile); registerServer(server); windowManager.addWindow(server); if (configProvider.getConfigProvider().getOptionBool("general", "showrawwindow")) { server.addRaw(); } return server; } /** * Registers a new server with the manager. * * @param server The server to be registered */ public void registerServer(final Server server) { servers.add(server); } /** * Unregisters a server from the manager. The request is ignored if the ServerManager is in the * process of closing all servers. * * @param server The server to be unregistered */ public void unregisterServer(final Server server) { servers.remove(server); } @Override public List getConnections() { return new ArrayList(servers); } @Override public void disconnectAll(final String message) { for (Server server : servers) { server.disconnect(message); } } @Override public void closeAll(final String message) { for (Server server : servers) { server.disconnect(message); server.close(); } } @Override public int getConnectionCount() { return servers.size(); } @Override public List getConnectionsByNetwork(final String network) { final List res = new ArrayList<>(); for (Server server : servers) { if (server.isNetwork(network)) { res.add(server); } } return res; } @Override public Connection connectToAddress(final URI uri) { return connectToAddress(uri, identityController.getProvidersByType("profile").get(0)); } @Override public Connection connectToAddress(final URI uri, final ConfigProvider profile) { checkArgument(profile.isProfile()); Connection server = null; for (Server loopServer : servers) { if (loopServer.compareURI(uri)) { server = loopServer; break; } } if (server == null) { server = createServer(uri, profile); server.connect(); return server; } if (server.getState().isDisconnected()) { server.connect(uri, profile); } else { final Collection joinRequests = server.getParser().extractChannels(uri); server.join(joinRequests.toArray(new ChannelJoinRequest[joinRequests.size()])); } return server; } @Override public void joinDevChat() { final List qnetServers = getConnectionsByNetwork("Quakenet"); Connection connectedServer = null; for (Connection server : qnetServers) { if (server.getState() == ServerState.CONNECTED) { connectedServer = server; if (server.hasChannel("#DMDirc")) { server.join(new ChannelJoinRequest("#DMDirc")); return; } } } if (connectedServer == null) { try { connectToAddress(new URI("irc://irc.quakenet.org/DMDirc")); } catch (URISyntaxException ex) { eventBus.publishAsync(new UserErrorEvent(ErrorLevel.MEDIUM, ex, "Unable to construct new server", "")); } } else { connectedServer.join(new ChannelJoinRequest("#DMDirc")); } } }