+package net.pterodactylus.irc.connection;
+
+import static java.lang.String.format;
+import static java.lang.String.valueOf;
+import static org.apache.log4j.Logger.getLogger;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import net.pterodactylus.irc.Connection;
+import net.pterodactylus.irc.Reply;
+
+import com.google.common.eventbus.EventBus;
+import org.apache.log4j.Logger;
+
+/**
+ * Parses the server’s messages about which prefixes it understands for
+ * channels and nicknames.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class PrefixHandler implements Handler {
+
+ private static final Logger logger =
+ getLogger(PrefixHandler.class);
+
+ private final Map<String, String> nickPrefixes = new HashMap<>();
+ private final Set<Character> channelTypes = new HashSet<>();
+
+ @Override
+ public boolean willHandle(Reply reply) {
+ return "005".equals(reply.command());
+ }
+
+ @Override
+ public void handleReply(Reply reply) {
+ List<String> parameters = reply.parameters();
+
+ for (String parameter : parameters) {
+ if (parameter.startsWith("PREFIX=")) {
+ parseNickPrefixes(parameter);
+ } else if (parameter.startsWith("CHANTYPES=")) {
+ parseChannelTypes(parameter);
+ }
+ }
+ }
+
+ public boolean isChannel(String receiver) {
+ return channelTypes.contains(receiver.charAt(0));
+ }
+
+ public boolean isNickPrefixed(String nick) {
+ return nickPrefixes.containsKey(nick.substring(0, 1));
+ }
+
+ private void parseNickPrefixes(String parameter) {
+ int openParen = parameter.indexOf('(');
+ int closeParen = parameter.indexOf(')');
+ if ((openParen != -1) && (closeParen != -1)) {
+ for (int modeCharacterIndex = 1;
+ modeCharacterIndex < (closeParen - openParen);
+ ++modeCharacterIndex) {
+ char modeCharacter = parameter.charAt(
+ openParen + modeCharacterIndex);
+ char modeSymbol = parameter.charAt(
+ closeParen + modeCharacterIndex);
+ nickPrefixes.put(valueOf(modeSymbol),
+ valueOf(modeCharacter));
+ }
+ logger.debug(format("Parsed Prefixes: %s", nickPrefixes));
+ }
+ }
+
+ private void parseChannelTypes(String parameter) {
+ for (char channelType : parameter.substring(10).toCharArray()) {
+ channelTypes.add(channelType);
+ }
+ logger.debug(format("Parsed Channel Types: %s", channelTypes));
+ }
+
+}