-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-/*\r
- * 25.8.2006\r
- */\r
-package org.simantics.utils.ui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.eclipse.core.runtime.Assert;\r
-import org.eclipse.core.runtime.IAdaptable;\r
-import org.eclipse.jface.viewers.ISelection;\r
-import org.eclipse.jface.viewers.IStructuredSelection;\r
-import org.eclipse.jface.viewers.StructuredSelection;\r
-import org.simantics.utils.datastructures.hints.IHintContext;\r
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
-\r
-/**\r
- * ISelectionUtils contains static utility methods for dealing with the\r
- * ISelection interface.\r
- * \r
- * @author Toni Kalajainen\r
- */\r
-public class ISelectionUtils<T> {\r
-\r
- /**\r
- * This method converts selection sel for to collection of instances of T.\r
- * All elements of the selection are assumed to be instances of T.\r
- * \r
- * @param <T> type of interest\r
- * @param sel selection\r
- * @return list\r
- * @throws ClassCastException if the selection contains elements not\r
- * instance of T\r
- */\r
- @SuppressWarnings("unchecked")\r
- public static <T> List<T> convertSelection(ISelection sel) throws ClassCastException\r
- {\r
- if (sel == null || sel.isEmpty() || (!(sel instanceof IStructuredSelection)))\r
- return Collections.emptyList();\r
-\r
- List<T> result = new ArrayList<T>();\r
- //Class<T> tClass = (Class<T>)result.getClass().getTypeParameters()[0].getBounds()[0];\r
- IStructuredSelection ss = (IStructuredSelection) sel;\r
- for (Object o : ss.toArray())\r
- //if (tClass.isAssignableFrom(o.getClass()))\r
- result.add((T)o);\r
- return result;\r
- }\r
-\r
- /**\r
- * This method reads selection sel for all instances of T.\r
- * All elements of the selection are assumed to be instances of T.\r
- * \r
- * @param <T> type of interest\r
- * @param sel selection\r
- * @return set\r
- * @throws ClassCastException if the selection contains elements not\r
- * instance of T\r
- */\r
- @SuppressWarnings("unchecked")\r
- public static <T> Set<T> convertSetSelection(ISelection sel) throws ClassCastException\r
- {\r
- if (sel.isEmpty() || (!(sel instanceof IStructuredSelection)))\r
- return Collections.emptySet();\r
-\r
- Set<T> result = new HashSet<T>();\r
- //Class<T> tClass = (Class<T>)result.getClass().getTypeParameters()[0].getBounds()[0];\r
- IStructuredSelection ss = (IStructuredSelection) sel;\r
- for (Object o : ss.toArray())\r
- //if (tClass.isAssignableFrom(o.getClass()))\r
- result.add((T)o);\r
- return result;\r
- }\r
-\r
-\r
- @SuppressWarnings("unchecked")\r
- public static <T> T convertSingleSelection(ISelection sel)\r
- {\r
- if (sel.isEmpty() || (!(sel instanceof IStructuredSelection)))\r
- return null;\r
- IStructuredSelection ss = (IStructuredSelection) sel;\r
- return (ss.size() == 1) ? (T) ss.getFirstElement() : null;\r
- }\r
-\r
- /**\r
- * This method converts selection sel to collection of instances of T\r
- * @param <T> type of interest\r
- * @param sel selection\r
- * @return list\r
- */\r
- @SuppressWarnings("unchecked")\r
- public static <T> List<T> filterSelection(ISelection sel, Class<T> assignableFrom)\r
- {\r
- if (sel == null || sel.isEmpty() || (!(sel instanceof IStructuredSelection)))\r
- return Collections.emptyList();\r
-\r
- List<T> result = new ArrayList<T>();\r
- IStructuredSelection ss = (IStructuredSelection) sel;\r
- for (Object o : ss.toArray()) {\r
- if (o != null && assignableFrom.isAssignableFrom(o.getClass())) {\r
- result.add((T)o);\r
- } else if (o instanceof IAdaptable) {\r
- T t = (T) ((IAdaptable) o).getAdapter(assignableFrom);\r
- if (t != null)\r
- result.add(t);\r
- }\r
- }\r
- return result;\r
- }\r
-\r
- /**\r
- * This method reads selection sel for all instances of T.\r
- * \r
- * @param <T> type of interest\r
- * @param sel selection\r
- * @return all instances of T in sel\r
- */\r
- public static <T> Set<T> filterSetSelection(Object sel, Class<T> assignableFrom)\r
- {\r
- if (sel instanceof IStructuredSelection) {\r
- IStructuredSelection ss = (IStructuredSelection) sel;\r
- if (!ss.isEmpty())\r
- return filterCollection(ss.toList(), assignableFrom, new HashSet<T>());\r
- } else if (sel instanceof Collection<?>) {\r
- Collection<?> c = (Collection<?>) sel;\r
- if (!c.isEmpty())\r
- return filterCollection(c, assignableFrom, new HashSet<T>());\r
- }\r
-\r
- return Collections.emptySet();\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public static <T> T filterSingleSelection(Object sel, Class<T> assignableTo)\r
- {\r
- if (sel == null) {\r
- return null;\r
- } else if (sel instanceof IStructuredSelection) {\r
- IStructuredSelection ss = (IStructuredSelection) sel;\r
- if (ss.size() == 1)\r
- return tryAdapt(ss.getFirstElement(), assignableTo);\r
- } else if (sel instanceof Collection<?>) {\r
- Collection<?> c = (Collection<?>) sel;\r
- if (c.size() == 1)\r
- return tryAdapt(c.iterator().next(), assignableTo);\r
- } else if (sel.getClass().isArray()) {\r
- Object[] os = (Object[])sel;\r
- Object result = null;\r
- for(Object o : os) {\r
- Object r = tryAdapt(o, assignableTo);\r
- if(r != null) {\r
- if(result != null) return null;\r
- result = r;\r
- }\r
- }\r
- return (T)result;\r
- }\r
- return null;\r
- }\r
-\r
- public static <T> T findFirstAdaptable(Object sel, Class<T> assignableTo)\r
- {\r
- if (sel instanceof IStructuredSelection) {\r
- IStructuredSelection ss = (IStructuredSelection) sel;\r
- if (!ss.isEmpty())\r
- return findFirstAdaptable_(ss.toList(), assignableTo);\r
- } else if (sel instanceof Collection<?>) {\r
- Collection<?> c = (Collection<?>) sel;\r
- if (!c.isEmpty())\r
- return findFirstAdaptable_(c, assignableTo);\r
- }\r
- return null;\r
- }\r
-\r
- private static <T> T findFirstAdaptable_(Collection<?> objects, Class<T> assignableTo) {\r
- for (Object o : objects) {\r
- T t = tryAdapt(o, assignableTo);\r
- if (t != null)\r
- return t;\r
- }\r
- return null;\r
- }\r
-\r
- private static <T, C extends Collection<T>> C filterCollection(Collection<?> objects, Class<T> assignableTo, C result) {\r
- for (Object o : objects) {\r
- T t = tryAdapt(o, assignableTo);\r
- if (t != null)\r
- result.add(t);\r
- }\r
- return result;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- private static <T> T tryAdapt(Object o, Class<T> assignableTo) {\r
- if (o != null && assignableTo.isAssignableFrom(o.getClass())) {\r
- return (T) o;\r
- } else if (o instanceof IAdaptable) {\r
- T t = (T) ((IAdaptable) o).getAdapter(assignableTo);\r
- if (t != null) {\r
- return t;\r
- }\r
- }\r
- return null;\r
- }\r
-\r
- /**\r
- * Try to extract a single object that is an instance of the specified class\r
- * out of the provided selection object.\r
- * \r
- * This tries everything even remotely plausible - and then some.\r
- * \r
- * This method works as follows:\r
- * <ul>\r
- * <li>Supported input selection objects: IStructuredSelection and\r
- * Collection<?>, IHintContext, IAdaptable, direct instances of the\r
- * requested class</li>\r
- * <li>Selection elements are assumed to be either instances of\r
- * IHintContext, IAdaptable or direct instances of the requested class</li>\r
- * <li>If an IHintContext is found, the result object is searched within it\r
- * with the specified key.</li>\r
- * <li>Searching involves testing whether the hint value is an instance of\r
- * clazz or adaptable to it through {@link IAdaptable}.</li>\r
- * </ul>\r
- * \r
- * \r
- * \r
- * @param selection\r
- * @param key\r
- * @param clazz desired class of the objects to look for in the selection\r
- * @return a single objects matching the search criteria. If there are no or\r
- * several matches, <code>null</code> is returned\r
- */\r
- @SuppressWarnings("unchecked")\r
- public static <T> T getSinglePossibleKey(Object object, Key key, Class<T> clazz) {\r
- return getSinglePossibleKey(object, key, clazz, true);\r
- }\r
-\r
- /**\r
- * Try to extract a single object that is an instance of the specified class\r
- * out of the provided selection object.\r
- * \r
- * This tries everything even remotely plausible - and then some.\r
- * \r
- * This method works as follows:\r
- * <ul>\r
- * <li>Supported input selection objects: IStructuredSelection and\r
- * Collection<?>, IHintContext, IAdaptable, direct instances of the\r
- * requested class</li>\r
- * <li>Selection elements are assumed to be either instances of\r
- * IHintContext, IAdaptable or direct instances of the requested class</li>\r
- * <li>If an IHintContext is found, the result object is searched within it\r
- * with the specified key.</li>\r
- * <li>Searching involves testing whether the hint value is an instance of\r
- * clazz or adaptable to it through {@link IAdaptable}.</li>\r
- * </ul>\r
- * \r
- * \r
- * \r
- * @param selection\r
- * @param key\r
- * @param clazz desired class of the objects to look for in the selection\r
- * @return a single objects matching the search criteria. If there are no or\r
- * several matches, <code>null</code> is returned\r
- */\r
- @SuppressWarnings("unchecked")\r
- public static <T> T getSinglePossibleKey(Object object, Key key, Class<T> clazz, boolean allowDirectMatch) {\r
- if (object == null)\r
- return null;\r
-\r
- // Direct match is returned without key analysis\r
- if (allowDirectMatch && clazz.isInstance(object))\r
- return (T) object;\r
-\r
- if (object instanceof ISelection) {\r
- ISelection sel = (ISelection) object;\r
-\r
- if (sel.isEmpty() || (!(sel instanceof IStructuredSelection)))\r
- return null;\r
-\r
- IStructuredSelection ss = (IStructuredSelection) sel;\r
- if (ss.size() != 1)\r
- return null;\r
-\r
- // The result must now be in the first and only element\r
- return getSinglePossibleKey(ss.getFirstElement(), key, clazz, allowDirectMatch);\r
- }\r
-\r
- if (object instanceof Collection<?>) {\r
- Collection<?> c = (Collection<?>) object;\r
- if (c.size() != 1)\r
- return null;\r
-\r
- return getSinglePossibleKey(c.iterator().next(), key, clazz, allowDirectMatch);\r
- }\r
-\r
- // If there was no success so far now we must take the Key into account\r
- if (object instanceof IHintContext) {\r
- IHintContext context = (IHintContext) object;\r
- Object hint = context.getHint(key);\r
-\r
- // We had a hint context and a matching key was not available - now try single hint - TODO: this somewhat questionable\r
- if (hint == null) {\r
- // NOTE: Removed because of a bug:\r
- // https://www.simantics.org/redmine/issues/3061\r
- // Hope this doesn't break existing code.\r
- Map<Key, Object> hints = context.getHints();\r
- // There are multiple hints, thats it, there is no result\r
- if(hints.size() != 1) return null;\r
- hint = hints.values().iterator().next();\r
-\r
- T t = getSinglePossibleKey(hint, key, clazz);\r
-// if (t != null) {\r
-// System.out.println("******************** GEEZ: " + t);\r
-// new Exception().printStackTrace();\r
-// }\r
- return t;\r
-// return null;\r
- }\r
-\r
- if (clazz.isInstance(hint)) {\r
- return (T) hint;\r
- } else if (hint instanceof IAdaptable) {\r
- T adapter = (T) ((IAdaptable) hint).getAdapter(clazz);\r
- if (adapter != null)\r
- return adapter;\r
- } else {\r
- return getSinglePossibleKey(hint, key, clazz);\r
- }\r
- }\r
-\r
- if (object instanceof IAdaptable)\r
- return getSinglePossibleKey(((IAdaptable) object).getAdapter(IHintContext.class), key, clazz, allowDirectMatch);\r
-\r
- return null;\r
-\r
- }\r
-\r
- /**\r
- * Try to extract the possible objects that are instances of the specified\r
- * class out of the provided selection object.\r
- * \r
- * This method works as follows:\r
- * <ul>\r
- * <li>Supported input selection objects: IStructuredSelection and\r
- * Collection<?></li>\r
- * <li>Selection elements are assumed to be IHintContext instances</li>\r
- * <li>The result objects are searched for in the IHintContexts with the\r
- * specified key.</li>\r
- * <li>Searching involves testing whether the hint value is an instance of\r
- * clazz or adaptable to it through {@link IAdaptable}.</li>\r
- * </ul>\r
- * \r
- * All objects that pass through this filter are returned as the result.\r
- * \r
- * @param selection\r
- * @param key\r
- * @param clazz desired class of the objects to look for in the selection\r
- * @return list of the criteria matching elements in the selection or empty\r
- * list if nothing suitable was found\r
- */\r
- public static <T> List<T> getPossibleKeys(Object selection, Key key, Class<T> clazz) {\r
- if (selection == null)\r
- return Collections.emptyList();\r
-\r
- if (selection instanceof IStructuredSelection) {\r
- IStructuredSelection ss = (IStructuredSelection) selection;\r
- if (ss.isEmpty())\r
- return Collections.emptyList();\r
- return extractPossibleKeys(ss.toList(), key, clazz);\r
- }\r
-\r
- if (selection instanceof Collection<?>) {\r
- Collection<?> c = (Collection<?>) selection;\r
- return extractPossibleKeys(c, key, clazz);\r
- }\r
-\r
- if (selection.getClass().isArray()) {\r
- Object[] c = (Object[]) selection;\r
- return extractPossibleKeys(c, key, clazz);\r
- }\r
-\r
- return extractPossibleKeys(Collections.singleton(selection), key, clazz);\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- private static <T> List<T> extractPossibleKeys(Collection<?> objects, Key key, Class<T> clazz) {\r
- if (objects.isEmpty())\r
- return Collections.emptyList();\r
-\r
- ArrayList<T> result = new ArrayList<T>(objects.size());\r
- for (Object o : objects) {\r
- if (o instanceof IHintContext) {\r
- IHintContext context = (IHintContext) o;\r
- Object object = context.getHint(key);\r
- if (object != null) {\r
- if (clazz.isInstance(object)) {\r
- result.add((T) object);\r
- } else if (object instanceof IAdaptable) {\r
- Object adapter = ((IAdaptable) object).getAdapter(clazz);\r
- if (adapter != null)\r
- result.add((T) adapter);\r
- }\r
- }\r
- }\r
- }\r
- return result;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- private static <T> List<T> extractPossibleKeys(Object[] objects, Key key, Class<T> clazz) {\r
- if (objects.length==0)\r
- return Collections.emptyList();\r
-\r
- ArrayList<T> result = new ArrayList<T>(objects.length);\r
- for (Object o : objects) {\r
- if (o instanceof IHintContext) {\r
- IHintContext context = (IHintContext) o;\r
- Object object = context.getHint(key);\r
- if (object != null) {\r
- if (clazz.isInstance(object)) {\r
- result.add((T) object);\r
- } else if (object instanceof IAdaptable) {\r
- Object adapter = ((IAdaptable) object).getAdapter(clazz);\r
- if (adapter != null)\r
- result.add((T) adapter);\r
- }\r
- }\r
- }\r
- }\r
- return result;\r
- }\r
-\r
- /**\r
- * This method creates selection from set of objects\r
- * \r
- * @param objects objects\r
- * @return selection\r
- */\r
- public static ISelection createSelection(Object ... objects)\r
- {\r
- return new StructuredSelection(objects);\r
- }\r
-\r
-\r
- /**\r
- * A testcase.\r
- * \r
- * @param args\r
- */\r
- public static void main(String[] args) {\r
- Object o1 = new Integer(9);\r
- Object o2 = new HashMap<Object, Object>();\r
- Object o3 = new Long(1);\r
-\r
- ISelection s1 = createSelection(o1, o2, o3);\r
-\r
- List<Number> f1 = convertSelection(s1);\r
- List<Number> f2 = filterSelection(s1, Number.class);\r
-\r
- System.out.println(f1.toString());\r
- System.out.println(f2.toString());\r
-\r
- Assert.isTrue(f2.contains(o1) && f2.contains(o3) && !f2.contains(o2));\r
- Assert.isTrue(f1.contains(o1) && f1.contains(o3) && !f1.contains(o2));\r
- }\r
-\r
-}\r
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+/*
+ * 25.8.2006
+ */
+package org.simantics.utils.ui;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.simantics.utils.datastructures.hints.IHintContext;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+
+/**
+ * ISelectionUtils contains static utility methods for dealing with the
+ * ISelection interface.
+ *
+ * @author Toni Kalajainen
+ */
+public class ISelectionUtils<T> {
+
+ /**
+ * This method converts selection sel for to collection of instances of T.
+ * All elements of the selection are assumed to be instances of T.
+ *
+ * @param <T> type of interest
+ * @param sel selection
+ * @return list
+ * @throws ClassCastException if the selection contains elements not
+ * instance of T
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> List<T> convertSelection(ISelection sel) throws ClassCastException
+ {
+ if (sel == null || sel.isEmpty() || (!(sel instanceof IStructuredSelection)))
+ return Collections.emptyList();
+
+ List<T> result = new ArrayList<T>();
+ //Class<T> tClass = (Class<T>)result.getClass().getTypeParameters()[0].getBounds()[0];
+ IStructuredSelection ss = (IStructuredSelection) sel;
+ for (Object o : ss.toArray())
+ //if (tClass.isAssignableFrom(o.getClass()))
+ result.add((T)o);
+ return result;
+ }
+
+ /**
+ * This method reads selection sel for all instances of T.
+ * All elements of the selection are assumed to be instances of T.
+ *
+ * @param <T> type of interest
+ * @param sel selection
+ * @return set
+ * @throws ClassCastException if the selection contains elements not
+ * instance of T
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> Set<T> convertSetSelection(ISelection sel) throws ClassCastException
+ {
+ if (sel.isEmpty() || (!(sel instanceof IStructuredSelection)))
+ return Collections.emptySet();
+
+ Set<T> result = new HashSet<T>();
+ //Class<T> tClass = (Class<T>)result.getClass().getTypeParameters()[0].getBounds()[0];
+ IStructuredSelection ss = (IStructuredSelection) sel;
+ for (Object o : ss.toArray())
+ //if (tClass.isAssignableFrom(o.getClass()))
+ result.add((T)o);
+ return result;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static <T> T convertSingleSelection(ISelection sel)
+ {
+ if (sel.isEmpty() || (!(sel instanceof IStructuredSelection)))
+ return null;
+ IStructuredSelection ss = (IStructuredSelection) sel;
+ return (ss.size() == 1) ? (T) ss.getFirstElement() : null;
+ }
+
+ /**
+ * This method converts selection sel to collection of instances of T
+ * @param <T> type of interest
+ * @param sel selection
+ * @return list
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> List<T> filterSelection(ISelection sel, Class<T> assignableFrom)
+ {
+ if (sel == null || sel.isEmpty() || (!(sel instanceof IStructuredSelection)))
+ return Collections.emptyList();
+
+ List<T> result = new ArrayList<T>();
+ IStructuredSelection ss = (IStructuredSelection) sel;
+ for (Object o : ss.toArray()) {
+ if (o != null && assignableFrom.isAssignableFrom(o.getClass())) {
+ result.add((T)o);
+ } else if (o instanceof IAdaptable) {
+ T t = (T) ((IAdaptable) o).getAdapter(assignableFrom);
+ if (t != null)
+ result.add(t);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * This method reads selection sel for all instances of T.
+ *
+ * @param <T> type of interest
+ * @param sel selection
+ * @return all instances of T in sel
+ */
+ public static <T> Set<T> filterSetSelection(Object sel, Class<T> assignableFrom)
+ {
+ if (sel instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection) sel;
+ if (!ss.isEmpty())
+ return filterCollection(ss.toList(), assignableFrom, new HashSet<T>());
+ } else if (sel instanceof Collection<?>) {
+ Collection<?> c = (Collection<?>) sel;
+ if (!c.isEmpty())
+ return filterCollection(c, assignableFrom, new HashSet<T>());
+ }
+
+ return Collections.emptySet();
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T filterSingleSelection(Object sel, Class<T> assignableTo)
+ {
+ if (sel == null) {
+ return null;
+ } else if (sel instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection) sel;
+ if (ss.size() == 1)
+ return tryAdapt(ss.getFirstElement(), assignableTo);
+ } else if (sel instanceof Collection<?>) {
+ Collection<?> c = (Collection<?>) sel;
+ if (c.size() == 1)
+ return tryAdapt(c.iterator().next(), assignableTo);
+ } else if (sel.getClass().isArray()) {
+ Object[] os = (Object[])sel;
+ Object result = null;
+ for(Object o : os) {
+ Object r = tryAdapt(o, assignableTo);
+ if(r != null) {
+ if(result != null) return null;
+ result = r;
+ }
+ }
+ return (T)result;
+ }
+ return null;
+ }
+
+ public static <T> T findFirstAdaptable(Object sel, Class<T> assignableTo)
+ {
+ if (sel instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection) sel;
+ if (!ss.isEmpty())
+ return findFirstAdaptable_(ss.toList(), assignableTo);
+ } else if (sel instanceof Collection<?>) {
+ Collection<?> c = (Collection<?>) sel;
+ if (!c.isEmpty())
+ return findFirstAdaptable_(c, assignableTo);
+ }
+ return null;
+ }
+
+ private static <T> T findFirstAdaptable_(Collection<?> objects, Class<T> assignableTo) {
+ for (Object o : objects) {
+ T t = tryAdapt(o, assignableTo);
+ if (t != null)
+ return t;
+ }
+ return null;
+ }
+
+ private static <T, C extends Collection<T>> C filterCollection(Collection<?> objects, Class<T> assignableTo, C result) {
+ for (Object o : objects) {
+ T t = tryAdapt(o, assignableTo);
+ if (t != null)
+ result.add(t);
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> T tryAdapt(Object o, Class<T> assignableTo) {
+ if (o != null && assignableTo.isAssignableFrom(o.getClass())) {
+ return (T) o;
+ } else if (o instanceof IAdaptable) {
+ T t = (T) ((IAdaptable) o).getAdapter(assignableTo);
+ if (t != null) {
+ return t;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Try to extract a single object that is an instance of the specified class
+ * out of the provided selection object.
+ *
+ * This tries everything even remotely plausible - and then some.
+ *
+ * This method works as follows:
+ * <ul>
+ * <li>Supported input selection objects: IStructuredSelection and
+ * Collection<?>, IHintContext, IAdaptable, direct instances of the
+ * requested class</li>
+ * <li>Selection elements are assumed to be either instances of
+ * IHintContext, IAdaptable or direct instances of the requested class</li>
+ * <li>If an IHintContext is found, the result object is searched within it
+ * with the specified key.</li>
+ * <li>Searching involves testing whether the hint value is an instance of
+ * clazz or adaptable to it through {@link IAdaptable}.</li>
+ * </ul>
+ *
+ *
+ *
+ * @param selection
+ * @param key
+ * @param clazz desired class of the objects to look for in the selection
+ * @return a single objects matching the search criteria. If there are no or
+ * several matches, <code>null</code> is returned
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T getSinglePossibleKey(Object object, Key key, Class<T> clazz) {
+ return getSinglePossibleKey(object, key, clazz, true);
+ }
+
+ /**
+ * Try to extract a single object that is an instance of the specified class
+ * out of the provided selection object.
+ *
+ * This tries everything even remotely plausible - and then some.
+ *
+ * This method works as follows:
+ * <ul>
+ * <li>Supported input selection objects: IStructuredSelection and
+ * Collection<?>, IHintContext, IAdaptable, direct instances of the
+ * requested class</li>
+ * <li>Selection elements are assumed to be either instances of
+ * IHintContext, IAdaptable or direct instances of the requested class</li>
+ * <li>If an IHintContext is found, the result object is searched within it
+ * with the specified key.</li>
+ * <li>Searching involves testing whether the hint value is an instance of
+ * clazz or adaptable to it through {@link IAdaptable}.</li>
+ * </ul>
+ *
+ *
+ *
+ * @param selection
+ * @param key
+ * @param clazz desired class of the objects to look for in the selection
+ * @return a single objects matching the search criteria. If there are no or
+ * several matches, <code>null</code> is returned
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T getSinglePossibleKey(Object object, Key key, Class<T> clazz, boolean allowDirectMatch) {
+ if (object == null)
+ return null;
+
+ // Direct match is returned without key analysis
+ if (allowDirectMatch && clazz.isInstance(object))
+ return (T) object;
+
+ if (object instanceof ISelection) {
+ ISelection sel = (ISelection) object;
+
+ if (sel.isEmpty() || (!(sel instanceof IStructuredSelection)))
+ return null;
+
+ IStructuredSelection ss = (IStructuredSelection) sel;
+ if (ss.size() != 1)
+ return null;
+
+ // The result must now be in the first and only element
+ return getSinglePossibleKey(ss.getFirstElement(), key, clazz, allowDirectMatch);
+ }
+
+ if (object instanceof Collection<?>) {
+ Collection<?> c = (Collection<?>) object;
+ if (c.size() != 1)
+ return null;
+
+ return getSinglePossibleKey(c.iterator().next(), key, clazz, allowDirectMatch);
+ }
+
+ // If there was no success so far now we must take the Key into account
+ if (object instanceof IHintContext) {
+ IHintContext context = (IHintContext) object;
+ Object hint = context.getHint(key);
+
+ // We had a hint context and a matching key was not available - now try single hint - TODO: this somewhat questionable
+ if (hint == null) {
+ // NOTE: Removed because of a bug:
+ // https://www.simantics.org/redmine/issues/3061
+ // Hope this doesn't break existing code.
+ Map<Key, Object> hints = context.getHints();
+ // There are multiple hints, thats it, there is no result
+ if(hints.size() != 1) return null;
+ hint = hints.values().iterator().next();
+
+ T t = getSinglePossibleKey(hint, key, clazz);
+// if (t != null) {
+// System.out.println("******************** GEEZ: " + t);
+// new Exception().printStackTrace();
+// }
+ return t;
+// return null;
+ }
+
+ if (clazz.isInstance(hint)) {
+ return (T) hint;
+ } else if (hint instanceof IAdaptable) {
+ T adapter = (T) ((IAdaptable) hint).getAdapter(clazz);
+ if (adapter != null)
+ return adapter;
+ } else {
+ return getSinglePossibleKey(hint, key, clazz);
+ }
+ }
+
+ if (object instanceof IAdaptable)
+ return getSinglePossibleKey(((IAdaptable) object).getAdapter(IHintContext.class), key, clazz, allowDirectMatch);
+
+ return null;
+
+ }
+
+ /**
+ * Try to extract the possible objects that are instances of the specified
+ * class out of the provided selection object.
+ *
+ * This method works as follows:
+ * <ul>
+ * <li>Supported input selection objects: IStructuredSelection and
+ * Collection<?></li>
+ * <li>Selection elements are assumed to be IHintContext instances</li>
+ * <li>The result objects are searched for in the IHintContexts with the
+ * specified key.</li>
+ * <li>Searching involves testing whether the hint value is an instance of
+ * clazz or adaptable to it through {@link IAdaptable}.</li>
+ * </ul>
+ *
+ * All objects that pass through this filter are returned as the result.
+ *
+ * @param selection
+ * @param key
+ * @param clazz desired class of the objects to look for in the selection
+ * @return list of the criteria matching elements in the selection or empty
+ * list if nothing suitable was found
+ */
+ public static <T> List<T> getPossibleKeys(Object selection, Key key, Class<T> clazz) {
+ if (selection == null)
+ return Collections.emptyList();
+
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection) selection;
+ if (ss.isEmpty())
+ return Collections.emptyList();
+ return extractPossibleKeys(ss.toList(), key, clazz);
+ }
+
+ if (selection instanceof Collection<?>) {
+ Collection<?> c = (Collection<?>) selection;
+ return extractPossibleKeys(c, key, clazz);
+ }
+
+ if (selection.getClass().isArray()) {
+ Object[] c = (Object[]) selection;
+ return extractPossibleKeys(c, key, clazz);
+ }
+
+ return extractPossibleKeys(Collections.singleton(selection), key, clazz);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> List<T> extractPossibleKeys(Collection<?> objects, Key key, Class<T> clazz) {
+ if (objects.isEmpty())
+ return Collections.emptyList();
+
+ ArrayList<T> result = new ArrayList<T>(objects.size());
+ for (Object o : objects) {
+ if (o instanceof IHintContext) {
+ IHintContext context = (IHintContext) o;
+ Object object = context.getHint(key);
+ if (object != null) {
+ if (clazz.isInstance(object)) {
+ result.add((T) object);
+ } else if (object instanceof IAdaptable) {
+ Object adapter = ((IAdaptable) object).getAdapter(clazz);
+ if (adapter != null)
+ result.add((T) adapter);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> List<T> extractPossibleKeys(Object[] objects, Key key, Class<T> clazz) {
+ if (objects.length==0)
+ return Collections.emptyList();
+
+ ArrayList<T> result = new ArrayList<T>(objects.length);
+ for (Object o : objects) {
+ if (o instanceof IHintContext) {
+ IHintContext context = (IHintContext) o;
+ Object object = context.getHint(key);
+ if (object != null) {
+ if (clazz.isInstance(object)) {
+ result.add((T) object);
+ } else if (object instanceof IAdaptable) {
+ Object adapter = ((IAdaptable) object).getAdapter(clazz);
+ if (adapter != null)
+ result.add((T) adapter);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * This method creates selection from set of objects
+ *
+ * @param objects objects
+ * @return selection
+ */
+ public static ISelection createSelection(Object ... objects)
+ {
+ return new StructuredSelection(objects);
+ }
+
+
+ /**
+ * A testcase.
+ *
+ * @param args
+ */
+ public static void main(String[] args) {
+ Object o1 = new Integer(9);
+ Object o2 = new HashMap<Object, Object>();
+ Object o3 = new Long(1);
+
+ ISelection s1 = createSelection(o1, o2, o3);
+
+ List<Number> f1 = convertSelection(s1);
+ List<Number> f2 = filterSelection(s1, Number.class);
+
+ System.out.println(f1.toString());
+ System.out.println(f2.toString());
+
+ Assert.isTrue(f2.contains(o1) && f2.contains(o3) && !f2.contains(o2));
+ Assert.isTrue(f1.contains(o1) && f1.contains(o3) && !f1.contains(o2));
+ }
+
+}