You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IdentityManager.java 24KB

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