package net.sourceforge.pain.plugin.command; import net.sourceforge.pain.util.*; import java.util.*; public class CommandRegistry { private final HashMap prefixMapping = new HashMap(1024); final HashMap exactMapping = new HashMap(1024); private final HashMap commandNamesByClassName = new HashMap(1024); CommandRegistry() { } public LinkedHashMap findCommandsByPrefix(String prefix) { prefix = prefix.toLowerCase(); PrefixEntry entry = (PrefixEntry) prefixMapping.get(prefix); if (entry == null) { return null; } return entry.commands; } public void registerCommand(TextCommand command) { final String name = command.name; if (exactMapping.containsKey(name)) { throw new IllegalArgumentException("command with this name already registered:" + name); } for (int i = 0; i < name.length(); i++) { String prefix = name.substring(0, i + 1); PrefixEntry entry = (PrefixEntry) prefixMapping.get(prefix); if (entry == null) { entry = new PrefixEntry(); prefixMapping.put(prefix, entry); } entry.commands.put(name, command); } exactMapping.put(name, command); addToClassNameMapping(command); } private void addToClassNameMapping(TextCommand command) { HashSet commandNames = (HashSet) commandNamesByClassName.get(command.commandClassName); if (commandNames == null) { commandNames = new HashSet(); commandNamesByClassName.put(command.commandClassName, commandNames); } commandNames.add(command.name); } public void unregisterCommand(String name) { name = name.toLowerCase(); TextCommand command = (TextCommand) exactMapping.remove(name); if (command == null) { return; } for (int i = name.length(); i > 0; i--) { String prefix = name.substring(0, i); PrefixEntry entry = (PrefixEntry) prefixMapping.get(prefix); if (entry == null) { return; } entry.commands.remove(name); if (entry.commands.isEmpty()) { prefixMapping.remove(prefix); } } removeFromClassNameMapping(command); } private void removeFromClassNameMapping(TextCommand command) { HashSet commandNames = (HashSet) commandNamesByClassName.get(command.commandClassName); if (commandNames == null) { Log.warn("BUG:removeFromClassNameMapping: commandsNames is null"); return; } commandNames.remove(command.name); if (commandNames.isEmpty()) { commandNamesByClassName.remove(command.commandClassName); } } public TextCommand findCommandByPrefix(String prefix) { LinkedHashMap commandsByPrefix = findCommandsByPrefix(prefix); if (commandsByPrefix == null || commandsByPrefix.isEmpty()) { return null; } return (TextCommand) commandsByPrefix.values().iterator().next(); } public Set getAllCommandsForClassName(String className) { return (Set) commandNamesByClassName.get(className); } private static class PrefixEntry { LinkedHashMap commands = new LinkedHashMap(); } }