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.

CoreProfilesDialogModel.java 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  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.ui.core.profiles;
  23. import com.dmdirc.config.profiles.Profile;
  24. import com.dmdirc.config.profiles.ProfileManager;
  25. import com.dmdirc.interfaces.ui.ProfilesDialogModel;
  26. import com.dmdirc.interfaces.ui.ProfilesDialogModelListener;
  27. import com.dmdirc.util.collections.ListenerList;
  28. import com.dmdirc.util.validators.FileNameValidator;
  29. import com.dmdirc.util.validators.IdentValidator;
  30. import com.dmdirc.util.validators.ListNotEmptyValidator;
  31. import com.dmdirc.util.validators.NotEmptyValidator;
  32. import com.dmdirc.util.validators.PermissiveValidator;
  33. import com.dmdirc.util.validators.Validator;
  34. import com.dmdirc.util.validators.ValidatorChain;
  35. import com.google.common.collect.ImmutableList;
  36. import com.google.common.collect.Iterables;
  37. import com.google.common.collect.Lists;
  38. import java.util.Comparator;
  39. import java.util.List;
  40. import java.util.Optional;
  41. import java.util.SortedMap;
  42. import java.util.concurrent.ConcurrentSkipListMap;
  43. import javax.inject.Inject;
  44. import static com.google.common.base.Preconditions.checkArgument;
  45. import static com.google.common.base.Preconditions.checkNotNull;
  46. import static com.google.common.base.Preconditions.checkState;
  47. public class CoreProfilesDialogModel implements ProfilesDialogModel {
  48. private final ListenerList listeners;
  49. private final ProfileManager profileManager;
  50. private final SortedMap<String, MutableProfile> profiles;
  51. private Optional<MutableProfile> selectedProfile = Optional.empty();
  52. private Optional<String> selectedNickname = Optional.empty();
  53. private Optional<String> selectedHighlight = Optional.empty();
  54. @Inject
  55. public CoreProfilesDialogModel(final ProfileManager profileManager) {
  56. this.profileManager = profileManager;
  57. listeners = new ListenerList();
  58. profiles = new ConcurrentSkipListMap<>(Comparator.naturalOrder());
  59. }
  60. @Override
  61. public void loadModel() {
  62. profiles.clear();
  63. profileManager.getProfiles().stream().map(MutableProfile::new).forEach(mp -> {
  64. profiles.put(mp.getName(), mp);
  65. listeners.getCallable(ProfilesDialogModelListener.class).profileAdded(mp);
  66. });
  67. setSelectedProfile(Optional.ofNullable(Iterables.getFirst(profiles.values(), null)));
  68. }
  69. @Override
  70. public List<MutableProfile> getProfileList() {
  71. return ImmutableList.copyOf(profiles.values());
  72. }
  73. @Override
  74. public Optional<MutableProfile> getProfile(final String name) {
  75. checkNotNull(name, "Name cannot be null");
  76. return Optional.ofNullable(profiles.get(name));
  77. }
  78. @Override
  79. public void addProfile(final String name, final String realname, final String ident,
  80. final List<String> nicknames) {
  81. checkNotNull(name, "Name cannot be null");
  82. checkArgument(!name.isEmpty(), "Name cannot be empty");
  83. checkArgument(!profiles.containsKey(name), "Name cannot already exist");
  84. final MutableProfile profile =
  85. new MutableProfile(name, realname, Optional.ofNullable(ident), nicknames);
  86. profiles.put(name, profile);
  87. listeners.getCallable(ProfilesDialogModelListener.class).profileAdded(profile);
  88. setSelectedProfile(Optional.of(profile));
  89. }
  90. @Override
  91. public void addProfile(final String name) {
  92. addProfile(name, name, name, Lists.newArrayList(name));
  93. }
  94. @Override
  95. public void removeProfile(final String name) {
  96. checkNotNull(name, "Name cannot be null");
  97. checkArgument(profiles.containsKey(name), "profile must exist in list");
  98. removeProfile(profiles.get(name));
  99. }
  100. @Override
  101. public void removeProfile(final MutableProfile profile) {
  102. checkNotNull(profile, "Profile cannot be null");
  103. checkArgument(profiles.containsValue(profile), "profile must exist in list");
  104. profiles.remove(profile.getName());
  105. if (getSelectedProfile().isPresent() && getSelectedProfile().get().equals(profile)) {
  106. setSelectedProfile(Optional.ofNullable(Iterables.getFirst(profiles.values(), null)));
  107. setSelectedProfileIdent(Optional.empty());
  108. setSelectedProfileRealname(Optional.empty());
  109. setSelectedProfileSelectedHighlight(Optional.empty());
  110. setSelectedProfileName(Optional.empty());
  111. setSelectedProfileSelectedNickname(Optional.empty());
  112. setSelectedProfileHighlights(Optional.empty());
  113. setSelectedProfileNicknames(Optional.empty());
  114. }
  115. listeners.getCallable(ProfilesDialogModelListener.class).profileRemoved(profile);
  116. }
  117. @Override
  118. public void save() {
  119. final List<Profile> profileList = Lists.newArrayList(profileManager.getProfiles());
  120. profileList.forEach(profileManager::deleteProfile);
  121. profiles.values().forEach(p -> profileManager.addProfile(
  122. Profile.create(p.getName(), p.getRealname(), p.getIdent(),
  123. p.getNicknames(), p.getHighlights())));
  124. }
  125. @Override
  126. public void setSelectedProfile(final Optional<MutableProfile> profile) {
  127. checkNotNull(profile, "profile cannot be null");
  128. profile.ifPresent(mutableProfile -> checkArgument(profiles.containsValue(mutableProfile), "Profile must exist in list"));
  129. if (!selectedProfile.equals(profile)) {
  130. selectedProfile = profile;
  131. listeners.getCallable(ProfilesDialogModelListener.class).profileSelectionChanged(profile);
  132. }
  133. }
  134. @Override
  135. public Optional<MutableProfile> getSelectedProfile() {
  136. return selectedProfile;
  137. }
  138. @Override
  139. public Optional<String> getSelectedProfileName() {
  140. return selectedProfile.map(MutableProfile::getName);
  141. }
  142. @Override
  143. public void setSelectedProfileName(final Optional<String> name) {
  144. checkNotNull(name, "Name cannot be null");
  145. selectedProfile.ifPresent(p -> {
  146. p.setName(name.orElse(""));
  147. listeners.getCallable(ProfilesDialogModelListener.class).profileEdited(p);
  148. });
  149. }
  150. @Override
  151. public Optional<String> getSelectedProfileRealname() {
  152. return selectedProfile.map(MutableProfile::getRealname);
  153. }
  154. @Override
  155. public void setSelectedProfileRealname(final Optional<String> realname) {
  156. checkNotNull(realname, "Realname cannot be null");
  157. selectedProfile.ifPresent(p -> {
  158. p.setRealname(realname.orElse(""));
  159. listeners.getCallable(ProfilesDialogModelListener.class).profileEdited(p);
  160. });
  161. }
  162. @Override
  163. public Optional<String> getSelectedProfileIdent() {
  164. return selectedProfile.flatMap(MutableProfile::getIdent);
  165. }
  166. @Override
  167. public void setSelectedProfileIdent(final Optional<String> ident) {
  168. checkNotNull(ident, "Ident cannot be null");
  169. selectedProfile.ifPresent(p -> {
  170. p.setIdent(ident);
  171. listeners.getCallable(ProfilesDialogModelListener.class).profileEdited(p);
  172. });
  173. }
  174. @Override
  175. public Optional<List<String>> getSelectedProfileNicknames() {
  176. return selectedProfile.map(MutableProfile::getNicknames);
  177. }
  178. @Override
  179. public void setSelectedProfileNicknames(final Optional<List<String>> nicknames) {
  180. checkNotNull(nicknames, "nicknames cannot be null");
  181. selectedProfile.ifPresent(p -> {
  182. p.setNicknames(nicknames.orElse(Lists.newArrayList()));
  183. listeners.getCallable(ProfilesDialogModelListener.class).profileEdited(p);
  184. });
  185. }
  186. @Override
  187. public void setSelectedProfileHighlights(final Optional<List<String>> highlights) {
  188. checkNotNull(highlights, "highlights cannot be null");
  189. selectedProfile.ifPresent(p -> {
  190. p.setHighlights(highlights.orElse(Lists.newArrayList()));
  191. listeners.getCallable(ProfilesDialogModelListener.class).profileEdited(p);
  192. });
  193. }
  194. @Override
  195. public void addSelectedProfileNickname(final String nickname) {
  196. checkNotNull(nickname, "Nickname cannot be null");
  197. selectedProfile.ifPresent(p -> {
  198. checkArgument(!p.getNicknames().contains(nickname), "New nickname must not exist");
  199. p.addNickname(nickname);
  200. listeners.getCallable(ProfilesDialogModelListener.class)
  201. .selectedProfileNicknameAdded(nickname);
  202. });
  203. }
  204. @Override
  205. public void removeSelectedProfileNickname(final String nickname) {
  206. checkNotNull(nickname, "Nickname cannot be null");
  207. selectedProfile.ifPresent(p -> {
  208. checkArgument(p.getNicknames().contains(nickname), "Nickname must exist");
  209. p.removeNickname(nickname);
  210. listeners.getCallable(ProfilesDialogModelListener.class)
  211. .selectedProfileNicknameRemoved(nickname);
  212. });
  213. }
  214. @Override
  215. public void editSelectedProfileNickname(final String oldName, final String newName) {
  216. checkNotNull(oldName, "Nickname cannot be null");
  217. checkNotNull(newName, "Nickname cannot be null");
  218. selectedProfile.ifPresent(p -> {
  219. checkArgument(p.getNicknames().contains(oldName), "Old nickname must exist");
  220. checkArgument(!p.getNicknames().contains(newName), "New nickname must not exist");
  221. final int index = p.getNicknames().indexOf(oldName);
  222. p.setNickname(index, newName);
  223. selectedNickname = Optional.of(newName);
  224. listeners.getCallable(ProfilesDialogModelListener.class)
  225. .selectedProfileNicknameEdited(oldName, newName);
  226. });
  227. }
  228. @Override
  229. public Optional<String> getSelectedProfileSelectedNickname() {
  230. return selectedNickname;
  231. }
  232. @Override
  233. public Optional<String> getSelectedProfileSelectedHighlight() {
  234. return selectedHighlight;
  235. }
  236. @Override
  237. public void setSelectedProfileSelectedNickname(final Optional<String> selectedNickname) {
  238. checkNotNull(selectedNickname, "Nickname cannot be null");
  239. selectedProfile.ifPresent(p -> {
  240. selectedNickname.ifPresent(s -> checkArgument(p.getNicknames().contains(s),
  241. "Nickname must exist in nicknames list"));
  242. if (this.selectedNickname != selectedNickname) {
  243. this.selectedNickname = selectedNickname;
  244. listeners.getCallable(ProfilesDialogModelListener.class)
  245. .selectedNicknameChanged(selectedNickname);
  246. }
  247. });
  248. }
  249. @Override
  250. public void setSelectedProfileSelectedHighlight(final Optional<String> selectedHighlight) {
  251. checkNotNull(selectedHighlight, "Highlight cannot be null");
  252. selectedProfile.ifPresent(p -> {
  253. selectedHighlight.ifPresent(s -> checkArgument(p.getHighlights().contains(s),
  254. "Nickname must exist in nicknames list"));
  255. if (this.selectedHighlight != selectedHighlight) {
  256. this.selectedHighlight = selectedHighlight;
  257. listeners.getCallable(ProfilesDialogModelListener.class)
  258. .selectedHighlightChanged(selectedNickname);
  259. }
  260. });
  261. }
  262. @Override
  263. public void addListener(final ProfilesDialogModelListener listener) {
  264. checkNotNull(listener, "Listener must not be null");
  265. listeners.add(ProfilesDialogModelListener.class, listener);
  266. }
  267. @Override
  268. public void removeListener(final ProfilesDialogModelListener listener) {
  269. checkNotNull(listener, "Listener must not be null");
  270. listeners.remove(ProfilesDialogModelListener.class, listener);
  271. }
  272. @Override
  273. public boolean canSwitchProfiles() {
  274. return !selectedProfile.isPresent() ||
  275. isSelectedProfileIdentValid() && isSelectedProfileNameValid() &&
  276. isSelectedProfileNicknamesValid() && isSelectedProfileRealnameValid();
  277. }
  278. @Override
  279. public boolean isSaveAllowed() {
  280. return isProfileListValid() && isSelectedProfileIdentValid() &&
  281. isSelectedProfileNameValid() && isSelectedProfileNicknamesValid() &&
  282. isSelectedProfileRealnameValid();
  283. }
  284. @Override
  285. public boolean isSelectedProfileNicknamesValid() {
  286. return !getSelectedProfileNicknames().isPresent() || !getSelectedProfileNicknamesValidator()
  287. .validate(getSelectedProfileNicknames().get()).isFailure();
  288. }
  289. @Override
  290. public boolean isSelectedProfileHighlightsValid() {
  291. return !getSelectedProfileHighlights().isPresent() ||
  292. !getSelectedProfileHighlightsValidator().validate(
  293. getSelectedProfileHighlights().get()).isFailure();
  294. }
  295. @Override
  296. public boolean isSelectedProfileIdentValid() {
  297. return !getSelectedProfileIdent().isPresent() ||
  298. !getSelectedProfileIdentValidator().validate(getSelectedProfileIdent().get())
  299. .isFailure();
  300. }
  301. @Override
  302. public boolean isSelectedProfileRealnameValid() {
  303. return getSelectedProfileRealname().isPresent() ||
  304. !getSelectedProfileRealnameValidator().validate(getSelectedProfileRealname().get())
  305. .isFailure();
  306. }
  307. @Override
  308. public boolean isSelectedProfileNameValid() {
  309. return getSelectedProfileName().isPresent() &&
  310. !getSelectedProfileNameValidator().validate(getSelectedProfileName().get())
  311. .isFailure();
  312. }
  313. @Override
  314. public boolean isProfileListValid() {
  315. return !getProfileListValidator().validate(getProfileList()).isFailure();
  316. }
  317. @Override
  318. public Validator<List<MutableProfile>> getProfileListValidator() {
  319. return new ListNotEmptyValidator<>();
  320. }
  321. @Override
  322. public Validator<String> getSelectedProfileNameValidator() {
  323. return ValidatorChain.<String>builder()
  324. .addValidator(new EditSelectedProfileNameValidator(this))
  325. .addValidator(new FileNameValidator())
  326. .build();
  327. }
  328. @Override
  329. public Validator<String> getNewProfileNameValidator() {
  330. return ValidatorChain.<String>builder()
  331. .addValidator(new NewProfileNameValidator(this))
  332. .addValidator(new FileNameValidator())
  333. .build();
  334. }
  335. @Override
  336. public Validator<String> getSelectedProfileIdentValidator() {
  337. return new PermissiveValidator<>();
  338. }
  339. @Override
  340. public Validator<String> getSelectedProfileRealnameValidator() {
  341. return new NotEmptyValidator();
  342. }
  343. @Override
  344. public Validator<List<String>> getSelectedProfileNicknamesValidator() {
  345. return new ListNotEmptyValidator<>();
  346. }
  347. @Override
  348. public Optional<List<String>> getSelectedProfileHighlights() {
  349. return selectedProfile.map(MutableProfile::getHighlights);
  350. }
  351. @Override
  352. public Validator<List<String>> getSelectedProfileHighlightsValidator() {
  353. return new PermissiveValidator<>();
  354. }
  355. @Override
  356. public Validator<String> getSelectedProfileAddNicknameValidator() {
  357. return ValidatorChain.<String>builder()
  358. .addValidator(new NotEmptyValidator())
  359. .addValidator(new AddNicknameValidator(this))
  360. .build();
  361. }
  362. @Override
  363. public Validator<String> getSelectedProfileEditNicknameValidator() {
  364. return ValidatorChain.<String>builder()
  365. .addValidator(new NotEmptyValidator())
  366. .addValidator(new EditSelectedNicknameValidator(this))
  367. .build();
  368. }
  369. @Override
  370. public void addSelectedProfileHighlight(final String highlight) {
  371. checkNotNull(highlight, "highlight cannot be null");
  372. selectedProfile.ifPresent(p -> {
  373. if (!p.getHighlights().contains(highlight)) {
  374. p.addHighlight(highlight);
  375. listeners.getCallable(ProfilesDialogModelListener.class)
  376. .selectedProfileHighlightAdded(highlight);
  377. }
  378. });
  379. }
  380. @Override
  381. public void removeSelectedProfileHighlight(final String highlight) {
  382. checkNotNull(highlight, "highlight cannot be null");
  383. selectedProfile.ifPresent(p -> {
  384. if (p.getHighlights().contains(highlight)) {
  385. p.removeHighlight(highlight);
  386. listeners.getCallable(ProfilesDialogModelListener.class)
  387. .selectedProfileHighlightRemoved(highlight);
  388. }
  389. });
  390. }
  391. @Override
  392. public Validator<String> getSelectedProfileAddHighlightValidator() {
  393. return new NotEmptyValidator();
  394. }
  395. @Override
  396. public void editSelectedProfileHighlight(final String oldHighlight, final String newHighlight) {
  397. checkNotNull(oldHighlight, "Highlight cannot be null");
  398. checkNotNull(newHighlight, "Highlight cannot be null");
  399. checkState(selectedProfile.isPresent(), "There must be a profile selected");
  400. selectedProfile.ifPresent(p -> {
  401. checkArgument(p.getHighlights().contains(oldHighlight), "Old highlight must exist");
  402. checkArgument(!p.getHighlights().contains(newHighlight), "New highlight must not exist");
  403. final int index = p.getHighlights().indexOf(oldHighlight);
  404. p.setHighlight(index, newHighlight);
  405. selectedHighlight = Optional.of(newHighlight);
  406. listeners.getCallable(ProfilesDialogModelListener.class)
  407. .selectedProfileHighlightEdited(oldHighlight, newHighlight);
  408. });
  409. }
  410. @Override
  411. public Validator<String> getSelectedProfileEditHighlightValidator() {
  412. return new EditSelectedHighlightValidator(this);
  413. }
  414. @Override
  415. public Validator<List<String>> getNicknamesValidator() {
  416. return new ListNotEmptyValidator<>();
  417. }
  418. @Override
  419. public Validator<List<String>> getHighlightsValidator() {
  420. return new PermissiveValidator<>();
  421. }
  422. @Override
  423. public Validator<String> getRealnameValidator() {
  424. return new NotEmptyValidator();
  425. }
  426. @Override
  427. public Validator<String> getIdentValidator() {
  428. return new IdentValidator();
  429. }
  430. }