Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

IdentityManager.java 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. /*
  2. * Copyright (c) 2006-2015 DMDirc Developers
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc.config;
  23. import com.dmdirc.Precondition;
  24. import com.dmdirc.interfaces.config.AggregateConfigProvider;
  25. import com.dmdirc.interfaces.config.ConfigProvider;
  26. import com.dmdirc.interfaces.config.ConfigProviderMigrator;
  27. import com.dmdirc.interfaces.config.IdentityController;
  28. import com.dmdirc.interfaces.config.IdentityFactory;
  29. import com.dmdirc.util.ClientInfo;
  30. import com.dmdirc.util.io.ConfigFile;
  31. import com.dmdirc.util.io.FileUtils;
  32. import com.dmdirc.util.io.InvalidConfigFileException;
  33. import com.google.common.collect.ArrayListMultimap;
  34. import com.google.common.collect.Multimap;
  35. import java.io.IOException;
  36. import java.lang.ref.WeakReference;
  37. import java.net.URISyntaxException;
  38. import java.nio.file.DirectoryStream;
  39. import java.nio.file.Files;
  40. import java.nio.file.Path;
  41. import java.util.ArrayList;
  42. import java.util.Collection;
  43. import java.util.Collections;
  44. import java.util.HashMap;
  45. import java.util.List;
  46. import java.util.Map;
  47. import java.util.Objects;
  48. import java.util.concurrent.ConcurrentHashMap;
  49. import java.util.stream.Collectors;
  50. import org.slf4j.Logger;
  51. import org.slf4j.LoggerFactory;
  52. import static com.dmdirc.util.LogUtils.FATAL_APP_ERROR;
  53. import static com.dmdirc.util.LogUtils.FATAL_USER_ERROR;
  54. import static com.dmdirc.util.LogUtils.USER_ERROR;
  55. import static com.google.common.base.Preconditions.checkArgument;
  56. import static com.google.common.base.Preconditions.checkNotNull;
  57. public class IdentityManager implements IdentityFactory, IdentityController {
  58. private static final Logger LOG = LoggerFactory.getLogger(IdentityManager.class);
  59. /** A regular expression that will match all characters illegal in file names. */
  60. private static final String ILLEGAL_CHARS = "[\\\\\"/:\\*\\?\"<>\\|]";
  61. /** The domain used for identity settings. */
  62. private static final String IDENTITY_DOMAIN = "identity";
  63. /** The domain used for profile settings. */
  64. private static final String PROFILE_DOMAIN = "profile";
  65. /** Base configuration directory where the main configuration file will be located. */
  66. private final Path configDirectory;
  67. /** Directory to save and load identities in. */
  68. private final Path identitiesDirectory;
  69. /**
  70. * The identities that have been loaded into this manager.
  71. *
  72. * Standard identities are inserted with a {@code null} key, custom identities use their
  73. * custom type as the key.
  74. */
  75. private final Multimap<String, ConfigFileBackedConfigProvider> identities = ArrayListMultimap.create();
  76. /** Map of paths to corresponding config providers, to facilitate reloading. */
  77. private final Map<Path, ConfigFileBackedConfigProvider> configProvidersByPath = new ConcurrentHashMap<>();
  78. /**
  79. * The {@link ConfigProviderListener}s that have registered with this manager.
  80. *
  81. * Listeners for standard identities are inserted with a {@code null} key, listeners for a
  82. * specific custom type use their type as the key.
  83. */
  84. private final Multimap<String, WeakReference<ConfigProviderListener>> listeners =
  85. ArrayListMultimap.create();
  86. /** Client info objecty. */
  87. private final ClientInfo clientInfo;
  88. /** The identity file used for the global config. */
  89. private ConfigFileBackedConfigProvider config;
  90. /** The identity file used for addon defaults. */
  91. private ConfigFileBackedConfigProvider addonConfig;
  92. /** The identity file bundled with the client containing version info. */
  93. private ConfigFileBackedConfigProvider versionConfig;
  94. /** The config manager used for global settings. */
  95. private AggregateConfigProvider globalconfig;
  96. /**
  97. * Creates a new instance of IdentityManager.
  98. *
  99. * @param baseDirectory The BASE config directory.
  100. * @param identitiesDirectory The directory to store identities in.
  101. */
  102. public IdentityManager(final Path baseDirectory, final Path identitiesDirectory,
  103. final ClientInfo clientInfo) {
  104. this.configDirectory = baseDirectory;
  105. this.identitiesDirectory = identitiesDirectory;
  106. this.clientInfo = clientInfo;
  107. }
  108. /**
  109. * Loads all identity files.
  110. *
  111. * @throws InvalidIdentityFileException If there is an error with the config file.
  112. */
  113. public void initialise() throws InvalidIdentityFileException {
  114. identities.clear();
  115. loadVersionIdentity();
  116. loadDefaults();
  117. loadUserIdentities();
  118. loadConfig();
  119. // Set up the identity used for the addons defaults
  120. final ConfigTarget target = new ConfigTarget();
  121. target.setGlobalDefault();
  122. target.setOrder(500000);
  123. final ConfigFile addonConfigFile = new ConfigFile((Path) null);
  124. final Map<String, String> addonSettings = new HashMap<>();
  125. addonSettings.put("name", "Addon defaults");
  126. addonConfigFile.addDomain("identity", addonSettings);
  127. addonConfig = new ConfigFileBackedConfigProvider(this, addonConfigFile, target);
  128. addConfigProvider(addonConfig);
  129. }
  130. /** Loads the default (built in) identities. */
  131. private void loadDefaults() {
  132. try {
  133. loadIdentity(FileUtils.getPathForResource(getClass().getResource(
  134. "defaults/default/defaults")));
  135. loadIdentity(FileUtils.getPathForResource(getClass().getResource(
  136. "defaults/default/formatter")));
  137. } catch (URISyntaxException ex) {
  138. LOG.error(FATAL_APP_ERROR, "Unable to load settings", ex);
  139. }
  140. final Path file = identitiesDirectory.resolve("modealiases");
  141. if (!Files.exists(file)) {
  142. try {
  143. Files.createDirectories(file);
  144. } catch (IOException ex) {
  145. LOG.info(USER_ERROR, "Unable to create modealiases directory", file, ex);
  146. }
  147. }
  148. try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(file)) {
  149. if (!directoryStream.iterator().hasNext()) {
  150. extractIdentities("modealiases");
  151. }
  152. } catch (IOException ex) {
  153. LOG.error(FATAL_USER_ERROR, "Unable to iterate required directory '{}'. Please check"
  154. + "file permissions or specify a different configuration directory.", file, ex);
  155. return;
  156. }
  157. loadUser(file);
  158. }
  159. /**
  160. * Extracts the specific set of default identities to the user's identity folder.
  161. *
  162. * @param target The target to be extracted
  163. */
  164. private void extractIdentities(final String target) {
  165. try {
  166. FileUtils.copyResources(getClass().getResource("defaults/" + target),
  167. identitiesDirectory);
  168. } catch (IOException ex) {
  169. LOG.warn(USER_ERROR, "Unable to extract default identities: {}", ex.getMessage(), ex);
  170. }
  171. }
  172. @Override
  173. public void loadUserIdentities() {
  174. if (!Files.exists(identitiesDirectory)) {
  175. try {
  176. Files.createDirectories(identitiesDirectory);
  177. } catch (IOException ex) {
  178. LOG.warn(USER_ERROR, "Unable to create identity dir", ex);
  179. }
  180. }
  181. loadUser(identitiesDirectory);
  182. }
  183. /**
  184. * Recursively loads files from the specified directory.
  185. *
  186. * @param dir The directory to be loaded
  187. */
  188. @Precondition({
  189. "The specified File is not null",
  190. "The specified File is a directory"
  191. })
  192. private void loadUser(final Path dir) {
  193. checkNotNull(dir);
  194. checkArgument(Files.isDirectory(dir));
  195. try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(dir)) {
  196. for (Path child : directoryStream) {
  197. if (Files.isDirectory(child)) {
  198. loadUser(child);
  199. } else {
  200. loadIdentity(child);
  201. }
  202. }
  203. } catch (IOException ex) {
  204. LOG.warn(USER_ERROR, "Unable to load user identity files from: {}", dir, ex);
  205. }
  206. }
  207. /**
  208. * Loads an identity from the specified file. If the identity already exists, it is told to
  209. * reload instead.
  210. *
  211. * @param file The file to load the identity from.
  212. */
  213. private void loadIdentity(final Path file) {
  214. synchronized (identities) {
  215. if (configProvidersByPath.containsKey(file)) {
  216. try {
  217. configProvidersByPath.get(file).reload();
  218. } catch (IOException ex) {
  219. LOG.warn(USER_ERROR, "I/O error when reloading identity file: {} ({})",
  220. file, ex.getMessage(), ex);
  221. } catch (InvalidConfigFileException ex) {
  222. // Do nothing
  223. }
  224. }
  225. }
  226. try {
  227. final ConfigFileBackedConfigProvider provider = new ConfigFileBackedConfigProvider(this, file, false);
  228. addConfigProvider(provider);
  229. configProvidersByPath.put(file, provider);
  230. } catch (InvalidIdentityFileException ex) {
  231. LOG.warn(USER_ERROR, "Invalid identity file: {} ({})", file, ex.getMessage(), ex);
  232. } catch (IOException ex) {
  233. LOG.warn(USER_ERROR, "I/O error when reading identity file: {}", file, ex);
  234. }
  235. }
  236. /**
  237. * Retrieves all known identities.
  238. *
  239. * @return A set of all known identities
  240. *
  241. * @since 0.6.4
  242. */
  243. private Iterable<ConfigFileBackedConfigProvider> getAllIdentities() {
  244. return identities.values();
  245. }
  246. /**
  247. * Returns the "group" to which the specified identity belongs. For custom identities this is
  248. * the custom identity type, otherwise this is <code>null</code>.
  249. *
  250. * @param identity The identity whose group is being retrieved
  251. *
  252. * @return The group of the specified identity
  253. *
  254. * @since 0.6.4
  255. */
  256. private String getGroup(final ConfigFileBackedConfigProvider identity) {
  257. return identity.getTarget().getType() == ConfigTarget.TYPE.CUSTOM
  258. ? identity.getTarget().getData() : null;
  259. }
  260. @Override
  261. public void loadVersionIdentity() {
  262. try {
  263. versionConfig = new ConfigFileBackedConfigProvider(IdentityManager.class.
  264. getResourceAsStream("/com/dmdirc/version.config"), false);
  265. addConfigProvider(versionConfig);
  266. } catch (IOException | InvalidIdentityFileException ex) {
  267. LOG.warn(USER_ERROR, "Unable to load version information.", ex);
  268. }
  269. }
  270. /**
  271. * Loads the config identity.
  272. *
  273. * @throws InvalidIdentityFileException if there is a problem with the config file.
  274. */
  275. private void loadConfig() throws InvalidIdentityFileException {
  276. try {
  277. final Path file = configDirectory.resolve("dmdirc.config");
  278. if (!Files.exists(file)) {
  279. Files.createFile(file);
  280. }
  281. config = new ConfigFileBackedConfigProvider(this, file, true);
  282. config.setOption("identity", "name", "Global config");
  283. configProvidersByPath.put(file, config);
  284. addConfigProvider(config);
  285. } catch (IOException ex) {
  286. LOG.warn(USER_ERROR, "I/O error when loading global config: {}", ex.getMessage(), ex);
  287. }
  288. }
  289. @Override
  290. public ConfigProvider getUserSettings() {
  291. return config;
  292. }
  293. @Override
  294. public ConfigProvider getAddonSettings() {
  295. return addonConfig;
  296. }
  297. @Override
  298. public ConfigProvider getVersionSettings() {
  299. return versionConfig;
  300. }
  301. @Override
  302. public void saveAll() {
  303. synchronized (identities) {
  304. for (ConfigProvider identity : getAllIdentities()) {
  305. identity.save();
  306. }
  307. }
  308. }
  309. @Override
  310. public void addConfigProvider(final ConfigFileBackedConfigProvider identity) {
  311. checkNotNull(identity);
  312. final String target = getGroup(identity);
  313. if (identities.containsEntry(target, identity)) {
  314. removeConfigProvider(identity);
  315. }
  316. synchronized (identities) {
  317. identities.put(target, identity);
  318. }
  319. LOG.debug("Adding identity: {} (group: {})", new Object[]{identity, target});
  320. synchronized (listeners) {
  321. listeners.get(target).stream()
  322. .map(WeakReference::get)
  323. .filter(Objects::nonNull)
  324. .forEach(l -> l.configProviderAdded(identity));
  325. }
  326. }
  327. @Override
  328. public void removeConfigProvider(final ConfigFileBackedConfigProvider identity) {
  329. checkNotNull(identity);
  330. final String group = getGroup(identity);
  331. checkArgument(identities.containsEntry(group, identity));
  332. Path path = null;
  333. for (Map.Entry<Path, ConfigFileBackedConfigProvider> entry : configProvidersByPath.entrySet()) {
  334. if (entry.getValue() == identity) {
  335. path = entry.getKey();
  336. }
  337. }
  338. if (path != null) {
  339. configProvidersByPath.remove(path);
  340. }
  341. synchronized (identities) {
  342. identities.remove(group, identity);
  343. }
  344. synchronized (listeners) {
  345. listeners.get(group).stream()
  346. .map(WeakReference::get)
  347. .filter(Objects::nonNull)
  348. .forEach(l -> l.configProviderRemoved(identity));
  349. }
  350. }
  351. private void registerIdentityListener(final ConfigProviderListener listener) {
  352. registerIdentityListener(null, listener);
  353. }
  354. // TODO: It feels like this method should be called at some point...
  355. private void unregisterIdentityListener(final ConfigProviderListener listener) {
  356. synchronized (listeners) {
  357. listeners.entries().stream().filter(e -> {
  358. final ConfigProviderListener value = e.getValue().get();
  359. return value == null || value.equals(listener);
  360. }).forEach(e -> listeners.remove(e.getKey(), e.getValue()));
  361. }
  362. }
  363. private void registerIdentityListener(final String type, final ConfigProviderListener listener) {
  364. checkNotNull(listener);
  365. synchronized (listeners) {
  366. listeners.put(type, new WeakReference<>(listener));
  367. }
  368. }
  369. @Override
  370. public Collection<ConfigProvider> getProvidersByType(final String type) {
  371. return Collections.unmodifiableCollection(identities.get(type));
  372. }
  373. /**
  374. * Retrieves a list of all config sources that should be applied to the specified config
  375. * manager.
  376. *
  377. * @param manager The manager requesting sources
  378. *
  379. * @return A list of all matching config sources
  380. */
  381. List<ConfigFileBackedConfigProvider> getIdentitiesForManager(final ConfigManager manager) {
  382. final List<ConfigFileBackedConfigProvider> sources = new ArrayList<>();
  383. synchronized (identities) {
  384. sources.addAll(identities.get(null).stream()
  385. .filter(manager::identityApplies)
  386. .collect(Collectors.toList()));
  387. }
  388. Collections.sort(sources, new ConfigProviderTargetComparator());
  389. LOG.debug("Found {} source(s) for {}", sources.size(), manager);
  390. return sources;
  391. }
  392. @Override
  393. public synchronized AggregateConfigProvider getGlobalConfiguration() {
  394. if (globalconfig == null) {
  395. globalconfig = createAggregateConfig("", "", "", "");
  396. }
  397. return globalconfig;
  398. }
  399. @Override
  400. public ConfigProvider createChannelConfig(final String network, final String channel) {
  401. if (network == null || network.isEmpty()) {
  402. throw new IllegalArgumentException("getChannelConfig called "
  403. + "with null or empty network\n\nNetwork: " + network);
  404. }
  405. if (channel == null || channel.isEmpty()) {
  406. throw new IllegalArgumentException("getChannelConfig called "
  407. + "with null or empty channel\n\nChannel: " + channel);
  408. }
  409. final String myTarget = (channel + '@' + network).toLowerCase();
  410. synchronized (identities) {
  411. for (ConfigFileBackedConfigProvider identity : identities.get(null)) {
  412. if (identity.getTarget().getType() == ConfigTarget.TYPE.CHANNEL
  413. && identity.getTarget().getData().equalsIgnoreCase(myTarget)) {
  414. return identity;
  415. }
  416. }
  417. }
  418. // We need to create one
  419. final ConfigTarget target = new ConfigTarget();
  420. target.setChannel(myTarget);
  421. return createConfig(target);
  422. }
  423. @Override
  424. public ConfigProvider createNetworkConfig(final String network) {
  425. if (network == null || network.isEmpty()) {
  426. throw new IllegalArgumentException("getNetworkConfig called "
  427. + "with null or empty network\n\nNetwork:" + network);
  428. }
  429. final String myTarget = network.toLowerCase();
  430. synchronized (identities) {
  431. for (ConfigFileBackedConfigProvider identity : identities.get(null)) {
  432. if (identity.getTarget().getType() == ConfigTarget.TYPE.NETWORK
  433. && identity.getTarget().getData().equalsIgnoreCase(myTarget)) {
  434. return identity;
  435. }
  436. }
  437. }
  438. // We need to create one
  439. final ConfigTarget target = new ConfigTarget();
  440. target.setNetwork(myTarget);
  441. return createConfig(target);
  442. }
  443. @Override
  444. public ConfigProvider createServerConfig(final String server) {
  445. if (server == null || server.isEmpty()) {
  446. throw new IllegalArgumentException("getServerConfig called "
  447. + "with null or empty server\n\nServer: " + server);
  448. }
  449. final String myTarget = server.toLowerCase();
  450. synchronized (identities) {
  451. for (ConfigFileBackedConfigProvider identity : identities.get(null)) {
  452. if (identity.getTarget().getType() == ConfigTarget.TYPE.SERVER
  453. && identity.getTarget().getData().equalsIgnoreCase(myTarget)) {
  454. return identity;
  455. }
  456. }
  457. }
  458. // We need to create one
  459. final ConfigTarget target = new ConfigTarget();
  460. target.setServer(myTarget);
  461. return createConfig(target);
  462. }
  463. @Override
  464. public ConfigProvider createCustomConfig(final String name, final String type) {
  465. final Map<String, Map<String, String>> settings = new HashMap<>();
  466. settings.put(IDENTITY_DOMAIN, new HashMap<>(2));
  467. settings.get(IDENTITY_DOMAIN).put("name", name);
  468. settings.get(IDENTITY_DOMAIN).put("type", type);
  469. try {
  470. return createIdentity(settings);
  471. } catch (InvalidIdentityFileException | IOException ex) {
  472. LOG.warn(USER_ERROR, "Unable to create identity", ex);
  473. return null;
  474. }
  475. }
  476. @Override
  477. public ConfigProvider createProfileConfig(final String name) {
  478. final Map<String, Map<String, String>> settings = new HashMap<>();
  479. settings.put(IDENTITY_DOMAIN, new HashMap<>(1));
  480. settings.put(PROFILE_DOMAIN, new HashMap<>(2));
  481. final String nick = System.getProperty("user.name").replace(' ', '_');
  482. settings.get(IDENTITY_DOMAIN).put("name", name);
  483. settings.get(PROFILE_DOMAIN).put("nicknames", nick);
  484. settings.get(PROFILE_DOMAIN).put("realname", nick);
  485. try {
  486. return createIdentity(settings);
  487. } catch (InvalidIdentityFileException | IOException ex) {
  488. LOG.warn(USER_ERROR, "Unable to create identity", ex);
  489. return null;
  490. }
  491. }
  492. @Override
  493. public ConfigProvider createConfig(final ConfigTarget target) {
  494. final Map<String, Map<String, String>> settings = new HashMap<>();
  495. settings.put(IDENTITY_DOMAIN, new HashMap<>(2));
  496. settings.get(IDENTITY_DOMAIN).put("name", target.getData());
  497. settings.get(IDENTITY_DOMAIN).put(target.getTypeName(), target.getData());
  498. try {
  499. return createIdentity(settings);
  500. } catch (InvalidIdentityFileException | IOException ex) {
  501. LOG.warn(USER_ERROR, "Unable to create identity", ex);
  502. return null;
  503. }
  504. }
  505. /**
  506. * Creates a new identity containing the specified properties.
  507. *
  508. * @param settings The settings to populate the identity with
  509. *
  510. * @return A new identity containing the specified properties
  511. *
  512. * @throws IOException If the file cannot be created
  513. * @throws InvalidIdentityFileException If the settings are invalid
  514. * @since 0.6.3m1
  515. */
  516. private ConfigFileBackedConfigProvider createIdentity(
  517. final Map<String, Map<String, String>> settings)
  518. throws IOException, InvalidIdentityFileException {
  519. if (!settings.containsKey(IDENTITY_DOMAIN)
  520. || !settings.get(IDENTITY_DOMAIN).containsKey("name")
  521. || settings.get(IDENTITY_DOMAIN).get("name").isEmpty()) {
  522. throw new InvalidIdentityFileException("identity.name is not set");
  523. }
  524. final String name = settings.get(IDENTITY_DOMAIN).get("name").replaceAll(ILLEGAL_CHARS, "_");
  525. Path file = identitiesDirectory.resolve(name);
  526. int attempt = 1;
  527. while (Files.exists(file)) {
  528. file = identitiesDirectory.resolve(name + '-' + attempt);
  529. attempt++;
  530. }
  531. final ConfigFile configFile = new ConfigFile(file);
  532. for (Map.Entry<String, Map<String, String>> entry : settings.entrySet()) {
  533. configFile.addDomain(entry.getKey(), entry.getValue());
  534. }
  535. configFile.write();
  536. final ConfigFileBackedConfigProvider identity = new ConfigFileBackedConfigProvider(this,
  537. file, false);
  538. addConfigProvider(identity);
  539. return identity;
  540. }
  541. /**
  542. * Finds and adds sources for the given manager, and adds it as an identity listener.
  543. *
  544. * @param configManager The manager to be initialised.
  545. */
  546. private void setUpConfigManager(final ConfigManager configManager) {
  547. final List<ConfigFileBackedConfigProvider> sources = getIdentitiesForManager(configManager);
  548. for (ConfigFileBackedConfigProvider identity : sources) {
  549. LOG.trace("Found {}", identity);
  550. configManager.checkIdentity(identity);
  551. }
  552. registerIdentityListener(configManager);
  553. }
  554. @Override
  555. public ConfigProviderMigrator createMigratableConfig(final String protocol,
  556. final String ircd, final String network, final String server) {
  557. final ConfigManager configManager = new ConfigManager(clientInfo, this, protocol,
  558. ircd, network, server);
  559. setUpConfigManager(configManager);
  560. return new ConfigManagerMigrator(configManager);
  561. }
  562. @Override
  563. public ConfigProviderMigrator createMigratableConfig(final String protocol,
  564. final String ircd, final String network, final String server, final String channel) {
  565. final ConfigManager configManager = new ConfigManager(clientInfo, this, protocol,
  566. ircd, network, server, channel);
  567. setUpConfigManager(configManager);
  568. return new ConfigManagerMigrator(configManager);
  569. }
  570. @Override
  571. public AggregateConfigProvider createAggregateConfig(final String protocol, final String ircd,
  572. final String network, final String server) {
  573. final ConfigManager configManager = new ConfigManager(clientInfo, this, protocol,
  574. ircd, network, server);
  575. setUpConfigManager(configManager);
  576. return configManager;
  577. }
  578. @Override
  579. public AggregateConfigProvider createAggregateConfig(final String protocol, final String ircd,
  580. final String network, final String server, final String channel) {
  581. final ConfigManager configManager = new ConfigManager(clientInfo, this, protocol,
  582. ircd, network, server, channel);
  583. setUpConfigManager(configManager);
  584. return configManager;
  585. }
  586. }