blob: 1f99c10dc1dc859394868487fee259864333a03f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 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 Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.commands;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.util.Util;
import org.eclipse.ui.keys.KeySequence;
import org.eclipse.ui.keys.KeyStroke;
final class KeySequenceBindingNode {
final static class Assignment implements Comparable {
boolean hasPluginCommandIdInFirstKeyConfiguration;
boolean hasPluginCommandIdInInheritedKeyConfiguration;
boolean hasPreferenceCommandIdInFirstKeyConfiguration;
boolean hasPreferenceCommandIdInInheritedKeyConfiguration;
String pluginCommandIdInFirstKeyConfiguration;
String pluginCommandIdInInheritedKeyConfiguration;
String preferenceCommandIdInFirstKeyConfiguration;
String preferenceCommandIdInInheritedKeyConfiguration;
public int compareTo(Object object) {
Assignment castedObject = (Assignment) object;
int compareTo =
hasPreferenceCommandIdInFirstKeyConfiguration == false
? (castedObject.hasPreferenceCommandIdInFirstKeyConfiguration
== true
? -1
: 0)
: 1;
if (compareTo == 0) {
compareTo =
hasPreferenceCommandIdInInheritedKeyConfiguration == false
? (castedObject
.hasPreferenceCommandIdInInheritedKeyConfiguration
== true
? -1
: 0)
: 1;
if (compareTo == 0) {
compareTo =
hasPluginCommandIdInFirstKeyConfiguration == false
? (castedObject
.hasPluginCommandIdInFirstKeyConfiguration
== true
? -1
: 0)
: 1;
if (compareTo == 0) {
compareTo =
hasPluginCommandIdInInheritedKeyConfiguration
== false
? (castedObject
.hasPluginCommandIdInInheritedKeyConfiguration
== true
? -1
: 0)
: 1;
if (compareTo == 0) {
compareTo =
Util.compare(
preferenceCommandIdInFirstKeyConfiguration,
castedObject
.preferenceCommandIdInFirstKeyConfiguration);
if (compareTo == 0) {
compareTo =
Util.compare(
preferenceCommandIdInInheritedKeyConfiguration,
castedObject
.preferenceCommandIdInInheritedKeyConfiguration);
if (compareTo == 0) {
compareTo =
Util.compare(
pluginCommandIdInFirstKeyConfiguration,
castedObject
.pluginCommandIdInFirstKeyConfiguration);
if (compareTo == 0)
compareTo =
Util.compare(
pluginCommandIdInInheritedKeyConfiguration,
castedObject
.pluginCommandIdInInheritedKeyConfiguration);
}
}
}
}
}
}
return compareTo;
}
boolean contains(String commandId) {
return Util.equals(
commandId,
preferenceCommandIdInFirstKeyConfiguration)
|| Util.equals(
commandId,
preferenceCommandIdInInheritedKeyConfiguration)
|| Util.equals(commandId, pluginCommandIdInFirstKeyConfiguration)
|| Util.equals(
commandId,
pluginCommandIdInInheritedKeyConfiguration);
}
public boolean equals(Object object) {
if (!(object instanceof Assignment))
return false;
Assignment castedObject = (Assignment) object;
boolean equals = true;
equals &= hasPreferenceCommandIdInFirstKeyConfiguration
== castedObject.hasPreferenceCommandIdInFirstKeyConfiguration;
equals &= hasPreferenceCommandIdInInheritedKeyConfiguration
== castedObject.hasPreferenceCommandIdInInheritedKeyConfiguration;
equals &= hasPluginCommandIdInFirstKeyConfiguration
== castedObject.hasPluginCommandIdInFirstKeyConfiguration;
equals &= hasPluginCommandIdInInheritedKeyConfiguration
== castedObject.hasPluginCommandIdInInheritedKeyConfiguration;
equals &= preferenceCommandIdInFirstKeyConfiguration
== castedObject.preferenceCommandIdInFirstKeyConfiguration;
equals &= preferenceCommandIdInInheritedKeyConfiguration
== castedObject.preferenceCommandIdInInheritedKeyConfiguration;
equals &= pluginCommandIdInFirstKeyConfiguration
== castedObject.pluginCommandIdInFirstKeyConfiguration;
equals &= pluginCommandIdInInheritedKeyConfiguration
== castedObject.pluginCommandIdInInheritedKeyConfiguration;
return equals;
}
}
static void add(
Map keyStrokeNodeByKeyStrokeMap,
KeySequence keySequence,
String contextId,
String keyConfigurationId,
int rank,
String platform,
String locale,
String commandId) {
List keyStrokes = keySequence.getKeyStrokes();
Map root = keyStrokeNodeByKeyStrokeMap;
KeySequenceBindingNode keySequenceBindingNode = null;
for (int i = 0; i < keyStrokes.size(); i++) {
KeyStroke keyStroke = (KeyStroke) keyStrokes.get(i);
keySequenceBindingNode =
(KeySequenceBindingNode) root.get(keyStroke);
if (keySequenceBindingNode == null) {
keySequenceBindingNode = new KeySequenceBindingNode();
root.put(keyStroke, keySequenceBindingNode);
}
root = keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap;
}
if (keySequenceBindingNode != null)
keySequenceBindingNode.add(
contextId,
keyConfigurationId,
rank,
platform,
locale,
commandId);
}
static Map find(Map keyStrokeNodeByKeyStrokeMap, KeySequence keySequence) {
Iterator iterator = keySequence.getKeyStrokes().iterator();
KeySequenceBindingNode keySequenceBindingNode = null;
while (iterator.hasNext()) {
keySequenceBindingNode =
(KeySequenceBindingNode) keyStrokeNodeByKeyStrokeMap.get(
iterator.next());
if (keySequenceBindingNode == null)
return null;
keyStrokeNodeByKeyStrokeMap =
keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap;
}
return keyStrokeNodeByKeyStrokeMap;
}
static Map getAssignmentsByContextIdKeySequence(
Map keyStrokeNodeByKeyStrokeMap,
KeySequence prefix) {
Map assignmentsByContextIdByKeySequence = new HashMap();
Iterator iterator = keyStrokeNodeByKeyStrokeMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
KeyStroke keyStroke = (KeyStroke) entry.getKey();
KeySequenceBindingNode keySequenceBindingNode =
(KeySequenceBindingNode) entry.getValue();
List keyStrokes = new ArrayList(prefix.getKeyStrokes());
keyStrokes.add(keyStroke);
KeySequence keySequence = KeySequence.getInstance(keyStrokes);
Map childAssignmentsByContextIdByKeySequence =
getAssignmentsByContextIdKeySequence(
keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap,
keySequence);
if (childAssignmentsByContextIdByKeySequence.size() >= 1)
assignmentsByContextIdByKeySequence.putAll(
childAssignmentsByContextIdByKeySequence);
assignmentsByContextIdByKeySequence.put(
keySequence,
keySequenceBindingNode.assignmentsByContextId);
}
return assignmentsByContextIdByKeySequence;
}
static void getKeySequenceBindingDefinitions(
Map keyStrokeNodeByKeyStrokeMap,
KeySequence prefix,
int rank,
List keySequenceBindingDefinitions) {
Iterator iterator = keyStrokeNodeByKeyStrokeMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
KeyStroke keyStroke = (KeyStroke) entry.getKey();
KeySequenceBindingNode keySequenceBindingNode =
(KeySequenceBindingNode) entry.getValue();
List keyStrokes = new ArrayList(prefix.getKeyStrokes());
keyStrokes.add(keyStroke);
KeySequence keySequence = KeySequence.getInstance(keyStrokes);
Map contextMap = keySequenceBindingNode.contextMap;
Iterator iterator2 = contextMap.entrySet().iterator();
while (iterator2.hasNext()) {
Map.Entry entry2 = (Map.Entry) iterator2.next();
String contextId = (String) entry2.getKey();
Map keyConfigurationMap = (Map) entry2.getValue();
Iterator iterator3 = keyConfigurationMap.entrySet().iterator();
while (iterator3.hasNext()) {
Map.Entry entry3 = (Map.Entry) iterator3.next();
String keyConfigurationId = (String) entry3.getKey();
Map rankMap = (Map) entry3.getValue();
Map platformMap = (Map) rankMap.get(new Integer(rank));
if (platformMap != null) {
Iterator iterator4 = platformMap.entrySet().iterator();
while (iterator4.hasNext()) {
Map.Entry entry4 = (Map.Entry) iterator4.next();
String platform = (String) entry4.getKey();
Map localeMap = (Map) entry4.getValue();
Iterator iterator5 =
localeMap.entrySet().iterator();
while (iterator5.hasNext()) {
Map.Entry entry5 = (Map.Entry) iterator5.next();
String locale = (String) entry5.getKey();
Set commandIds = (Set) entry5.getValue();
Iterator iterator6 = commandIds.iterator();
while (iterator6.hasNext()) {
String commandId =
(String) iterator6.next();
keySequenceBindingDefinitions.add(
new KeySequenceBindingDefinition(
contextId,
commandId,
keyConfigurationId,
keySequence,
locale,
platform,
null));
}
}
}
}
}
}
getKeySequenceBindingDefinitions(
keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap,
keySequence,
rank,
keySequenceBindingDefinitions);
}
}
static Map getKeySequenceBindingsByCommandId(Map keySequenceMap) {
Map commandMap = new HashMap();
Iterator iterator = keySequenceMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
KeySequence keySequence = (KeySequence) entry.getKey();
Match match = (Match) entry.getValue();
String commandId = match.getCommandId();
int value = match.getValue();
SortedSet keySequenceBindings =
(SortedSet) commandMap.get(commandId);
if (keySequenceBindings == null) {
keySequenceBindings = new TreeSet();
commandMap.put(commandId, keySequenceBindings);
}
keySequenceBindings.add(new KeySequenceBinding(keySequence, value));
}
return commandMap;
}
static Map getMatchesByKeySequence(
Map keyStrokeNodeByKeyStrokeMap,
KeySequence prefix) {
Map keySequenceMap = new HashMap();
Iterator iterator = keyStrokeNodeByKeyStrokeMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
KeyStroke keyStroke = (KeyStroke) entry.getKey();
KeySequenceBindingNode keySequenceBindingNode =
(KeySequenceBindingNode) entry.getValue();
List keyStrokes = new ArrayList(prefix.getKeyStrokes());
keyStrokes.add(keyStroke);
KeySequence keySequence = KeySequence.getInstance(keyStrokes);
Map childMatchesByKeySequence =
getMatchesByKeySequence(
keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap,
keySequence);
if (childMatchesByKeySequence.size() >= 1)
keySequenceMap.putAll(childMatchesByKeySequence);
else if (
keySequenceBindingNode.match != null
&& keySequenceBindingNode.match.getCommandId() != null)
keySequenceMap.put(keySequence, keySequenceBindingNode.match);
}
return keySequenceMap;
}
static void remove(
Map keyStrokeNodeByKeyStrokeMap,
KeySequence keySequence,
String contextId,
String keyConfigurationId,
int rank,
String platform,
String locale) {
Iterator iterator = keySequence.getKeyStrokes().iterator();
KeySequenceBindingNode keySequenceBindingNode = null;
while (iterator.hasNext()) {
keySequenceBindingNode =
(KeySequenceBindingNode) keyStrokeNodeByKeyStrokeMap.get(
iterator.next());
if (keySequenceBindingNode == null)
return;
keyStrokeNodeByKeyStrokeMap =
keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap;
}
keySequenceBindingNode.remove(
contextId,
keyConfigurationId,
rank,
platform,
locale);
}
static void remove(
Map keyStrokeNodeByKeyStrokeMap,
KeySequence keySequence,
String contextId,
String keyConfigurationId,
int rank,
String platform,
String locale,
String commandId) {
Iterator iterator = keySequence.getKeyStrokes().iterator();
KeySequenceBindingNode keySequenceBindingNode = null;
while (iterator.hasNext()) {
keySequenceBindingNode =
(KeySequenceBindingNode) keyStrokeNodeByKeyStrokeMap.get(
iterator.next());
if (keySequenceBindingNode == null)
return;
keyStrokeNodeByKeyStrokeMap =
keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap;
}
keySequenceBindingNode.remove(
contextId,
keyConfigurationId,
rank,
platform,
locale,
commandId);
}
static void solve(
Map keyStrokeNodeByKeyStrokeMap,
String[] keyConfigurationIds,
String[] platforms,
String[] locales) {
for (Iterator iterator =
keyStrokeNodeByKeyStrokeMap.values().iterator();
iterator.hasNext();
) {
KeySequenceBindingNode keySequenceBindingNode =
(KeySequenceBindingNode) iterator.next();
keySequenceBindingNode.solveAssignmentsByContextId(
keyConfigurationIds,
platforms,
locales);
solve(
keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap,
keyConfigurationIds,
platforms,
locales);
}
}
static void solve(
Map keyStrokeNodeByKeyStrokeMap,
Map contextIds,
String[] keyConfigurationIds,
String[] platforms,
String[] locales) {
for (Iterator iterator =
keyStrokeNodeByKeyStrokeMap.values().iterator();
iterator.hasNext();
) {
KeySequenceBindingNode keySequenceBindingNode =
(KeySequenceBindingNode) iterator.next();
keySequenceBindingNode.solveMatch(
contextIds,
keyConfigurationIds,
platforms,
locales);
solve(
keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap,
contextIds,
keyConfigurationIds,
platforms,
locales);
}
}
private Map contextMap = new HashMap();
private Map assignmentsByContextId = new HashMap();
private Map childKeyStrokeNodeByKeyStrokeMap = new HashMap();
private Match match = null;
private KeySequenceBindingNode() {
}
private void add(
String contextId,
String keyConfigurationId,
int rank,
String platform,
String locale,
String commandId) {
Map keyConfigurationMap = (Map) contextMap.get(contextId);
if (keyConfigurationMap == null) {
keyConfigurationMap = new HashMap();
contextMap.put(contextId, keyConfigurationMap);
}
Map rankMap = (Map) keyConfigurationMap.get(keyConfigurationId);
if (rankMap == null) {
rankMap = new HashMap();
keyConfigurationMap.put(keyConfigurationId, rankMap);
}
Map platformMap = (Map) rankMap.get(new Integer(rank));
if (platformMap == null) {
platformMap = new HashMap();
rankMap.put(new Integer(rank), platformMap);
}
Map localeMap = (Map) platformMap.get(platform);
if (localeMap == null) {
localeMap = new HashMap();
platformMap.put(platform, localeMap);
}
Set commandIds = (Set) localeMap.get(locale);
if (commandIds == null) {
commandIds = new HashSet();
localeMap.put(locale, commandIds);
}
commandIds.add(commandId);
}
private void remove(
String contextId,
String keyConfigurationId,
int rank,
String platform,
String locale) {
Map keyConfigurationMap = (Map) contextMap.get(contextId);
if (keyConfigurationMap != null) {
Map rankMap = (Map) keyConfigurationMap.get(keyConfigurationId);
if (rankMap != null) {
Map platformMap = (Map) rankMap.get(new Integer(rank));
if (platformMap != null) {
Map localeMap = (Map) platformMap.get(platform);
if (localeMap != null) {
localeMap.remove(locale);
if (localeMap.isEmpty()) {
platformMap.remove(platform);
if (platformMap.isEmpty()) {
rankMap.remove(new Integer(rank));
if (rankMap.isEmpty()) {
keyConfigurationMap.remove(
keyConfigurationId);
if (keyConfigurationMap.isEmpty())
contextMap.remove(contextId);
}
}
}
}
}
}
}
}
private void remove(
String contextId,
String keyConfigurationId,
int rank,
String platform,
String locale,
String commandId) {
Map keyConfigurationMap = (Map) contextMap.get(contextId);
if (keyConfigurationMap != null) {
Map rankMap = (Map) keyConfigurationMap.get(keyConfigurationId);
if (rankMap != null) {
Map platformMap = (Map) rankMap.get(new Integer(rank));
if (platformMap != null) {
Map localeMap = (Map) platformMap.get(platform);
if (localeMap != null) {
Set commandIds = (Set) localeMap.get(locale);
if (commandIds != null) {
commandIds.remove(commandId);
if (commandIds.isEmpty()) {
localeMap.remove(locale);
if (localeMap.isEmpty()) {
platformMap.remove(platform);
if (platformMap.isEmpty()) {
rankMap.remove(new Integer(rank));
if (rankMap.isEmpty()) {
keyConfigurationMap.remove(
keyConfigurationId);
if (keyConfigurationMap.isEmpty())
contextMap.remove(contextId);
}
}
}
}
}
}
}
}
}
}
private void solveAssignmentsByContextId(
String[] keyConfigurationIds,
String[] platforms,
String[] locales) {
assignmentsByContextId.clear();
for (Iterator iterator = contextMap.entrySet().iterator();
iterator.hasNext();
) {
Map.Entry entry = (Map.Entry) iterator.next();
String contextId = (String) entry.getKey();
Map keyConfigurationMap = (Map) entry.getValue();
KeySequenceBindingNode.Assignment assignment = null;
if (keyConfigurationMap != null)
for (int keyConfiguration = 0;
keyConfiguration < keyConfigurationIds.length
&& keyConfiguration < 0xFF;
keyConfiguration++) {
Map rankMap =
(Map) keyConfigurationMap.get(
keyConfigurationIds[keyConfiguration]);
if (rankMap != null)
for (int rank = 0; rank <= 1; rank++) {
Map platformMap =
(Map) rankMap.get(new Integer(rank));
if (platformMap != null)
for (int platform = 0;
platform < platforms.length
&& platform < 0xFF;
platform++) {
Map localeMap =
(Map) platformMap.get(
platforms[platform]);
if (localeMap != null)
for (int locale = 0;
locale < locales.length
&& locale < 0xFF;
locale++) {
Set commandIds =
(Set) localeMap.get(
locales[locale]);
if (commandIds != null) {
String commandId =
commandIds.size() == 1
? (String) commandIds
.iterator()
.next()
: null;
if (assignment == null)
assignment =
new Assignment();
switch (rank) {
case 0 :
if (keyConfiguration
== 0
&& !assignment
.hasPreferenceCommandIdInFirstKeyConfiguration) {
assignment
.hasPreferenceCommandIdInFirstKeyConfiguration =
true;
assignment
.preferenceCommandIdInFirstKeyConfiguration =
commandId;
} else if (
!assignment
.hasPreferenceCommandIdInInheritedKeyConfiguration) {
assignment
.hasPreferenceCommandIdInInheritedKeyConfiguration =
true;
assignment
.preferenceCommandIdInInheritedKeyConfiguration =
commandId;
}
break;
case 1 :
if (keyConfiguration
== 0
&& !assignment
.hasPluginCommandIdInFirstKeyConfiguration) {
assignment
.hasPluginCommandIdInFirstKeyConfiguration =
true;
assignment
.pluginCommandIdInFirstKeyConfiguration =
commandId;
} else if (
!assignment
.hasPluginCommandIdInInheritedKeyConfiguration) {
assignment
.hasPluginCommandIdInInheritedKeyConfiguration =
true;
assignment
.pluginCommandIdInInheritedKeyConfiguration =
commandId;
}
break;
}
}
}
}
}
}
if (assignment != null)
assignmentsByContextId.put(contextId, assignment);
}
}
/**
* <p>
* Finds a single match for this key binding node, given the state passed in
* as parameters. The match will contain a single command identifier, and a
* match value (a rough approximation of how accurate the match may be --
* lower is better).
* </p>
* <p>
* The matching algorithm checks for a match in each context given -- in the
* order provided. Similar, it checks the key configuration, the rank (see
* below), the platform, and the locale -- in the order provided. If a
* single command identifier (note: this could be <code>null</code>--
* indicating a removed key binding) matches the given characteristics, then
* it is added to the list. For each context identifier, there can be at
* most one match. If there is no match,
* <em>or the match has a <code>null</code> command identifier</em>,
* then we will move on to consider the next context.
* </p>
* <p>
* The rank is a special value. It is either <code>0</code> or
* <code>1</code>. It is used for marking removed key bindings. The
* removed command identifier is moved to the first rank, and a
* <code>null</code> command identifier is placed in the zeroth rank. The
* ranking mechanism is controlled externally, but only the zeroth and first
* ranks are considered internally.
* </p>
* <p>
* When this method completes, <code>match</code> will contain the best
* possible match, if any. If no match can be found, then <code>match</code>
* will be <code>null</code>.
* </p>
* <p>
* TODO Doug's Note (May 29, 2004): This mechanism is insanely complex for
* what it is doing, and doesn't seem to cover all of the use cases. This
* would be a good candidate for refactoring in the future. Most of this
* code was written by Chris McLaren, but I've had to hack in some
* behavioural changes to accomodate bugs for 3.0. If you're looking for
* insight as to how it currently works, you might try talking to one of us.
* Most notably, the fall through mechanism for <code>null</code> command
* identifiers. My main concerns are: interactions between key
* configurations, and unbinding a key in a child context so as to bind it
* in a parent context.
* </p>
*
* @param contextTree
* The tree of contexts to consider. The tree is represented as a
* map of child context identifiers to parent context
* identifiers. This value must never be <code>null</code>,
* though it may contain <code>null</code> parents. It should
* never contain <code>null</code> children. It should only
* contain strings.
* @param keyConfigurationIds
* The key configuration identifiers in the order they should be
* considered. This value must never be <code>null</code>,
* though it may contain <code>null</code> values.
* <code>null</code> values typically indicate "any".
* @param platforms
* The platform identifiers in the order they should be
* considered. This value must never be <code>null</code>,
* though it may contain <code>null</code> values.
* <code>null</code> values typically indicate "any".
* @param locales
* The locale identifiers in the order they should be considered.
* This value must never be <code>null</code>, though it may
* contain <code>null</code> values. <code>null</code> values
* typically indicate "any".
*/
private void solveMatch(Map contextTree,
String[] keyConfigurationIds, String[] platforms, String[] locales) {
// Clear out the current match.
match = null;
// Get an array of context identifiers.
final String[] contextIds = (String[]) contextTree.keySet().toArray(
new String[contextTree.size()]);
// Get the maximum indices to consider.
final int maxContext = (contextIds.length > 0xFF) ? 0xFF
: contextIds.length;
int maxKeyConfiguration = (keyConfigurationIds.length > 0xFF) ? 0xFF
: keyConfigurationIds.length;
final int maxPlatform = (platforms.length > 0xFF) ? 0xFF
: platforms.length;
final int maxLocale = (locales.length > 0xFF) ? 0xFF : locales.length;
// Peel apart the nested map looking for matches.
final Collection contextIdsNotToConsider = new HashSet();
for (int context = 0; context < maxContext; context++) {
boolean matchFoundForThisContext = false;
/*
* Check to see if the context identifier has been nixed by a child
* context. That is, has a non-null match been found in a child
* context?
*/
final String contextId = contextIds[context];
if (contextIdsNotToConsider.contains(contextId)) {
continue;
}
final Map keyConfigurationMap = (Map) contextMap.get(contextId);
if (keyConfigurationMap != null)
for (int keyConfiguration = 0; keyConfiguration < maxKeyConfiguration
&& !matchFoundForThisContext; keyConfiguration++) {
final Map rankMap = (Map) keyConfigurationMap
.get(keyConfigurationIds[keyConfiguration]);
if (rankMap != null) {
for (int rank = 0; rank <= 1; rank++) {
final Map platformMap = (Map) rankMap
.get(new Integer(rank));
if (platformMap != null)
for (int platform = 0; platform < maxPlatform
&& !matchFoundForThisContext; platform++) {
final Map localeMap = (Map) platformMap
.get(platforms[platform]);
if (localeMap != null)
for (int locale = 0; locale < maxLocale
&& !matchFoundForThisContext; locale++) {
final Set commandIds = (Set) localeMap
.get(locales[locale]);
if (commandIds != null) {
/*
* Jump to the next
* context.
*/
matchFoundForThisContext = true;
/*
* Get the command
* identifier.
*/
final String commandId = commandIds
.size() == 1 ? (String) commandIds
.iterator()
.next()
: null;
/*
* Make sure we
* don't consider
* any higher key
* configurations
* again.
*/
maxKeyConfiguration = keyConfiguration + 1;
/*
* Make sure we
* don't consider
* any parents of
* this context, if
* the command
* identifier is not
* null.
*/
if (commandId != null) {
String parentContext = (String) contextTree
.get(contextId);
while (parentContext != null) {
contextIdsNotToConsider
.add(parentContext);
parentContext = (String) contextTree
.get(parentContext);
}
/*
* Check for a
* conflict.
*/
if ((match != null)
&& (!contextIdsNotToConsider
.contains(contextIds[match
.getValue() >> 24]))) {
WorkbenchPlugin
.log("Conflicting key binding for '" //$NON-NLS-1$
+ commandId
+ "' and '" //$NON-NLS-1$
+ match
.getCommandId()
+ "'"); //$NON-NLS-1$
match = null;
} else {
match = new Match(
commandId,
(context << 24)
+ (keyConfiguration << 16)
+ (platform << 8)
+ locale);
}
}
}
}
}
}
}
}
}
}
}