KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > commands > KeySequenceBindingNode


1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.ui.internal.commands;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Collection JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.HashSet JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.Set JavaDoc;
22 import java.util.SortedSet JavaDoc;
23 import java.util.TreeSet JavaDoc;
24
25 import org.eclipse.ui.internal.WorkbenchPlugin;
26 import org.eclipse.ui.internal.util.Util;
27 import org.eclipse.ui.keys.KeySequence;
28 import org.eclipse.ui.keys.KeyStroke;
29
30 final class KeySequenceBindingNode {
31
32     final static class Assignment implements Comparable JavaDoc {
33         boolean hasPluginCommandIdInFirstKeyConfiguration;
34         boolean hasPluginCommandIdInInheritedKeyConfiguration;
35
36         boolean hasPreferenceCommandIdInFirstKeyConfiguration;
37         boolean hasPreferenceCommandIdInInheritedKeyConfiguration;
38         String JavaDoc pluginCommandIdInFirstKeyConfiguration;
39         String JavaDoc pluginCommandIdInInheritedKeyConfiguration;
40         String JavaDoc preferenceCommandIdInFirstKeyConfiguration;
41         String JavaDoc preferenceCommandIdInInheritedKeyConfiguration;
42
43         public int compareTo(Object JavaDoc object) {
44             Assignment castedObject = (Assignment) object;
45             int compareTo =
46                 hasPreferenceCommandIdInFirstKeyConfiguration == false
47                     ? (castedObject.hasPreferenceCommandIdInFirstKeyConfiguration
48                         == true
49                         ? -1
50                         : 0)
51                     : 1;
52
53             if (compareTo == 0) {
54                 compareTo =
55                     hasPreferenceCommandIdInInheritedKeyConfiguration == false
56                         ? (castedObject
57                             .hasPreferenceCommandIdInInheritedKeyConfiguration
58                             == true
59                             ? -1
60                             : 0)
61                         : 1;
62
63                 if (compareTo == 0) {
64                     compareTo =
65                         hasPluginCommandIdInFirstKeyConfiguration == false
66                             ? (castedObject
67                                 .hasPluginCommandIdInFirstKeyConfiguration
68                                 == true
69                                 ? -1
70                                 : 0)
71                             : 1;
72
73                     if (compareTo == 0) {
74                         compareTo =
75                             hasPluginCommandIdInInheritedKeyConfiguration
76                                 == false
77                                 ? (castedObject
78                                     .hasPluginCommandIdInInheritedKeyConfiguration
79                                     == true
80                                     ? -1
81                                     : 0)
82                                 : 1;
83
84                         if (compareTo == 0) {
85                             compareTo =
86                                 Util.compare(
87                                     preferenceCommandIdInFirstKeyConfiguration,
88                                     castedObject
89                                         .preferenceCommandIdInFirstKeyConfiguration);
90
91                             if (compareTo == 0) {
92                                 compareTo =
93                                     Util.compare(
94                                         preferenceCommandIdInInheritedKeyConfiguration,
95                                         castedObject
96                                             .preferenceCommandIdInInheritedKeyConfiguration);
97
98                                 if (compareTo == 0) {
99                                     compareTo =
100                                         Util.compare(
101                                             pluginCommandIdInFirstKeyConfiguration,
102                                             castedObject
103                                                 .pluginCommandIdInFirstKeyConfiguration);
104
105                                     if (compareTo == 0)
106                                         compareTo =
107                                             Util.compare(
108                                                 pluginCommandIdInInheritedKeyConfiguration,
109                                                 castedObject
110                                                     .pluginCommandIdInInheritedKeyConfiguration);
111                                 }
112                             }
113                         }
114                     }
115                 }
116             }
117
118             return compareTo;
119         }
120
121         boolean contains(String JavaDoc commandId) {
122             return Util.equals(
123                 commandId,
124                 preferenceCommandIdInFirstKeyConfiguration)
125                 || Util.equals(
126                     commandId,
127                     preferenceCommandIdInInheritedKeyConfiguration)
128                 || Util.equals(commandId, pluginCommandIdInFirstKeyConfiguration)
129                 || Util.equals(
130                     commandId,
131                     pluginCommandIdInInheritedKeyConfiguration);
132         }
133
134         public boolean equals(Object JavaDoc object) {
135             if (!(object instanceof Assignment))
136                 return false;
137
138             Assignment castedObject = (Assignment) object;
139             boolean equals = true;
140             equals &= hasPreferenceCommandIdInFirstKeyConfiguration
141                 == castedObject.hasPreferenceCommandIdInFirstKeyConfiguration;
142             equals &= hasPreferenceCommandIdInInheritedKeyConfiguration
143                 == castedObject.hasPreferenceCommandIdInInheritedKeyConfiguration;
144             equals &= hasPluginCommandIdInFirstKeyConfiguration
145                 == castedObject.hasPluginCommandIdInFirstKeyConfiguration;
146             equals &= hasPluginCommandIdInInheritedKeyConfiguration
147                 == castedObject.hasPluginCommandIdInInheritedKeyConfiguration;
148             equals &= preferenceCommandIdInFirstKeyConfiguration
149                 == castedObject.preferenceCommandIdInFirstKeyConfiguration;
150             equals &= preferenceCommandIdInInheritedKeyConfiguration
151                 == castedObject.preferenceCommandIdInInheritedKeyConfiguration;
152             equals &= pluginCommandIdInFirstKeyConfiguration
153                 == castedObject.pluginCommandIdInFirstKeyConfiguration;
154             equals &= pluginCommandIdInInheritedKeyConfiguration
155                 == castedObject.pluginCommandIdInInheritedKeyConfiguration;
156             return equals;
157         }
158     }
159
160     static void add(
161         Map JavaDoc keyStrokeNodeByKeyStrokeMap,
162         KeySequence keySequence,
163         String JavaDoc contextId,
164         String JavaDoc keyConfigurationId,
165         int rank,
166         String JavaDoc platform,
167         String JavaDoc locale,
168         String JavaDoc commandId) {
169         List JavaDoc keyStrokes = keySequence.getKeyStrokes();
170         Map JavaDoc root = keyStrokeNodeByKeyStrokeMap;
171         KeySequenceBindingNode keySequenceBindingNode = null;
172
173         for (int i = 0; i < keyStrokes.size(); i++) {
174             KeyStroke keyStroke = (KeyStroke) keyStrokes.get(i);
175             keySequenceBindingNode =
176                 (KeySequenceBindingNode) root.get(keyStroke);
177
178             if (keySequenceBindingNode == null) {
179                 keySequenceBindingNode = new KeySequenceBindingNode();
180                 root.put(keyStroke, keySequenceBindingNode);
181             }
182
183             root = keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap;
184         }
185
186         if (keySequenceBindingNode != null)
187             keySequenceBindingNode.add(
188                 contextId,
189                 keyConfigurationId,
190                 rank,
191                 platform,
192                 locale,
193                 commandId);
194     }
195
196     static Map JavaDoc find(Map JavaDoc keyStrokeNodeByKeyStrokeMap, KeySequence keySequence) {
197         Iterator JavaDoc iterator = keySequence.getKeyStrokes().iterator();
198         KeySequenceBindingNode keySequenceBindingNode = null;
199
200         while (iterator.hasNext()) {
201             keySequenceBindingNode =
202                 (KeySequenceBindingNode) keyStrokeNodeByKeyStrokeMap.get(
203                     iterator.next());
204
205             if (keySequenceBindingNode == null)
206                 return null;
207
208             keyStrokeNodeByKeyStrokeMap =
209                 keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap;
210         }
211
212         return keyStrokeNodeByKeyStrokeMap;
213     }
214
215     static Map JavaDoc getAssignmentsByContextIdKeySequence(
216         Map JavaDoc keyStrokeNodeByKeyStrokeMap,
217         KeySequence prefix) {
218         Map JavaDoc assignmentsByContextIdByKeySequence = new HashMap JavaDoc();
219         Iterator JavaDoc iterator = keyStrokeNodeByKeyStrokeMap.entrySet().iterator();
220
221         while (iterator.hasNext()) {
222             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
223             KeyStroke keyStroke = (KeyStroke) entry.getKey();
224             KeySequenceBindingNode keySequenceBindingNode =
225                 (KeySequenceBindingNode) entry.getValue();
226             List JavaDoc keyStrokes = new ArrayList JavaDoc(prefix.getKeyStrokes());
227             keyStrokes.add(keyStroke);
228             KeySequence keySequence = KeySequence.getInstance(keyStrokes);
229             Map JavaDoc childAssignmentsByContextIdByKeySequence =
230                 getAssignmentsByContextIdKeySequence(
231                     keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap,
232                     keySequence);
233
234             if (childAssignmentsByContextIdByKeySequence.size() >= 1)
235                 assignmentsByContextIdByKeySequence.putAll(
236                     childAssignmentsByContextIdByKeySequence);
237
238             assignmentsByContextIdByKeySequence.put(
239                 keySequence,
240                 keySequenceBindingNode.assignmentsByContextId);
241         }
242
243         return assignmentsByContextIdByKeySequence;
244     }
245
246     static void getKeySequenceBindingDefinitions(
247         Map JavaDoc keyStrokeNodeByKeyStrokeMap,
248         KeySequence prefix,
249         int rank,
250         List JavaDoc keySequenceBindingDefinitions) {
251         Iterator JavaDoc iterator = keyStrokeNodeByKeyStrokeMap.entrySet().iterator();
252
253         while (iterator.hasNext()) {
254             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
255             KeyStroke keyStroke = (KeyStroke) entry.getKey();
256             KeySequenceBindingNode keySequenceBindingNode =
257                 (KeySequenceBindingNode) entry.getValue();
258             List JavaDoc keyStrokes = new ArrayList JavaDoc(prefix.getKeyStrokes());
259             keyStrokes.add(keyStroke);
260             KeySequence keySequence = KeySequence.getInstance(keyStrokes);
261             Map JavaDoc contextMap = keySequenceBindingNode.contextMap;
262             Iterator JavaDoc iterator2 = contextMap.entrySet().iterator();
263
264             while (iterator2.hasNext()) {
265                 Map.Entry JavaDoc entry2 = (Map.Entry JavaDoc) iterator2.next();
266                 String JavaDoc contextId = (String JavaDoc) entry2.getKey();
267                 Map JavaDoc keyConfigurationMap = (Map JavaDoc) entry2.getValue();
268                 Iterator JavaDoc iterator3 = keyConfigurationMap.entrySet().iterator();
269
270                 while (iterator3.hasNext()) {
271                     Map.Entry JavaDoc entry3 = (Map.Entry JavaDoc) iterator3.next();
272                     String JavaDoc keyConfigurationId = (String JavaDoc) entry3.getKey();
273                     Map JavaDoc rankMap = (Map JavaDoc) entry3.getValue();
274                     Map JavaDoc platformMap = (Map JavaDoc) rankMap.get(new Integer JavaDoc(rank));
275
276                     if (platformMap != null) {
277                         Iterator JavaDoc iterator4 = platformMap.entrySet().iterator();
278
279                         while (iterator4.hasNext()) {
280                             Map.Entry JavaDoc entry4 = (Map.Entry JavaDoc) iterator4.next();
281                             String JavaDoc platform = (String JavaDoc) entry4.getKey();
282                             Map JavaDoc localeMap = (Map JavaDoc) entry4.getValue();
283                             Iterator JavaDoc iterator5 =
284                                 localeMap.entrySet().iterator();
285
286                             while (iterator5.hasNext()) {
287                                 Map.Entry JavaDoc entry5 = (Map.Entry JavaDoc) iterator5.next();
288                                 String JavaDoc locale = (String JavaDoc) entry5.getKey();
289                                 Set JavaDoc commandIds = (Set JavaDoc) entry5.getValue();
290                                 Iterator JavaDoc iterator6 = commandIds.iterator();
291
292                                 while (iterator6.hasNext()) {
293                                     String JavaDoc commandId =
294                                         (String JavaDoc) iterator6.next();
295                                     keySequenceBindingDefinitions.add(
296                                         new KeySequenceBindingDefinition(
297                                             contextId,
298                                             commandId,
299                                             keyConfigurationId,
300                                             keySequence,
301                                             locale,
302                                             platform,
303                                             null));
304                                 }
305                             }
306                         }
307                     }
308                 }
309             }
310
311             getKeySequenceBindingDefinitions(
312                 keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap,
313                 keySequence,
314                 rank,
315                 keySequenceBindingDefinitions);
316         }
317     }
318
319     static Map JavaDoc getKeySequenceBindingsByCommandId(Map JavaDoc keySequenceMap) {
320         Map JavaDoc commandMap = new HashMap JavaDoc();
321         Iterator JavaDoc iterator = keySequenceMap.entrySet().iterator();
322
323         while (iterator.hasNext()) {
324             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
325             KeySequence keySequence = (KeySequence) entry.getKey();
326             Match match = (Match) entry.getValue();
327             String JavaDoc commandId = match.getCommandId();
328             int value = match.getValue();
329             SortedSet JavaDoc keySequenceBindings =
330                 (SortedSet JavaDoc) commandMap.get(commandId);
331
332             if (keySequenceBindings == null) {
333                 keySequenceBindings = new TreeSet JavaDoc();
334                 commandMap.put(commandId, keySequenceBindings);
335             }
336
337             keySequenceBindings.add(new KeySequenceBinding(keySequence, value));
338         }
339
340         return commandMap;
341     }
342
343     static Map JavaDoc getMatchesByKeySequence(
344         Map JavaDoc keyStrokeNodeByKeyStrokeMap,
345         KeySequence prefix) {
346         Map JavaDoc keySequenceMap = new HashMap JavaDoc();
347         Iterator JavaDoc iterator = keyStrokeNodeByKeyStrokeMap.entrySet().iterator();
348
349         while (iterator.hasNext()) {
350             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
351             KeyStroke keyStroke = (KeyStroke) entry.getKey();
352             KeySequenceBindingNode keySequenceBindingNode =
353                 (KeySequenceBindingNode) entry.getValue();
354             List JavaDoc keyStrokes = new ArrayList JavaDoc(prefix.getKeyStrokes());
355             keyStrokes.add(keyStroke);
356             KeySequence keySequence = KeySequence.getInstance(keyStrokes);
357             Map JavaDoc childMatchesByKeySequence =
358                 getMatchesByKeySequence(
359                     keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap,
360                     keySequence);
361
362             if (childMatchesByKeySequence.size() >= 1)
363                 keySequenceMap.putAll(childMatchesByKeySequence);
364             else if (
365                 keySequenceBindingNode.match != null
366                     && keySequenceBindingNode.match.getCommandId() != null)
367                 keySequenceMap.put(keySequence, keySequenceBindingNode.match);
368         }
369
370         return keySequenceMap;
371     }
372
373     static void remove(
374         Map JavaDoc keyStrokeNodeByKeyStrokeMap,
375         KeySequence keySequence,
376         String JavaDoc contextId,
377         String JavaDoc keyConfigurationId,
378         int rank,
379         String JavaDoc platform,
380         String JavaDoc locale) {
381         Iterator JavaDoc iterator = keySequence.getKeyStrokes().iterator();
382         KeySequenceBindingNode keySequenceBindingNode = null;
383
384         while (iterator.hasNext()) {
385             keySequenceBindingNode =
386                 (KeySequenceBindingNode) keyStrokeNodeByKeyStrokeMap.get(
387                     iterator.next());
388
389             if (keySequenceBindingNode == null)
390                 return;
391
392             keyStrokeNodeByKeyStrokeMap =
393                 keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap;
394         }
395
396         keySequenceBindingNode.remove(
397             contextId,
398             keyConfigurationId,
399             rank,
400             platform,
401             locale);
402     }
403
404     static void remove(
405         Map JavaDoc keyStrokeNodeByKeyStrokeMap,
406         KeySequence keySequence,
407         String JavaDoc contextId,
408         String JavaDoc keyConfigurationId,
409         int rank,
410         String JavaDoc platform,
411         String JavaDoc locale,
412         String JavaDoc commandId) {
413         Iterator JavaDoc iterator = keySequence.getKeyStrokes().iterator();
414         KeySequenceBindingNode keySequenceBindingNode = null;
415
416         while (iterator.hasNext()) {
417             keySequenceBindingNode =
418                 (KeySequenceBindingNode) keyStrokeNodeByKeyStrokeMap.get(
419                     iterator.next());
420
421             if (keySequenceBindingNode == null)
422                 return;
423
424             keyStrokeNodeByKeyStrokeMap =
425                 keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap;
426         }
427
428         keySequenceBindingNode.remove(
429             contextId,
430             keyConfigurationId,
431             rank,
432             platform,
433             locale,
434             commandId);
435     }
436
437     static void solve(
438         Map JavaDoc keyStrokeNodeByKeyStrokeMap,
439         String JavaDoc[] keyConfigurationIds,
440         String JavaDoc[] platforms,
441         String JavaDoc[] locales) {
442         for (Iterator JavaDoc iterator =
443             keyStrokeNodeByKeyStrokeMap.values().iterator();
444             iterator.hasNext();
445             ) {
446             KeySequenceBindingNode keySequenceBindingNode =
447                 (KeySequenceBindingNode) iterator.next();
448             keySequenceBindingNode.solveAssignmentsByContextId(
449                 keyConfigurationIds,
450                 platforms,
451                 locales);
452             solve(
453                 keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap,
454                 keyConfigurationIds,
455                 platforms,
456                 locales);
457         }
458     }
459
460     static void solve(
461         Map JavaDoc keyStrokeNodeByKeyStrokeMap,
462         Map JavaDoc contextIds,
463         String JavaDoc[] keyConfigurationIds,
464         String JavaDoc[] platforms,
465         String JavaDoc[] locales) {
466         for (Iterator JavaDoc iterator =
467             keyStrokeNodeByKeyStrokeMap.values().iterator();
468             iterator.hasNext();
469             ) {
470             KeySequenceBindingNode keySequenceBindingNode =
471                 (KeySequenceBindingNode) iterator.next();
472             keySequenceBindingNode.solveMatch(
473                 contextIds,
474                 keyConfigurationIds,
475                 platforms,
476                 locales);
477             solve(
478                 keySequenceBindingNode.childKeyStrokeNodeByKeyStrokeMap,
479                 contextIds,
480                 keyConfigurationIds,
481                 platforms,
482                 locales);
483         }
484     }
485     private Map JavaDoc contextMap = new HashMap JavaDoc();
486
487     private Map JavaDoc assignmentsByContextId = new HashMap JavaDoc();
488     private Map JavaDoc childKeyStrokeNodeByKeyStrokeMap = new HashMap JavaDoc();
489     private Match match = null;
490
491     private KeySequenceBindingNode() {
492     }
493
494     private void add(
495         String JavaDoc contextId,
496         String JavaDoc keyConfigurationId,
497         int rank,
498         String JavaDoc platform,
499         String JavaDoc locale,
500         String JavaDoc commandId) {
501         Map JavaDoc keyConfigurationMap = (Map JavaDoc) contextMap.get(contextId);
502
503         if (keyConfigurationMap == null) {
504             keyConfigurationMap = new HashMap JavaDoc();
505             contextMap.put(contextId, keyConfigurationMap);
506         }
507
508         Map JavaDoc rankMap = (Map JavaDoc) keyConfigurationMap.get(keyConfigurationId);
509
510         if (rankMap == null) {
511             rankMap = new HashMap JavaDoc();
512             keyConfigurationMap.put(keyConfigurationId, rankMap);
513         }
514
515         Map JavaDoc platformMap = (Map JavaDoc) rankMap.get(new Integer JavaDoc(rank));
516
517         if (platformMap == null) {
518             platformMap = new HashMap JavaDoc();
519             rankMap.put(new Integer JavaDoc(rank), platformMap);
520         }
521
522         Map JavaDoc localeMap = (Map JavaDoc) platformMap.get(platform);
523
524         if (localeMap == null) {
525             localeMap = new HashMap JavaDoc();
526             platformMap.put(platform, localeMap);
527         }
528
529         Set JavaDoc commandIds = (Set JavaDoc) localeMap.get(locale);
530
531         if (commandIds == null) {
532             commandIds = new HashSet JavaDoc();
533             localeMap.put(locale, commandIds);
534         }
535
536         commandIds.add(commandId);
537     }
538
539     private void remove(
540         String JavaDoc contextId,
541         String JavaDoc keyConfigurationId,
542         int rank,
543         String JavaDoc platform,
544         String JavaDoc locale) {
545         Map JavaDoc keyConfigurationMap = (Map JavaDoc) contextMap.get(contextId);
546
547         if (keyConfigurationMap != null) {
548             Map JavaDoc rankMap = (Map JavaDoc) keyConfigurationMap.get(keyConfigurationId);
549
550             if (rankMap != null) {
551                 Map JavaDoc platformMap = (Map JavaDoc) rankMap.get(new Integer JavaDoc(rank));
552
553                 if (platformMap != null) {
554                     Map JavaDoc localeMap = (Map JavaDoc) platformMap.get(platform);
555
556                     if (localeMap != null) {
557                         localeMap.remove(locale);
558
559                         if (localeMap.isEmpty()) {
560                             platformMap.remove(platform);
561
562                             if (platformMap.isEmpty()) {
563                                 rankMap.remove(new Integer JavaDoc(rank));
564
565                                 if (rankMap.isEmpty()) {
566                                     keyConfigurationMap.remove(
567                                         keyConfigurationId);
568
569                                     if (keyConfigurationMap.isEmpty())
570                                         contextMap.remove(contextId);
571                                 }
572                             }
573                         }
574                     }
575                 }
576             }
577         }
578     }
579
580     private void remove(
581         String JavaDoc contextId,
582         String JavaDoc keyConfigurationId,
583         int rank,
584         String JavaDoc platform,
585         String JavaDoc locale,
586         String JavaDoc commandId) {
587         Map JavaDoc keyConfigurationMap = (Map JavaDoc) contextMap.get(contextId);
588
589         if (keyConfigurationMap != null) {
590             Map JavaDoc rankMap = (Map JavaDoc) keyConfigurationMap.get(keyConfigurationId);
591
592             if (rankMap != null) {
593                 Map JavaDoc platformMap = (Map JavaDoc) rankMap.get(new Integer JavaDoc(rank));
594
595                 if (platformMap != null) {
596                     Map JavaDoc localeMap = (Map JavaDoc) platformMap.get(platform);
597
598                     if (localeMap != null) {
599                         Set JavaDoc commandIds = (Set JavaDoc) localeMap.get(locale);
600
601                         if (commandIds != null) {
602                             commandIds.remove(commandId);
603
604                             if (commandIds.isEmpty()) {
605                                 localeMap.remove(locale);
606
607                                 if (localeMap.isEmpty()) {
608                                     platformMap.remove(platform);
609
610                                     if (platformMap.isEmpty()) {
611                                         rankMap.remove(new Integer JavaDoc(rank));
612
613                                         if (rankMap.isEmpty()) {
614                                             keyConfigurationMap.remove(
615                                                 keyConfigurationId);
616
617                                             if (keyConfigurationMap.isEmpty())
618                                                 contextMap.remove(contextId);
619                                         }
620                                     }
621                                 }
622                             }
623                         }
624                     }
625                 }
626             }
627         }
628     }
629
630     private void solveAssignmentsByContextId(
631         String JavaDoc[] keyConfigurationIds,
632         String JavaDoc[] platforms,
633         String JavaDoc[] locales) {
634         assignmentsByContextId.clear();
635
636         for (Iterator JavaDoc iterator = contextMap.entrySet().iterator();
637             iterator.hasNext();
638             ) {
639             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
640             String JavaDoc contextId = (String JavaDoc) entry.getKey();
641             Map JavaDoc keyConfigurationMap = (Map JavaDoc) entry.getValue();
642             KeySequenceBindingNode.Assignment assignment = null;
643
644             if (keyConfigurationMap != null)
645                 for (int keyConfiguration = 0;
646                     keyConfiguration < keyConfigurationIds.length
647                         && keyConfiguration < 0xFF;
648                     keyConfiguration++) {
649                     Map JavaDoc rankMap =
650                         (Map JavaDoc) keyConfigurationMap.get(
651                             keyConfigurationIds[keyConfiguration]);
652
653                     if (rankMap != null)
654                         for (int rank = 0; rank <= 1; rank++) {
655                             Map JavaDoc platformMap =
656                                 (Map JavaDoc) rankMap.get(new Integer JavaDoc(rank));
657
658                             if (platformMap != null)
659                                 for (int platform = 0;
660                                     platform < platforms.length
661                                         && platform < 0xFF;
662                                     platform++) {
663                                     Map JavaDoc localeMap =
664                                         (Map JavaDoc) platformMap.get(
665                                             platforms[platform]);
666
667                                     if (localeMap != null)
668                                         for (int locale = 0;
669                                             locale < locales.length
670                                                 && locale < 0xFF;
671                                             locale++) {
672                                             Set JavaDoc commandIds =
673                                                 (Set JavaDoc) localeMap.get(
674                                                     locales[locale]);
675
676                                             if (commandIds != null) {
677                                                 String JavaDoc commandId =
678                                                     commandIds.size() == 1
679                                                         ? (String JavaDoc) commandIds
680                                                             .iterator()
681                                                             .next()
682                                                         : null;
683
684                                                 if (assignment == null)
685                                                     assignment =
686                                                         new Assignment();
687
688                                                 switch (rank) {
689                                                     case 0 :
690                                                         if (keyConfiguration
691                                                             == 0
692                                                             && !assignment
693                                                                 .hasPreferenceCommandIdInFirstKeyConfiguration) {
694                                                             assignment
695                                                                 .hasPreferenceCommandIdInFirstKeyConfiguration =
696                                                                 true;
697                                                             assignment
698                                                                 .preferenceCommandIdInFirstKeyConfiguration =
699                                                                 commandId;
700                                                         } else if (
701                                                             !assignment
702                                                                 .hasPreferenceCommandIdInInheritedKeyConfiguration) {
703                                                             assignment
704                                                                 .hasPreferenceCommandIdInInheritedKeyConfiguration =
705                                                                 true;
706                                                             assignment
707                                                                 .preferenceCommandIdInInheritedKeyConfiguration =
708                                                                 commandId;
709                                                         }
710
711                                                         break;
712
713                                                     case 1 :
714                                                         if (keyConfiguration
715                                                             == 0
716                                                             && !assignment
717                                                                 .hasPluginCommandIdInFirstKeyConfiguration) {
718                                                             assignment
719                                                                 .hasPluginCommandIdInFirstKeyConfiguration =
720                                                                 true;
721                                                             assignment
722                                                                 .pluginCommandIdInFirstKeyConfiguration =
723                                                                 commandId;
724                                                         } else if (
725                                                             !assignment
726                                                                 .hasPluginCommandIdInInheritedKeyConfiguration) {
727                                                             assignment
728                                                                 .hasPluginCommandIdInInheritedKeyConfiguration =
729                                                                 true;
730                                                             assignment
731                                                                 .pluginCommandIdInInheritedKeyConfiguration =
732                                                                 commandId;
733                                                         }
734
735                                                         break;
736                                                 }
737                                             }
738                                         }
739                                 }
740
741                         }
742
743                 }
744
745             if (assignment != null)
746                 assignmentsByContextId.put(contextId, assignment);
747         }
748     }
749
750     /**
751      * <p>
752      * Finds a single match for this key binding node, given the state passed in
753      * as parameters. The match will contain a single command identifier, and a
754      * match value (a rough approximation of how accurate the match may be --
755      * lower is better).
756      * </p>
757      * <p>
758      * The matching algorithm checks for a match in each context given -- in the
759      * order provided. Similar, it checks the key configuration, the rank (see
760      * below), the platform, and the locale -- in the order provided. If a
761      * single command identifier (note: this could be <code>null</code>--
762      * indicating a removed key binding) matches the given characteristics, then
763      * it is added to the list. For each context identifier, there can be at
764      * most one match. If there is no match,
765      * <em>or the match has a <code>null</code> command identifier</em>,
766      * then we will move on to consider the next context.
767      * </p>
768      * <p>
769      * The rank is a special value. It is either <code>0</code> or
770      * <code>1</code>. It is used for marking removed key bindings. The
771      * removed command identifier is moved to the first rank, and a
772      * <code>null</code> command identifier is placed in the zeroth rank. The
773      * ranking mechanism is controlled externally, but only the zeroth and first
774      * ranks are considered internally.
775      * </p>
776      * <p>
777      * When this method completes, <code>match</code> will contain the best
778      * possible match, if any. If no match can be found, then <code>match</code>
779      * will be <code>null</code>.
780      * </p>
781      * <p>
782      * TODO Doug's Note (May 29, 2004): This mechanism is insanely complex for
783      * what it is doing, and doesn't seem to cover all of the use cases. This
784      * would be a good candidate for refactoring in the future. Most of this
785      * code was written by Chris McLaren, but I've had to hack in some
786      * behavioural changes to accomodate bugs for 3.0. If you're looking for
787      * insight as to how it currently works, you might try talking to one of us.
788      * Most notably, the fall through mechanism for <code>null</code> command
789      * identifiers. My main concerns are: interactions between key
790      * configurations, and unbinding a key in a child context so as to bind it
791      * in a parent context.
792      * </p>
793      *
794      * @param contextTree
795      * The tree of contexts to consider. The tree is represented as a
796      * map of child context identifiers to parent context
797      * identifiers. This value must never be <code>null</code>,
798      * though it may contain <code>null</code> parents. It should
799      * never contain <code>null</code> children. It should only
800      * contain strings.
801      * @param keyConfigurationIds
802      * The key configuration identifiers in the order they should be
803      * considered. This value must never be <code>null</code>,
804      * though it may contain <code>null</code> values.
805      * <code>null</code> values typically indicate "any".
806      * @param platforms
807      * The platform identifiers in the order they should be
808      * considered. This value must never be <code>null</code>,
809      * though it may contain <code>null</code> values.
810      * <code>null</code> values typically indicate "any".
811      * @param locales
812      * The locale identifiers in the order they should be considered.
813      * This value must never be <code>null</code>, though it may
814      * contain <code>null</code> values. <code>null</code> values
815      * typically indicate "any".
816      */

817     private void solveMatch(Map JavaDoc contextTree,
818             String JavaDoc[] keyConfigurationIds, String JavaDoc[] platforms, String JavaDoc[] locales) {
819         // Clear out the current match.
820
match = null;
821         
822         // Get an array of context identifiers.
823
final String JavaDoc[] contextIds = (String JavaDoc[]) contextTree.keySet().toArray(
824                 new String JavaDoc[contextTree.size()]);
825
826         // Get the maximum indices to consider.
827
final int maxContext = (contextIds.length > 0xFF) ? 0xFF
828                 : contextIds.length;
829         int maxKeyConfiguration = (keyConfigurationIds.length > 0xFF) ? 0xFF
830                 : keyConfigurationIds.length;
831         final int maxPlatform = (platforms.length > 0xFF) ? 0xFF
832                 : platforms.length;
833         final int maxLocale = (locales.length > 0xFF) ? 0xFF : locales.length;
834
835         // Peel apart the nested map looking for matches.
836
final Collection JavaDoc contextIdsNotToConsider = new HashSet JavaDoc();
837         for (int context = 0; context < maxContext; context++) {
838             boolean matchFoundForThisContext = false;
839
840             /*
841              * Check to see if the context identifier has been nixed by a child
842              * context. That is, has a non-null match been found in a child
843              * context?
844              */

845             final String JavaDoc contextId = contextIds[context];
846             if (contextIdsNotToConsider.contains(contextId)) {
847                 continue;
848             }
849
850             final Map JavaDoc keyConfigurationMap = (Map JavaDoc) contextMap.get(contextId);
851             if (keyConfigurationMap != null)
852                     for (int keyConfiguration = 0; keyConfiguration < maxKeyConfiguration
853                             && !matchFoundForThisContext; keyConfiguration++) {
854                         final Map JavaDoc rankMap = (Map JavaDoc) keyConfigurationMap
855                                 .get(keyConfigurationIds[keyConfiguration]);
856
857                         if (rankMap != null) {
858                             for (int rank = 0; rank <= 1; rank++) {
859                                 final Map JavaDoc platformMap = (Map JavaDoc) rankMap
860                                         .get(new Integer JavaDoc(rank));
861
862                                 if (platformMap != null)
863                                         for (int platform = 0; platform < maxPlatform
864                                                 && !matchFoundForThisContext; platform++) {
865                                             final Map JavaDoc localeMap = (Map JavaDoc) platformMap
866                                                     .get(platforms[platform]);
867
868                                             if (localeMap != null)
869                                                     for (int locale = 0; locale < maxLocale
870                                                             && !matchFoundForThisContext; locale++) {
871                                                         final Set JavaDoc commandIds = (Set JavaDoc) localeMap
872                                                                 .get(locales[locale]);
873
874                                                         if (commandIds != null) {
875                                                             /*
876                                                              * Jump to the next
877                                                              * context.
878                                                              */

879                                                             matchFoundForThisContext = true;
880
881                                                             /*
882                                                              * Get the command
883                                                              * identifier.
884                                                              */

885                                                             final String JavaDoc commandId = commandIds
886                                                                     .size() == 1 ? (String JavaDoc) commandIds
887                                                                     .iterator()
888                                                                     .next()
889                                                                     : null;
890
891                                                             /*
892                                                              * Make sure we
893                                                              * don't consider
894                                                              * any higher key
895                                                              * configurations
896                                                              * again.
897                                                              */

898                                                             maxKeyConfiguration = keyConfiguration + 1;
899
900                                                             /*
901                                                              * Make sure we
902                                                              * don't consider
903                                                              * any parents of
904                                                              * this context, if
905                                                              * the command
906                                                              * identifier is not
907                                                              * null.
908                                                              */

909                                                             if (commandId != null) {
910                                                                 String JavaDoc parentContext = (String JavaDoc) contextTree
911                                                                         .get(contextId);
912                                                                 while (parentContext != null) {
913                                                                     contextIdsNotToConsider
914                                                                             .add(parentContext);
915                                                                     parentContext = (String JavaDoc) contextTree
916                                                                             .get(parentContext);
917                                                                 }
918
919                                                                 /*
920                                                                  * Check for a
921                                                                  * conflict.
922                                                                  */

923                                                                 if ((match != null)
924                                                                         && (!contextIdsNotToConsider
925                                                                                 .contains(contextIds[match
926                                                                                         .getValue() >> 24]))) {
927                                                                     WorkbenchPlugin
928                                                                             .log("Conflicting key binding for '" //$NON-NLS-1$
929
+ commandId
930                                                                                     + "' and '" //$NON-NLS-1$
931
+ match
932                                                                                             .getCommandId()
933                                                                                     + "'"); //$NON-NLS-1$
934
match = null;
935
936                                                                 } else {
937                                                                     match = new Match(
938                                                                             commandId,
939                                                                             (context << 24)
940                                                                                     + (keyConfiguration << 16)
941                                                                                     + (platform << 8)
942                                                                                     + locale);
943                                                                 }
944                                                             }
945                                                         }
946                                                     }
947                                         }
948                             }
949                         }
950                     }
951         }
952     }
953 }
954
Popular Tags