comparison org.eclipse.jface/src/org/eclipse/jface/bindings/CachedBindingSet.d @ 12:bc29606a740c

Added dwt-addons in original directory structure of eclipse.org
author Frank Benoit <benoit@tionex.de>
date Sat, 14 Mar 2009 18:23:29 +0100
parents
children
comparison
equal deleted inserted replaced
11:43904fec5dca 12:bc29606a740c
1 /*******************************************************************************
2 * Copyright (c) 2004, 2007 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module org.eclipse.jface.bindings.CachedBindingSet;
14
15 import org.eclipse.jface.bindings.TriggerSequence;
16 import org.eclipse.jface.bindings.Binding;
17
18
19 import org.eclipse.jface.util.Util;
20
21 import java.lang.all;
22 import java.util.Collection;
23 import java.util.Map;
24 import java.util.Set;
25
26 /**
27 * <p>
28 * A resolution of bindings for a given state. To see if we already have a
29 * cached binding set, just create one of these binding sets and then look it up
30 * in a map. If it is not already there, then add it and set the cached binding
31 * resolution.
32 * </p>
33 *
34 * @since 3.1
35 */
36 final class CachedBindingSet {
37
38 /**
39 * A factor for computing the hash code for all cached binding sets.
40 */
41 private const static int HASH_FACTOR = 89;
42
43 /**
44 * <p>
45 * A representation of the tree of active contexts at the time this cached
46 * binding set was computed. It is a map of context id (<code>String</code>)
47 * to context id (<code>String</code>). Each key represents one of the
48 * active contexts or one of its ancestors, while each value represents its
49 * parent. This is a way of perserving information about what the hierarchy
50 * looked like.
51 * </p>
52 * <p>
53 * This value will be <code>null</code> if the contexts were disregarded
54 * in the computation. It may also be empty. All of the keys are guaranteed
55 * to be non- <code>null</code>, but the values can be <code>null</code>
56 * (i.e., no parent).
57 * </p>
58 */
59 private const Map activeContextTree;
60
61 /**
62 * The map representing the resolved state of the bindings. This is a map of
63 * a trigger (<code>TriggerSequence</code>) to binding (<code>Binding</code>).
64 * This value may be <code>null</code> if it has not yet been initialized.
65 */
66 private Map bindingsByTrigger = null;
67
68 /**
69 * A map of triggers to collections of bindings. If this binding set
70 * contains conflicts, they are logged here.
71 *
72 * @since 3.3
73 */
74 private Map conflictsByTrigger = null;
75
76 /**
77 * The hash code for this object. This value is computed lazily, and marked
78 * as invalid when one of the values on which it is based changes.
79 */
80 private /+transient+/ int hashCode;
81
82 /**
83 * Whether <code>hashCode</code> still contains a valid value.
84 */
85 private /+transient+/ bool hashCodeComputed = false;
86
87 /**
88 * <p>
89 * The list of locales that were active at the time this binding set was
90 * computed. This list starts with the most specific representation of the
91 * locale, and moves to more general representations. For example, this
92 * array might look like ["en_US", "en", "", null].
93 * </p>
94 * <p>
95 * This value will never be <code>null</code>, and it will never be
96 * empty. It must contain at least one element, but its elements can be
97 * <code>null</code>.
98 * </p>
99 */
100 private const String[] locales;
101
102 /**
103 * <p>
104 * The list of platforms that were active at the time this binding set was
105 * computed. This list starts with the most specific representation of the
106 * platform, and moves to more general representations. For example, this
107 * array might look like ["gtk", "", null].
108 * </p>
109 * <p>
110 * This value will never be <code>null</code>, and it will never be
111 * empty. It must contain at least one element, but its elements can be
112 * <code>null</code>.
113 * </p>
114 */
115 private const String[] platforms;
116
117 /**
118 * A map of prefixes (<code>TriggerSequence</code>) to a map of
119 * available completions (possibly <code>null</code>, which means there
120 * is an exact match). The available completions is a map of trigger (<code>TriggerSequence</code>)
121 * to command identifier (<code>String</code>). This value is
122 * <code>null</code> if it has not yet been initialized.
123 */
124 private Map prefixTable = null;
125
126 /**
127 * <p>
128 * The list of schemes that were active at the time this binding set was
129 * computed. This list starts with the active scheme, and then continues
130 * with all of its ancestors -- in order. For example, this might look like
131 * ["emacs", "default"].
132 * </p>
133 * <p>
134 * This value will never be <code>null</code>, and it will never be
135 * empty. It must contain at least one element. Its elements cannot be
136 * <code>null</code>.
137 * </p>
138 */
139 private const String[] schemeIds;
140
141 /**
142 * The map representing the resolved state of the bindings. This is a map of
143 * a command id (<code>String</code>) to triggers (<code>Collection</code>
144 * of <code>TriggerSequence</code>). This value may be <code>null</code>
145 * if it has not yet been initialized.
146 */
147 private Map triggersByCommandId = null;
148
149 /**
150 * Constructs a new instance of <code>CachedBindingSet</code>.
151 *
152 * @param activeContextTree
153 * The set of context identifiers that were active when this
154 * binding set was calculated; may be empty. If it is
155 * <code>null</code>, then the contexts were disregarded in
156 * the computation. This is a map of context id (
157 * <code>String</code>) to parent context id (
158 * <code>String</code>). This is a way of caching the look of
159 * the context tree at the time the binding set was computed.
160 * @param locales
161 * The locales that were active when this binding set was
162 * calculated. The first element is the currently active locale,
163 * and it is followed by increasingly more general locales. This
164 * must not be <code>null</code> and must contain at least one
165 * element. The elements can be <code>null</code>, though.
166 * @param platforms
167 * The platform that were active when this binding set was
168 * calculated. The first element is the currently active
169 * platform, and it is followed by increasingly more general
170 * platforms. This must not be <code>null</code> and must
171 * contain at least one element. The elements can be
172 * <code>null</code>, though.
173 * @param schemeIds
174 * The scheme that was active when this binding set was
175 * calculated, followed by its ancestors. This may be
176 * <code>null</code or empty. The
177 * elements cannot be <code>null</code>.
178 */
179 this(Map activeContextTree, String[] locales,
180 String[] platforms, String[] schemeIds) {
181 if (locales is null) {
182 throw new NullPointerException("The locales cannot be null."); //$NON-NLS-1$
183 }
184
185 if (locales.length is 0) {
186 throw new NullPointerException("The locales cannot be empty."); //$NON-NLS-1$
187 }
188
189 if (platforms is null) {
190 throw new NullPointerException("The platforms cannot be null."); //$NON-NLS-1$
191 }
192
193 if (platforms.length is 0) {
194 throw new NullPointerException("The platforms cannot be empty."); //$NON-NLS-1$
195 }
196
197 this.activeContextTree = activeContextTree;
198 this.locales = locales;
199 this.platforms = platforms;
200 this.schemeIds = schemeIds;
201 }
202
203 /**
204 * Compares this binding set with another object. The objects will be equal
205 * if they are both instance of <code>CachedBindingSet</code> and have
206 * equivalent values for all of their properties.
207 *
208 * @param object
209 * The object with which to compare; may be <code>null</code>.
210 * @return <code>true</code> if they are both instances of
211 * <code>CachedBindingSet</code> and have the same values for all
212 * of their properties; <code>false</code> otherwise.
213 */
214 public final override int opEquals(Object object) {
215 if (!(cast(CachedBindingSet)object )) {
216 return false;
217 }
218
219 CachedBindingSet other = cast(CachedBindingSet) object;
220
221 if (!Util.opEquals(cast(Object)activeContextTree, cast(Object)other.activeContextTree)) {
222 return false;
223 }
224 if (!Util.opEquals(locales, other.locales)) {
225 return false;
226 }
227 if (!Util.opEquals(platforms, other.platforms)) {
228 return false;
229 }
230 return Util.opEquals(schemeIds, other.schemeIds);
231 }
232
233 /**
234 * Returns the map of command identifiers indexed by trigger sequence.
235 *
236 * @return A map of triggers (<code>TriggerSequence</code>) to bindings (<code>Binding</code>).
237 * This value may be <code>null</code> if this was not yet
238 * initialized.
239 */
240 final Map getBindingsByTrigger() {
241 return bindingsByTrigger;
242 }
243
244 /**
245 * Returns a map of conflicts for this set of contexts.
246 *
247 * @return A map of trigger to a collection of Bindings. May be
248 * <code>null</code>.
249 * @since 3.3
250 */
251 final Map getConflictsByTrigger() {
252 return conflictsByTrigger;
253 }
254
255 /**
256 * Returns the map of prefixes to a map of trigger sequence to command
257 * identifiers.
258 *
259 * @return A map of prefixes (<code>TriggerSequence</code>) to a map of
260 * available completions (possibly <code>null</code>, which means
261 * there is an exact match). The available completions is a map of
262 * trigger (<code>TriggerSequence</code>) to command identifier (<code>String</code>).
263 * This value may be <code>null</code> if it has not yet been
264 * initialized.
265 */
266 final Map getPrefixTable() {
267 return prefixTable;
268 }
269
270 /**
271 * Returns the map of triggers indexed by command identifiers.
272 *
273 * @return A map of command identifiers (<code>String</code>) to
274 * triggers (<code>Collection</code> of
275 * <code>TriggerSequence</code>). This value may be
276 * <code>null</code> if this was not yet initialized.
277 */
278 final Map getTriggersByCommandId() {
279 return triggersByCommandId;
280 }
281
282 /**
283 * Computes the hash code for this cached binding set. The hash code is
284 * based only on the immutable values. This allows the set to be created and
285 * checked for in a hashed collection <em>before</em> doing any
286 * computation.
287 *
288 * @return The hash code for this cached binding set.
289 */
290 public final override hash_t toHash() {
291 if (!hashCodeComputed) {
292
293 auto HASH_INITIAL = java.lang.all.toHash(CachedBindingSet.classinfo.name );
294 hashCode = HASH_INITIAL;
295 hashCode = hashCode * HASH_FACTOR
296 + Util.toHash(cast(Object)activeContextTree);
297 hashCode = hashCode * HASH_FACTOR + Util.toHash(locales);
298 hashCode = hashCode * HASH_FACTOR + Util.toHash(platforms);
299 hashCode = hashCode * HASH_FACTOR + Util.toHash(schemeIds);
300 hashCodeComputed = true;
301 }
302
303 return hashCode;
304 }
305
306 /**
307 * Sets the map of command identifiers indexed by trigger.
308 *
309 * @param commandIdsByTrigger
310 * The map to set; must not be <code>null</code>. This is a
311 * map of triggers (<code>TriggerSequence</code>) to binding (<code>Binding</code>).
312 */
313 final void setBindingsByTrigger(Map commandIdsByTrigger) {
314 if (commandIdsByTrigger is null) {
315 throw new NullPointerException(
316 "Cannot set a null binding resolution"); //$NON-NLS-1$
317 }
318
319 this.bindingsByTrigger = commandIdsByTrigger;
320 }
321
322 /**
323 * Sets the map of conflicting bindings by trigger.
324 *
325 * @param conflicts
326 * The map to set; must not be <code>null</code>.
327 * @since 3.3
328 */
329 final void setConflictsByTrigger(Map conflicts) {
330 if (conflicts is null) {
331 throw new NullPointerException(
332 "Cannot set a null binding conflicts"); //$NON-NLS-1$
333 }
334 conflictsByTrigger = conflicts;
335 }
336
337 /**
338 * Sets the map of prefixes to a map of trigger sequence to command
339 * identifiers.
340 *
341 * @param prefixTable
342 * A map of prefixes (<code>TriggerSequence</code>) to a map
343 * of available completions (possibly <code>null</code>, which
344 * means there is an exact match). The available completions is a
345 * map of trigger (<code>TriggerSequence</code>) to command
346 * identifier (<code>String</code>). Must not be
347 * <code>null</code>.
348 */
349 final void setPrefixTable(Map prefixTable) {
350 if (prefixTable is null) {
351 throw new NullPointerException("Cannot set a null prefix table"); //$NON-NLS-1$
352 }
353
354 this.prefixTable = prefixTable;
355 }
356
357 /**
358 * Sets the map of triggers indexed by command identifiers.
359 *
360 * @param triggersByCommandId
361 * The map to set; must not be <code>null</code>. This is a
362 * map of command identifiers (<code>String</code>) to
363 * triggers (<code>Collection</code> of
364 * <code>TriggerSequence</code>).
365 */
366 final void setTriggersByCommandId(Map triggersByCommandId) {
367 if (triggersByCommandId is null) {
368 throw new NullPointerException(
369 "Cannot set a null binding resolution"); //$NON-NLS-1$
370 }
371
372 this.triggersByCommandId = triggersByCommandId;
373 }
374 }