/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.browsing.ui.swt; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.eclipse.core.runtime.IAdaptable; import org.simantics.db.layer0.SelectionHints; import org.simantics.ui.selection.WorkbenchSelectionContentType; import org.simantics.ui.selection.WorkbenchSelectionElement; import org.simantics.utils.ObjectUtils; import org.simantics.utils.datastructures.hints.IHintContext; import org.simantics.utils.datastructures.hints.IHintListener; import org.simantics.utils.threads.IThreadWorkQueue; /** * A custom internal hint context implementation that does not support * notifications to achieve a more space-optimized implementation. * * @author Tuukka Lehtonen */ public class AdaptableHintContext implements IHintContext, IAdaptable, WorkbenchSelectionElement { private final Key[] keysToTry; protected final Map hints; public AdaptableHintContext() { this(SelectionHints.STD_KEYS); } public AdaptableHintContext(Key... keys) { this(new HashMap(4), keys); } public AdaptableHintContext(Map hints, Key... keys) { if (hints == null) throw new NullPointerException("null hints"); this.keysToTry = keys; this.hints = hints; } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public Object getAdapter(Class adapter) { for (Key key : keysToTry) { Object o = getHint(key); if (adapter.isAssignableFrom(o.getClass())) return o; if (o instanceof IAdaptable) { Object adapted = ((IAdaptable) o).getAdapter(adapter); if (adapted != null) { return adapted; } } } return null; } @Override public String toString() { return super.toString() + getHints(); } @Override public void clearWithoutNotification() { hints.clear(); } @Override public boolean containsHint(Key key) { return hints.get(key) != null; } @SuppressWarnings("unchecked") @Override public E getHint(Key key) { if (key == null) throw new IllegalArgumentException("key is null"); synchronized (this) { return (E) hints.get(key); } } @Override public synchronized Map getHints() { return new HashMap(hints); } @Override public Map getHintsUnsafe() { return hints; } @SuppressWarnings("unchecked") @Override public Map getHintsOfClass(Class clazz) { Map result = null; for (Entry e : hints.entrySet()) { Key key = e.getKey(); if (clazz.isAssignableFrom(key.getClass())) { if (result == null) result = new HashMap(4); result.put((E) key, e.getValue()); } } return result; } @Override public void setHint(Key key, Object value) { if (key == null) throw new IllegalArgumentException("key is null"); if (value == null) throw new IllegalArgumentException("value is null"); if (!key.isValueAccepted(value)) throw new RuntimeException("Value \"" + value + "\" is not accepted with key " + key.getClass().getName()); synchronized (this) { hints.put(key, value); } } @Override public void setHints(Map hints) { synchronized (this) { for (Entry e : hints.entrySet()) { Key key = e.getKey(); Object value = e.getValue(); if (value == null) throw new IllegalArgumentException("a value is null for key " + e.getKey()); this.hints.put(key, value); } } } @SuppressWarnings("unchecked") @Override public E removeHint(Key key) { if (key == null) throw new IllegalArgumentException("key is null"); Object oldValue = null; synchronized (this) { oldValue = hints.remove(key); } if (oldValue == null) return null; return (E) oldValue; } @Override public void addHintListener(IHintListener listener) { throw new UnsupportedOperationException(); } @Override public void removeHintListener(IHintListener listener) { throw new UnsupportedOperationException(); } @Override public void addKeyHintListener(Key key, IHintListener listener) { throw new UnsupportedOperationException(); } @Override public void removeKeyHintListener(Key key, IHintListener listener) { throw new UnsupportedOperationException(); } @Override public void addHintListener(IThreadWorkQueue threadAccess, IHintListener listener) { throw new UnsupportedOperationException(); } @Override public void removeHintListener(IThreadWorkQueue threadAccess, IHintListener listener) { throw new UnsupportedOperationException(); } @Override public void addKeyHintListener(IThreadWorkQueue threadAccess, Key key, IHintListener listener) { throw new UnsupportedOperationException(); } @Override public void removeKeyHintListener(IThreadWorkQueue threadAccess, Key key, IHintListener listener) { throw new UnsupportedOperationException(); } @Override public int hashCode() { return ((hints.hashCode() * 31) + Arrays.hashCode(keysToTry)) * 31; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; AdaptableHintContext other = (AdaptableHintContext) obj; return Arrays.equals(keysToTry, other.keysToTry) && ObjectUtils.objectEquals(hints, other.hints); } @Override public T getContent(WorkbenchSelectionContentType contentType) { return null; } }