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();
}
}