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.

AutoCommandManager.java 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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.commandparser.auto;
  18. import com.dmdirc.events.eventbus.EventBus;
  19. import java.util.Collections;
  20. import java.util.Map;
  21. import java.util.Optional;
  22. import java.util.Set;
  23. import java.util.concurrent.ConcurrentHashMap;
  24. import javax.inject.Inject;
  25. import javax.inject.Singleton;
  26. import static com.google.common.base.Preconditions.checkNotNull;
  27. /**
  28. * Manages {@link AutoCommand}s.
  29. */
  30. @Singleton
  31. public class AutoCommandManager {
  32. /** The bus to listen for events on. */
  33. private final EventBus eventBus;
  34. /** The factory to use to create handlers. */
  35. private final AutoCommandHandlerFactory factory;
  36. /** Known auto commands, mapped on to their handlers. */
  37. private final Map<AutoCommand, AutoCommandHandler> autoCommands = new ConcurrentHashMap<>();
  38. /** Whether the manager has been started or not. */
  39. private boolean started;
  40. /**
  41. * Creates a new instance of {@link AutoCommandManager}.
  42. *
  43. * @param eventBus The bus to listen to events on.
  44. * @param factory The factory to use to create handlers.
  45. */
  46. @Inject
  47. public AutoCommandManager(
  48. final EventBus eventBus,
  49. final AutoCommandHandlerFactory factory) {
  50. this.eventBus = eventBus;
  51. this.factory = factory;
  52. }
  53. /**
  54. * Starts handling events and triggering auto commands.
  55. */
  56. public void start() {
  57. started = true;
  58. autoCommands.values().forEach(eventBus::subscribe);
  59. }
  60. /**
  61. * Stops handling events and triggering auto commands.
  62. */
  63. public void stop() {
  64. started = false;
  65. autoCommands.values().forEach(eventBus::unsubscribe);
  66. }
  67. /**
  68. * Adds an auto command to this manager.
  69. *
  70. * <p>Only one auto command may exist for each combination of network, server and profile
  71. * targets. This method will throw an {@link IllegalStateException} if the given command is
  72. * a duplicate.
  73. *
  74. * @param autoCommand The command to be added.
  75. * @throws IllegalStateException If a command with the same target already exists.
  76. */
  77. public void addAutoCommand(final AutoCommand autoCommand) {
  78. checkNotNull(autoCommand);
  79. if (getAutoCommand(autoCommand.getNetwork(), autoCommand.getServer(),
  80. autoCommand.getProfile()).isPresent()) {
  81. throw new IllegalStateException("Only one AutoCommand may exist per " +
  82. "network/server/profile");
  83. }
  84. final AutoCommandHandler handler = factory.getAutoCommandHandler(autoCommand);
  85. if (started) {
  86. eventBus.subscribe(handler);
  87. }
  88. autoCommands.put(autoCommand, handler);
  89. }
  90. /**
  91. * Removes an existing auto command from this manager.
  92. *
  93. * @param autoCommand The command to be removed.
  94. */
  95. public void removeAutoCommand(final AutoCommand autoCommand) {
  96. checkNotNull(autoCommand);
  97. final AutoCommandHandler handler = autoCommands.remove(autoCommand);
  98. if (started) {
  99. eventBus.unsubscribe(handler);
  100. }
  101. }
  102. /**
  103. * 'Replaces' one AutoCommand with another, by removing the original and adding the replacement.
  104. *
  105. * @param original The original command to be replaced.
  106. * @param replacement The new command to be added.
  107. */
  108. public void replaceAutoCommand(final AutoCommand original, final AutoCommand replacement) {
  109. removeAutoCommand(original);
  110. addAutoCommand(replacement);
  111. }
  112. /**
  113. * Gets a set of all registered auto commands.
  114. *
  115. * @return The set of all known auto commands.
  116. */
  117. public Set<AutoCommand> getAutoCommands() {
  118. return Collections.unmodifiableSet(autoCommands.keySet());
  119. }
  120. /**
  121. * Returns the single global auto command, if it exists.
  122. *
  123. * @return The global auto-command, if it exists.
  124. */
  125. public Optional<AutoCommand> getGlobalAutoCommand() {
  126. return getAutoCommand(Optional.empty(), Optional.empty(), Optional.empty());
  127. }
  128. /**
  129. * Returns a single auto command matching the given parameters, if one exists.
  130. *
  131. * @param network The network to match
  132. * @param server The server to match
  133. * @param profile The profile to match
  134. * @return The matched auto command, if it exists.
  135. */
  136. public Optional<AutoCommand> getAutoCommand(final Optional<String> network,
  137. final Optional<String> server, final Optional<String> profile) {
  138. return getAutoCommands()
  139. .parallelStream()
  140. .filter(c -> c.getNetwork().equals(network))
  141. .filter(c -> c.getServer().equals(server))
  142. .filter(c -> c.getProfile().equals(profile))
  143. .findAny();
  144. }
  145. /**
  146. * Returns a single auto command matching the given parameters, or creates a new one if it
  147. * doesn't exist.
  148. *
  149. * @param network The network to match
  150. * @param server The server to match
  151. * @param profile The profile to match
  152. * @return The matched auto command, or a new auto command with the given targets.
  153. */
  154. public AutoCommand getOrCreateAutoCommand(final Optional<String> network,
  155. final Optional<String> server, final Optional<String> profile) {
  156. return getAutoCommand(network, server, profile).orElse(
  157. AutoCommand.create(server, network, profile, ""));
  158. }
  159. }