1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.browsing.ui.swt;
\r
14 import java.util.Arrays;
\r
15 import java.util.HashMap;
\r
16 import java.util.Map;
\r
17 import java.util.Map.Entry;
\r
19 import org.eclipse.core.runtime.IAdaptable;
\r
20 import org.simantics.db.layer0.SelectionHints;
\r
21 import org.simantics.ui.selection.WorkbenchSelectionContentType;
\r
22 import org.simantics.ui.selection.WorkbenchSelectionElement;
\r
23 import org.simantics.utils.ObjectUtils;
\r
24 import org.simantics.utils.datastructures.hints.IHintContext;
\r
25 import org.simantics.utils.datastructures.hints.IHintListener;
\r
26 import org.simantics.utils.threads.IThreadWorkQueue;
\r
29 * A custom internal hint context implementation that does not support
\r
30 * notifications to achieve a more space-optimized implementation.
\r
32 * @author Tuukka Lehtonen
\r
34 public class AdaptableHintContext implements IHintContext, IAdaptable, WorkbenchSelectionElement {
\r
36 private final Key[] keysToTry;
\r
37 protected final Map<Key, Object> hints;
\r
39 public AdaptableHintContext() {
\r
40 this(SelectionHints.STD_KEYS);
\r
43 public AdaptableHintContext(Key... keys) {
\r
44 this(new HashMap<Key, Object>(4), keys);
\r
47 public AdaptableHintContext(Map<Key, Object> hints, Key... keys) {
\r
49 throw new NullPointerException("null hints");
\r
50 this.keysToTry = keys;
\r
54 @SuppressWarnings({ "unchecked", "rawtypes" })
\r
56 public Object getAdapter(Class adapter) {
\r
57 for (Key key : keysToTry) {
\r
58 Object o = getHint(key);
\r
59 if (adapter.isAssignableFrom(o.getClass()))
\r
61 if (o instanceof IAdaptable) {
\r
62 Object adapted = ((IAdaptable) o).getAdapter(adapter);
\r
63 if (adapted != null) {
\r
72 public String toString() {
\r
73 return super.toString() + getHints();
\r
77 public void clearWithoutNotification() {
\r
82 public boolean containsHint(Key key) {
\r
83 return hints.get(key) != null;
\r
86 @SuppressWarnings("unchecked")
\r
88 public <E> E getHint(Key key) {
\r
90 throw new IllegalArgumentException("key is null");
\r
91 synchronized (this) {
\r
92 return (E) hints.get(key);
\r
97 public synchronized Map<Key, Object> getHints() {
\r
98 return new HashMap<Key, Object>(hints);
\r
102 public Map<Key, Object> getHintsUnsafe() {
\r
106 @SuppressWarnings("unchecked")
\r
108 public <E extends Key> Map<E, Object> getHintsOfClass(Class<E> clazz) {
\r
109 Map<E, Object> result = null;
\r
110 for (Entry<Key, Object> e : hints.entrySet()) {
\r
111 Key key = e.getKey();
\r
112 if (clazz.isAssignableFrom(key.getClass())) {
\r
113 if (result == null)
\r
114 result = new HashMap<E, Object>(4);
\r
115 result.put((E) key, e.getValue());
\r
122 public void setHint(Key key, Object value) {
\r
124 throw new IllegalArgumentException("key is null");
\r
126 throw new IllegalArgumentException("value is null");
\r
127 if (!key.isValueAccepted(value))
\r
128 throw new RuntimeException("Value \"" + value + "\" is not accepted with key " + key.getClass().getName());
\r
130 synchronized (this) {
\r
131 hints.put(key, value);
\r
136 public void setHints(Map<Key, Object> hints) {
\r
137 synchronized (this) {
\r
138 for (Entry<Key, Object> e : hints.entrySet()) {
\r
139 Key key = e.getKey();
\r
140 Object value = e.getValue();
\r
142 throw new IllegalArgumentException("a value is null for key " + e.getKey());
\r
143 this.hints.put(key, value);
\r
148 @SuppressWarnings("unchecked")
\r
150 public <E> E removeHint(Key key) {
\r
152 throw new IllegalArgumentException("key is null");
\r
154 Object oldValue = null;
\r
155 synchronized (this) {
\r
156 oldValue = hints.remove(key);
\r
158 if (oldValue == null)
\r
160 return (E) oldValue;
\r
164 public void addHintListener(IHintListener listener) {
\r
165 throw new UnsupportedOperationException();
\r
169 public void removeHintListener(IHintListener listener) {
\r
170 throw new UnsupportedOperationException();
\r
174 public void addKeyHintListener(Key key, IHintListener listener) {
\r
175 throw new UnsupportedOperationException();
\r
179 public void removeKeyHintListener(Key key, IHintListener listener) {
\r
180 throw new UnsupportedOperationException();
\r
184 public void addHintListener(IThreadWorkQueue threadAccess, IHintListener listener) {
\r
185 throw new UnsupportedOperationException();
\r
189 public void removeHintListener(IThreadWorkQueue threadAccess, IHintListener listener) {
\r
190 throw new UnsupportedOperationException();
\r
194 public void addKeyHintListener(IThreadWorkQueue threadAccess, Key key, IHintListener listener) {
\r
195 throw new UnsupportedOperationException();
\r
199 public void removeKeyHintListener(IThreadWorkQueue threadAccess, Key key, IHintListener listener) {
\r
200 throw new UnsupportedOperationException();
\r
204 public int hashCode() {
\r
205 return ((hints.hashCode() * 31) + Arrays.hashCode(keysToTry)) * 31;
\r
209 public boolean equals(Object obj) {
\r
214 if (getClass() != obj.getClass())
\r
216 AdaptableHintContext other = (AdaptableHintContext) obj;
\r
217 return Arrays.equals(keysToTry, other.keysToTry) && ObjectUtils.objectEquals(hints, other.hints);
\r
221 public <T> T getContent(WorkbenchSelectionContentType<T> contentType) {
\r