blob: 1cba2ea8958454525aae3c012e209f38747e56f9 [file] [log] [blame]
/************************************************************************
Copyright (c) 2002 IBM Corporation and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Common Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v10.html
Contributors:
IBM - Initial implementation
************************************************************************/
package org.eclipse.ui.internal.commands.keys;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
final class Node {
static void add(SortedMap tree, Binding binding, State state) {
List keyStrokes = binding.getKeySequence().getKeyStrokes();
SortedMap root = tree;
Node node = null;
for (int i = 0; i < keyStrokes.size(); i++) {
KeyStroke keyStroke = (KeyStroke) keyStrokes.get(i);
node = (Node) root.get(keyStroke);
if (node == null) {
node = new Node();
root.put(keyStroke, node);
}
root = node.childMap;
}
if (node != null)
node.add(binding, state);
}
static SortedMap find(SortedMap tree, KeySequence prefix) {
Iterator iterator = prefix.getKeyStrokes().iterator();
while (iterator.hasNext()) {
Node node = (Node) tree.get(iterator.next());
if (node == null)
return null;
tree = node.childMap;
}
return tree;
}
static void remove(SortedMap tree, Binding binding, State state) {
List keyStrokes = binding.getKeySequence().getKeyStrokes();
SortedMap root = tree;
Node node = null;
for (int i = 0; i < keyStrokes.size(); i++) {
KeyStroke keyStroke = (KeyStroke) keyStrokes.get(i);
node = (Node) root.get(keyStroke);
if (node == null)
break;
root = node.childMap;
}
if (node != null)
node.remove(binding, state);
}
static void solve(SortedMap tree, State[] stack) {
Iterator iterator = tree.values().iterator();
while (iterator.hasNext()) {
Node node = (Node) iterator.next();
node.match = solveStateMap(node.stateMap, stack);
solve(node.childMap, stack);
node.bestChildMatch = null;
Iterator iterator2 = node.childMap.values().iterator();
while (iterator2.hasNext()) {
Node child = (Node) iterator2.next();
Match childMatch = child.match;
if (childMatch != null && (node.bestChildMatch == null || childMatch.getValue() < node.bestChildMatch.getValue()))
node.bestChildMatch = childMatch;
}
}
}
static Binding solveActionMap(Map actionMap) {
Set bindingSet = (Set) actionMap.get(null);
if (bindingSet == null) {
bindingSet = new TreeSet();
Iterator iterator = actionMap.values().iterator();
while (iterator.hasNext())
bindingSet.addAll((Set) iterator.next());
}
return bindingSet.size() == 1 ? (Binding) bindingSet.iterator().next() : null;
}
static Binding solvePluginMap(Map pluginMap) {
Map actionMap = (Map) pluginMap.get(null);
if (actionMap != null)
return solveActionMap(actionMap);
else {
Set bindingSet = new TreeSet();
Iterator iterator = pluginMap.values().iterator();
while (iterator.hasNext())
bindingSet.add(solveActionMap((Map) iterator.next()));
return bindingSet.size() == 1 ? (Binding) bindingSet.iterator().next() : null;
}
}
static Match solveStateMap(SortedMap stateMap, State state) {
Match match = null;
Iterator iterator = stateMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
State testState = (State) entry.getKey();
Map testPluginMap = (Map) entry.getValue();
if (testPluginMap != null) {
Binding testBinding = solvePluginMap(testPluginMap);
if (testBinding != null) {
int testMatch = testState.match(state);
if (testMatch >= 0) {
if (testMatch == 0)
return Match.create(testBinding, 0);
else if (match == null || testMatch < match.getValue())
match = Match.create(testBinding, testMatch);
}
}
}
}
return match;
}
static Match solveStateMap(SortedMap stateMap, State[] stack) {
for (int i = 0; i < stack.length; i++) {
Match match = solveStateMap(stateMap, stack[i]);
if (match != null)
return match;
}
return null;
}
static Map toActionMap(Set matches) {
Map actionMap = new HashMap();
Iterator iterator = matches.iterator();
while (iterator.hasNext()) {
Match match = (Match) iterator.next();
String action = match.getBinding().getAction();
Set matchSet = (Set) actionMap.get(action);
if (matchSet == null) {
matchSet = new TreeSet();
actionMap.put(action, matchSet);
}
matchSet.add(match);
}
return actionMap;
}
static void toBindingSet(SortedMap tree, Set bindingSet) {
Iterator iterator = tree.values().iterator();
while (iterator.hasNext())
toBindingSet((Node) iterator.next(), bindingSet);
}
static void toBindingSet(Node node, Set bindingSet) {
toBindingSet(node.childMap, bindingSet);
Iterator iterator = node.stateMap.values().iterator();
while (iterator.hasNext()) {
Map pluginMap = (Map) iterator.next();
Iterator iterator2 = pluginMap.values().iterator();
while (iterator2.hasNext()) {
Map actionMap = (Map) iterator2.next();
Iterator iterator3 = actionMap.values().iterator();
while (iterator3.hasNext())
bindingSet.addAll((Set) iterator3.next());
}
}
}
static void toMatchSet(SortedMap tree, SortedSet matchSet) {
Iterator iterator = tree.values().iterator();
while (iterator.hasNext())
toMatchSet((Node) iterator.next(), matchSet);
}
static void toMatchSet(Node node, SortedSet matchSet) {
if (node.bestChildMatch != null && (node.match == null || node.bestChildMatch.getValue() < node.match.getValue()))
toMatchSet(node.childMap, matchSet);
else if (node.match != null)
matchSet.add(node.match);
}
static Map toKeySequenceMap(Set matches) {
Map keySequenceMap = new TreeMap();
Iterator iterator = matches.iterator();
while (iterator.hasNext()) {
Match match = (Match) iterator.next();
KeySequence keySequence = match.getBinding().getKeySequence();
Set matchSet = (Set) keySequenceMap.get(keySequence);
if (matchSet == null) {
matchSet = new TreeSet();
keySequenceMap.put(keySequence, matchSet);
}
matchSet.add(match);
}
return keySequenceMap;
}
Match bestChildMatch = null;
SortedMap childMap = new TreeMap();
Match match = null;
SortedMap stateMap = new TreeMap();
private Node() {
super();
}
void add(Binding binding, State state) {
Map pluginMap = (Map) stateMap.get(state);
if (pluginMap == null) {
pluginMap = new HashMap();
stateMap.put(state, pluginMap);
}
String plugin = binding.getPlugin();
Map actionMap = (Map) pluginMap.get(plugin);
if (actionMap == null) {
actionMap = new HashMap();
pluginMap.put(plugin, actionMap);
}
String action = binding.getAction();
Set bindingSet = (Set) actionMap.get(action);
if (bindingSet == null) {
bindingSet = new TreeSet();
actionMap.put(action, bindingSet);
}
bindingSet.add(binding);
}
void remove(Binding binding, State state) {
Map pluginMap = (Map) stateMap.get(state);
if (pluginMap != null) {
String plugin = binding.getPlugin();
Map actionMap = (Map) pluginMap.get(plugin);
if (actionMap != null) {
String action = binding.getAction();
Set bindingSet = (Set) actionMap.get(action);
if (bindingSet != null) {
bindingSet.remove(binding);
if (bindingSet.isEmpty()) {
actionMap.remove(action);
if (actionMap.isEmpty()) {
pluginMap.remove(plugin);
if (pluginMap.isEmpty())
stateMap.remove(state);
}
}
}
}
}
}
}