Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

IdentityManager.java 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. /*
  2. * Copyright (c) 2006-2014 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.ConfigProviderListener;
  27. import com.dmdirc.interfaces.config.ConfigProviderMigrator;
  28. import com.dmdirc.interfaces.config.IdentityController;
  29. import com.dmdirc.interfaces.config.IdentityFactory;
  30. import com.dmdirc.logger.ErrorLevel;
  31. import com.dmdirc.logger.Logger;
  32. import com.dmdirc.updater.Version;
  33. import com.dmdirc.util.collections.MapList;
  34. import com.dmdirc.util.collections.WeakMapList;
  35. import com.dmdirc.util.io.ConfigFile;
  36. import com.dmdirc.util.io.InvalidConfigFileException;
  37. import com.dmdirc.util.resourcemanager.ResourceManager;
  38. import java.io.File;
  39. import java.io.IOException;
  40. import java.util.ArrayList;
  41. import java.util.Collections;
  42. import java.util.HashMap;
  43. import java.util.LinkedHashSet;
  44. import java.util.List;
  45. import java.util.Map;
  46. import java.util.Set;
  47. import org.slf4j.LoggerFactory;
  48. import static com.google.common.base.Preconditions.checkArgument;
  49. import static com.google.common.base.Preconditions.checkNotNull;
  50. /**
  51. * The identity manager manages all known identities, providing easy methods
  52. * to access them.
  53. */
  54. public class IdentityManager implements IdentityFactory, IdentityController {
  55. private static final org.slf4j.Logger log = LoggerFactory.getLogger(IdentityManager.class);
  56. /** A regular expression that will match all characters illegal in file names. */
  57. private static final String ILLEGAL_CHARS = "[\\\\\"/:\\*\\?\"<>\\|]";
  58. /** The domain used for identity settings. */
  59. private static final String IDENTITY_DOMAIN = "identity";
  60. /** The domain used for profile settings. */
  61. private static final String PROFILE_DOMAIN = "profile";
  62. /** A singleton instance of IdentityManager. */
  63. private static IdentityManager instance;
  64. /** Config Directory. */
  65. private String configDirectory;
  66. /**
  67. * The identities that have been loaded into this manager.
  68. *
  69. * Standard identities are inserted with a <code>null</code> key, custom
  70. * identities use their custom type as the key.
  71. */
  72. private final MapList<String, ConfigProvider> identities = new MapList<>();
  73. /**
  74. * The {@link IdentityListener}s that have registered with this manager.
  75. *
  76. * Listeners for standard identities are inserted with a <code>null</code>
  77. * key, listeners for a specific custom type use their type as the key.
  78. */
  79. private final MapList<String, ConfigProviderListener> listeners = new WeakMapList<>();
  80. /** The identity file used for the global config. */
  81. private ConfigProvider config;
  82. /** The identity file used for addon defaults. */
  83. private ConfigProvider addonConfig;
  84. /** The identity file bundled with the client containing version info. */
  85. private ConfigProvider versionConfig;
  86. /** The config manager used for global settings. */
  87. private ConfigManager globalconfig;
  88. /**
  89. * Creates a new instance of IdentityManager.
  90. *
  91. * @param directory The BASE config directory.
  92. */
  93. public IdentityManager(final String directory) {
  94. this.configDirectory = directory;
  95. }
  96. /** {@inheritDoc} */
  97. @Override
  98. @Deprecated
  99. public String getConfigurationDirectory() {
  100. return configDirectory;
  101. }
  102. /**
  103. * Loads all identity files.
  104. *
  105. * @throws InvalidIdentityFileException If there is an error with the config
  106. * file.
  107. */
  108. public void initialise() throws InvalidIdentityFileException {
  109. identities.clear();
  110. loadVersionIdentity();
  111. loadDefaults();
  112. loadUserIdentities();
  113. loadConfig();
  114. if (getProvidersByType("profile").isEmpty()) {
  115. createProfileConfig("Default Profile");
  116. }
  117. // Set up the identity used for the addons defaults
  118. final ConfigTarget target = new ConfigTarget();
  119. target.setGlobalDefault();
  120. target.setOrder(500000);
  121. final ConfigFile addonConfigFile = new ConfigFile((File) null);
  122. final Map<String, String> addonSettings = new HashMap<>();
  123. addonSettings.put("name", "Addon defaults");
  124. addonConfigFile.addDomain("identity", addonSettings);
  125. addonConfig = new ConfigFileBackedConfigProvider(addonConfigFile, target);
  126. addConfigProvider(addonConfig);
  127. if (!getGlobalConfiguration().hasOptionString("identity", "defaultsversion")) {
  128. Logger.userError(ErrorLevel.FATAL, "Default settings "
  129. + "could not be loaded");
  130. }
  131. }
  132. /** Loads the default (built in) identities. */
  133. private void loadDefaults() {
  134. final String[] targets = {"default", "modealiases"};
  135. final String dir = getUserSettingsDirectory();
  136. for (String target : targets) {
  137. final File file = new File(dir + target);
  138. if (file.exists() && !file.isDirectory()) {
  139. boolean success = false;
  140. for (int i = 0; i < 10 && !success; i++) {
  141. final String suffix = ".old" + (i > 0 ? "-" + i : "");
  142. success = file.renameTo(new File(file.getParentFile(), target + suffix));
  143. }
  144. if (!success) {
  145. Logger.userError(ErrorLevel.HIGH, "Unable to create directory for "
  146. + "default settings folder (" + target + ")", "A file "
  147. + "with that name already exists, and couldn't be renamed."
  148. + " Rename or delete " + file.getAbsolutePath());
  149. continue;
  150. }
  151. }
  152. if (!file.exists() || file.listFiles() == null || file.listFiles().length == 0) {
  153. file.mkdirs();
  154. extractIdentities(target);
  155. }
  156. loadUser(file);
  157. }
  158. extractFormatters();
  159. // If the bundled defaults are newer than the ones the user is
  160. // currently using, extract them.
  161. if (getGlobalConfiguration().hasOptionString("identity", "defaultsversion")
  162. && getGlobalConfiguration().hasOptionString("updater", "bundleddefaultsversion")) {
  163. final Version installedVersion = new Version(getGlobalConfiguration()
  164. .getOption("identity", "defaultsversion"));
  165. final Version bundledVersion = new Version(getGlobalConfiguration()
  166. .getOption("updater", "bundleddefaultsversion"));
  167. if (bundledVersion.compareTo(installedVersion) > 0) {
  168. extractIdentities("default");
  169. loadUser(new File(dir, "default"));
  170. }
  171. }
  172. }
  173. /**
  174. * Extracts the bundled formatters to the user's identity folder.
  175. */
  176. private void extractFormatters() {
  177. try {
  178. ResourceManager.getResourceManager().extractResource(
  179. "com/dmdirc/config/defaults/default/formatter",
  180. getUserSettingsDirectory() + "default/", false);
  181. } catch (IOException ex) {
  182. Logger.userError(ErrorLevel.MEDIUM, "Unable to extract default "
  183. + "formatters: " + ex.getMessage());
  184. }
  185. }
  186. /**
  187. * Extracts the specific set of default identities to the user's identity
  188. * folder.
  189. *
  190. * @param target The target to be extracted
  191. */
  192. private void extractIdentities(final String target) {
  193. try {
  194. ResourceManager.getResourceManager().extractResources(
  195. "com/dmdirc/config/defaults/" + target,
  196. getUserSettingsDirectory() + target, false);
  197. } catch (IOException ex) {
  198. Logger.userError(ErrorLevel.MEDIUM, "Unable to extract default "
  199. + "identities: " + ex.getMessage());
  200. }
  201. }
  202. /** {@inheritDoc} */
  203. @Override
  204. @Deprecated
  205. public String getUserSettingsDirectory() {
  206. return configDirectory + "identities" + System.getProperty("file.separator");
  207. }
  208. /** {@inheritDoc} */
  209. @Override
  210. public void loadUserIdentities() {
  211. final File dir = new File(getUserSettingsDirectory());
  212. if (!dir.exists()) {
  213. try {
  214. dir.mkdirs();
  215. dir.createNewFile();
  216. } catch (IOException ex) {
  217. Logger.userError(ErrorLevel.MEDIUM, "Unable to create identity dir");
  218. }
  219. }
  220. loadUser(dir);
  221. }
  222. /**
  223. * Recursively loads files from the specified directory.
  224. *
  225. * @param dir The directory to be loaded
  226. */
  227. @Precondition({
  228. "The specified File is not null",
  229. "The specified File is a directory"
  230. })
  231. private void loadUser(final File dir) {
  232. checkNotNull(dir);
  233. checkArgument(dir.isDirectory());
  234. if (dir.listFiles() == null) {
  235. Logger.userError(ErrorLevel.MEDIUM,
  236. "Unable to load user identity files from "
  237. + dir.getAbsolutePath());
  238. } else {
  239. for (File file : dir.listFiles()) {
  240. if (file.isDirectory()) {
  241. loadUser(file);
  242. } else {
  243. loadIdentity(file);
  244. }
  245. }
  246. }
  247. }
  248. /**
  249. * Loads an identity from the specified file. If the identity already
  250. * exists, it is told to reload instead.
  251. *
  252. * @param file The file to load the identity from.
  253. */
  254. private void loadIdentity(final File file) {
  255. synchronized (identities) {
  256. for (ConfigProvider identity : getAllIdentities()) {
  257. if ((identity instanceof ConfigFileBackedConfigProvider) && ((ConfigFileBackedConfigProvider) identity).isFile(file)) {
  258. // TODO: This manager should keep a list of files->identities instead of
  259. // relying on the identities remembering.
  260. try {
  261. identity.reload();
  262. } catch (IOException ex) {
  263. Logger.userError(ErrorLevel.MEDIUM,
  264. "I/O error when reloading identity file: "
  265. + file.getAbsolutePath() + " (" + ex.getMessage() + ")");
  266. } catch (InvalidConfigFileException ex) {
  267. // Do nothing
  268. }
  269. return;
  270. }
  271. }
  272. }
  273. try {
  274. addConfigProvider(new ConfigFileBackedConfigProvider(file, false));
  275. } catch (InvalidIdentityFileException ex) {
  276. Logger.userError(ErrorLevel.MEDIUM,
  277. "Invalid identity file: " + file.getAbsolutePath()
  278. + " (" + ex.getMessage() + ")");
  279. } catch (IOException ex) {
  280. Logger.userError(ErrorLevel.MEDIUM,
  281. "I/O error when reading identity file: "
  282. + file.getAbsolutePath());
  283. }
  284. }
  285. /**
  286. * Retrieves all known identities.
  287. *
  288. * @return A set of all known identities
  289. * @since 0.6.4
  290. */
  291. private Set<ConfigProvider> getAllIdentities() {
  292. final Set<ConfigProvider> res = new LinkedHashSet<>();
  293. for (Map.Entry<String, List<ConfigProvider>> entry : identities.entrySet()) {
  294. res.addAll(entry.getValue());
  295. }
  296. return res;
  297. }
  298. /**
  299. * Returns the "group" to which the specified identity belongs. For custom
  300. * identities this is the custom identity type, otherwise this is
  301. * <code>null</code>.
  302. *
  303. * @param identity The identity whose group is being retrieved
  304. * @return The group of the specified identity
  305. * @since 0.6.4
  306. */
  307. private String getGroup(final ConfigProvider identity) {
  308. return identity.getTarget().getType() == ConfigTarget.TYPE.CUSTOM
  309. ? identity.getTarget().getData() : null;
  310. }
  311. /** {@inheritDoc} */
  312. @Override
  313. public void loadVersionIdentity() {
  314. try {
  315. versionConfig = new ConfigFileBackedConfigProvider(IdentityManager.class.getResourceAsStream("/com/dmdirc/version.config"), false);
  316. addConfigProvider(versionConfig);
  317. } catch (IOException | InvalidIdentityFileException ex) {
  318. Logger.appError(ErrorLevel.FATAL, "Unable to load version information", ex);
  319. }
  320. }
  321. /**
  322. * Loads the config identity.
  323. *
  324. * @throws InvalidIdentityFileException if there is a problem with the
  325. * config file.
  326. */
  327. private void loadConfig() throws InvalidIdentityFileException {
  328. try {
  329. final File file = new File(configDirectory + "dmdirc.config");
  330. if (!file.exists()) {
  331. file.createNewFile();
  332. }
  333. config = new ConfigFileBackedConfigProvider(file, true);
  334. config.setOption("identity", "name", "Global config");
  335. addConfigProvider(config);
  336. } catch (IOException ex) {
  337. Logger.userError(ErrorLevel.FATAL, "I/O error when loading global config: "
  338. + ex.getMessage(), ex);
  339. }
  340. }
  341. /** {@inheritDoc} */
  342. @Override
  343. public ConfigProvider getUserSettings() {
  344. return config;
  345. }
  346. /** {@inheritDoc} */
  347. @Override
  348. public ConfigProvider getAddonSettings() {
  349. return addonConfig;
  350. }
  351. /** {@inheritDoc} */
  352. @Override
  353. public ConfigProvider getVersionSettings() {
  354. return versionConfig;
  355. }
  356. /** {@inheritDoc} */
  357. @Override
  358. public void saveAll() {
  359. synchronized (identities) {
  360. for (ConfigProvider identity : getAllIdentities()) {
  361. identity.save();
  362. }
  363. }
  364. }
  365. /** {@inheritDoc} */
  366. @Override
  367. public void addConfigProvider(final ConfigProvider identity) {
  368. checkNotNull(identity);
  369. final String target = getGroup(identity);
  370. if (identities.containsValue(target, identity)) {
  371. removeConfigProvider(identity);
  372. }
  373. synchronized (identities) {
  374. identities.add(target, identity);
  375. }
  376. log.debug("Adding identity: {} (group: {})",
  377. new Object[]{ identity, target });
  378. synchronized (listeners) {
  379. for (ConfigProviderListener listener : listeners.safeGet(target)) {
  380. listener.configProviderAdded(identity);
  381. }
  382. }
  383. }
  384. /** {@inheritDoc} */
  385. @Override
  386. public void removeConfigProvider(final ConfigProvider identity) {
  387. checkNotNull(identity);
  388. final String group = getGroup(identity);
  389. checkArgument(identities.containsValue(group, identity));
  390. synchronized (identities) {
  391. identities.remove(group, identity);
  392. }
  393. synchronized (listeners) {
  394. for (ConfigProviderListener listener : listeners.safeGet(group)) {
  395. listener.configProviderRemoved(identity);
  396. }
  397. }
  398. }
  399. /** {@inheritDoc} */
  400. @Override
  401. public void registerIdentityListener(final ConfigProviderListener listener) {
  402. registerIdentityListener(null, listener);
  403. }
  404. /** {@inheritDoc} */
  405. @Override
  406. public void unregisterIdentityListener(final ConfigProviderListener listener) {
  407. listeners.removeFromAll(listener);
  408. }
  409. /** {@inheritDoc} */
  410. @Override
  411. public void registerIdentityListener(final String type, final ConfigProviderListener listener) {
  412. checkNotNull(listener);
  413. synchronized (listeners) {
  414. listeners.add(type, listener);
  415. }
  416. }
  417. /** {@inheritDoc} */
  418. @Override
  419. public List<ConfigProvider> getProvidersByType(final String type) {
  420. return Collections.unmodifiableList(identities.safeGet(type));
  421. }
  422. /**
  423. * Retrieves a list of all config sources that should be applied to the
  424. * specified config manager.
  425. *
  426. * @param manager The manager requesting sources
  427. * @return A list of all matching config sources
  428. */
  429. public List<ConfigProvider> getIdentitiesForManager(final ConfigManager manager) {
  430. final List<ConfigProvider> sources = new ArrayList<>();
  431. synchronized (identities) {
  432. for (ConfigProvider identity : identities.safeGet(null)) {
  433. if (manager.identityApplies(identity)) {
  434. sources.add(identity);
  435. }
  436. }
  437. }
  438. // TODO: Expose this as a comparator other classes can use.
  439. Collections.sort(sources, new ConfigProviderTargetComparator());
  440. return sources;
  441. }
  442. /** {@inheritDoc} */
  443. @Override
  444. public synchronized AggregateConfigProvider getGlobalConfiguration() {
  445. if (globalconfig == null) {
  446. globalconfig = new ConfigManager("", "", "", "");
  447. }
  448. return globalconfig;
  449. }
  450. /** {@inheritDoc} */
  451. @Override
  452. public ConfigProvider createChannelConfig(final String network, final String channel) {
  453. if (network == null || network.isEmpty()) {
  454. throw new IllegalArgumentException("getChannelConfig called "
  455. + "with null or empty network\n\nNetwork: " + network);
  456. }
  457. if (channel == null || channel.isEmpty()) {
  458. throw new IllegalArgumentException("getChannelConfig called "
  459. + "with null or empty channel\n\nChannel: " + channel);
  460. }
  461. final String myTarget = (channel + "@" + network).toLowerCase();
  462. synchronized (identities) {
  463. for (ConfigProvider identity : identities.safeGet(null)) {
  464. if (identity.getTarget().getType() == ConfigTarget.TYPE.CHANNEL
  465. && identity.getTarget().getData().equalsIgnoreCase(myTarget)) {
  466. return identity;
  467. }
  468. }
  469. }
  470. // We need to create one
  471. final ConfigTarget target = new ConfigTarget();
  472. target.setChannel(myTarget);
  473. return createConfig(target);
  474. }
  475. /** {@inheritDoc} */
  476. @Override
  477. public ConfigProvider createNetworkConfig(final String network) {
  478. if (network == null || network.isEmpty()) {
  479. throw new IllegalArgumentException("getNetworkConfig called "
  480. + "with null or empty network\n\nNetwork:" + network);
  481. }
  482. final String myTarget = network.toLowerCase();
  483. synchronized (identities) {
  484. for (ConfigProvider identity : identities.safeGet(null)) {
  485. if (identity.getTarget().getType() == ConfigTarget.TYPE.NETWORK
  486. && identity.getTarget().getData().equalsIgnoreCase(myTarget)) {
  487. return identity;
  488. }
  489. }
  490. }
  491. // We need to create one
  492. final ConfigTarget target = new ConfigTarget();
  493. target.setNetwork(myTarget);
  494. return createConfig(target);
  495. }
  496. /** {@inheritDoc} */
  497. @Override
  498. public ConfigProvider createServerConfig(final String server) {
  499. if (server == null || server.isEmpty()) {
  500. throw new IllegalArgumentException("getServerConfig called "
  501. + "with null or empty server\n\nServer: " + server);
  502. }
  503. final String myTarget = server.toLowerCase();
  504. synchronized (identities) {
  505. for (ConfigProvider identity : identities.safeGet(null)) {
  506. if (identity.getTarget().getType() == ConfigTarget.TYPE.SERVER
  507. && identity.getTarget().getData().equalsIgnoreCase(myTarget)) {
  508. return identity;
  509. }
  510. }
  511. }
  512. // We need to create one
  513. final ConfigTarget target = new ConfigTarget();
  514. target.setServer(myTarget);
  515. return createConfig(target);
  516. }
  517. /** {@inheritDoc} */
  518. @Override
  519. public ConfigProvider createCustomConfig(final String name, final String type) {
  520. final Map<String, Map<String, String>> settings = new HashMap<>();
  521. settings.put(IDENTITY_DOMAIN, new HashMap<String, String>(2));
  522. settings.get(IDENTITY_DOMAIN).put("name", name);
  523. settings.get(IDENTITY_DOMAIN).put("type", type);
  524. try {
  525. return createIdentity(settings);
  526. } catch (InvalidIdentityFileException | IOException ex) {
  527. Logger.appError(ErrorLevel.MEDIUM, "Unable to create identity", ex);
  528. return null;
  529. }
  530. }
  531. /** {@inheritDoc} */
  532. @Override
  533. public ConfigProvider createProfileConfig(final String name) {
  534. final Map<String, Map<String, String>> settings = new HashMap<>();
  535. settings.put(IDENTITY_DOMAIN, new HashMap<String, String>(1));
  536. settings.put(PROFILE_DOMAIN, new HashMap<String, String>(2));
  537. final String nick = System.getProperty("user.name").replace(' ', '_');
  538. settings.get(IDENTITY_DOMAIN).put("name", name);
  539. settings.get(PROFILE_DOMAIN).put("nicknames", nick);
  540. settings.get(PROFILE_DOMAIN).put("realname", nick);
  541. try {
  542. return createIdentity(settings);
  543. } catch (InvalidIdentityFileException | IOException ex) {
  544. Logger.appError(ErrorLevel.MEDIUM, "Unable to create identity", ex);
  545. return null;
  546. }
  547. }
  548. /** {@inheritDoc} */
  549. @Override
  550. public ConfigProvider createConfig(final ConfigTarget target) {
  551. final Map<String, Map<String, String>> settings = new HashMap<>();
  552. settings.put(IDENTITY_DOMAIN, new HashMap<String, String>(2));
  553. settings.get(IDENTITY_DOMAIN).put("name", target.getData());
  554. settings.get(IDENTITY_DOMAIN).put(target.getTypeName(), target.getData());
  555. try {
  556. return createIdentity(settings);
  557. } catch (InvalidIdentityFileException | IOException ex) {
  558. Logger.appError(ErrorLevel.MEDIUM, "Unable to create identity", ex);
  559. return null;
  560. }
  561. }
  562. /**
  563. * Creates a new identity containing the specified properties.
  564. *
  565. * @param settings The settings to populate the identity with
  566. * @return A new identity containing the specified properties
  567. * @throws IOException If the file cannot be created
  568. * @throws InvalidIdentityFileException If the settings are invalid
  569. * @since 0.6.3m1
  570. */
  571. protected ConfigFileBackedConfigProvider createIdentity(final Map<String, Map<String, String>> settings)
  572. throws IOException, InvalidIdentityFileException {
  573. if (!settings.containsKey(IDENTITY_DOMAIN) || !settings.get(IDENTITY_DOMAIN).containsKey("name")
  574. || settings.get(IDENTITY_DOMAIN).get("name").isEmpty()) {
  575. throw new InvalidIdentityFileException("identity.name is not set");
  576. }
  577. final String fs = System.getProperty("file.separator");
  578. final String location = getUserSettingsDirectory();
  579. final String name = settings.get(IDENTITY_DOMAIN).get("name").replaceAll(ILLEGAL_CHARS, "_");
  580. File file = new File(location + name);
  581. int attempt = 1;
  582. while (file.exists()) {
  583. file = new File(location + name + "-" + attempt);
  584. attempt++;
  585. }
  586. final ConfigFile configFile = new ConfigFile(file);
  587. for (Map.Entry<String, Map<String, String>> entry : settings.entrySet()) {
  588. configFile.addDomain(entry.getKey(), entry.getValue());
  589. }
  590. configFile.write();
  591. final ConfigFileBackedConfigProvider identity = new ConfigFileBackedConfigProvider(file, false);
  592. addConfigProvider(identity);
  593. return identity;
  594. }
  595. /**
  596. * Gets a singleton instance of the Identity Manager.
  597. *
  598. * @return A singleton instance of the IdentityManager.
  599. * @deprecated Shouldn't use global state.
  600. */
  601. @Deprecated
  602. public static IdentityManager getIdentityManager() {
  603. return instance;
  604. }
  605. /**
  606. * Sets the singleton instance of the Identity Manager.
  607. *
  608. * @param identityManager The identity manager to use.
  609. * @deprecated Shouldn't use global state.
  610. */
  611. @Deprecated
  612. public static void setIdentityManager(final IdentityManager identityManager) {
  613. instance = identityManager;
  614. }
  615. /** {@inheritDoc} */
  616. @Override
  617. public ConfigProviderMigrator createMigratableConfig(final String protocol,
  618. final String ircd, final String network, final String server) {
  619. final ConfigManager configManager = new ConfigManager(protocol, ircd, network, server);
  620. return new ConfigManagerMigrator(configManager);
  621. }
  622. /** {@inheritDoc} */
  623. @Override
  624. public ConfigProviderMigrator createMigratableConfig(final String protocol,
  625. final String ircd, final String network, final String server, final String channel) {
  626. final ConfigManager configManager = new ConfigManager(protocol, ircd, network, server, channel);
  627. return new ConfigManagerMigrator(configManager);
  628. }
  629. }