X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.browsing.ui.common%2Fsrc%2Forg%2Fsimantics%2Fbrowsing%2Fui%2Fcommon%2FAdaptableHintContext.java;fp=bundles%2Forg.simantics.browsing.ui.common%2Fsrc%2Forg%2Fsimantics%2Fbrowsing%2Fui%2Fcommon%2FAdaptableHintContext.java;h=bd7aa2790a303dcd491498abd1b1f93b551af15f;hp=0000000000000000000000000000000000000000;hb=6a6726b1ee9c2e78971d26b50f15b867cc7c5a02;hpb=93622c2baf328a90b122dd749b63676c72c839f5 diff --git a/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/AdaptableHintContext.java b/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/AdaptableHintContext.java new file mode 100644 index 000000000..bd7aa2790 --- /dev/null +++ b/bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/AdaptableHintContext.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * 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.common; + +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; + } + +}