X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.utils.ui%2Fsrc%2Forg%2Fsimantics%2Futils%2Fui%2FISelectionUtils.java;h=c04ad572bad1ebd48ed130e3c8916cf64fa2311b;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hp=1f4e22824315ede3f0b20eb79dfde21319fdd990;hpb=24e2b34260f219f0d1644ca7a138894980e25b14;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/ISelectionUtils.java b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/ISelectionUtils.java index 1f4e22824..c04ad572b 100644 --- a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/ISelectionUtils.java +++ b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/ISelectionUtils.java @@ -1,484 +1,484 @@ -/******************************************************************************* - * 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 { - - /** - * 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 type of interest - * @param sel selection - * @return list - * @throws ClassCastException if the selection contains elements not - * instance of T - */ - @SuppressWarnings("unchecked") - public static List convertSelection(ISelection sel) throws ClassCastException - { - if (sel == null || sel.isEmpty() || (!(sel instanceof IStructuredSelection))) - return Collections.emptyList(); - - List result = new ArrayList(); - //Class tClass = (Class)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 type of interest - * @param sel selection - * @return set - * @throws ClassCastException if the selection contains elements not - * instance of T - */ - @SuppressWarnings("unchecked") - public static Set convertSetSelection(ISelection sel) throws ClassCastException - { - if (sel.isEmpty() || (!(sel instanceof IStructuredSelection))) - return Collections.emptySet(); - - Set result = new HashSet(); - //Class tClass = (Class)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 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 type of interest - * @param sel selection - * @return list - */ - @SuppressWarnings("unchecked") - public static List filterSelection(ISelection sel, Class assignableFrom) - { - if (sel == null || sel.isEmpty() || (!(sel instanceof IStructuredSelection))) - return Collections.emptyList(); - - List result = new ArrayList(); - 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 type of interest - * @param sel selection - * @return all instances of T in sel - */ - public static Set filterSetSelection(Object sel, Class assignableFrom) - { - if (sel instanceof IStructuredSelection) { - IStructuredSelection ss = (IStructuredSelection) sel; - if (!ss.isEmpty()) - return filterCollection(ss.toList(), assignableFrom, new HashSet()); - } else if (sel instanceof Collection) { - Collection c = (Collection) sel; - if (!c.isEmpty()) - return filterCollection(c, assignableFrom, new HashSet()); - } - - return Collections.emptySet(); - } - - @SuppressWarnings("unchecked") - public static T filterSingleSelection(Object sel, Class 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 findFirstAdaptable(Object sel, Class 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 findFirstAdaptable_(Collection objects, Class assignableTo) { - for (Object o : objects) { - T t = tryAdapt(o, assignableTo); - if (t != null) - return t; - } - return null; - } - - private static > C filterCollection(Collection objects, Class 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 tryAdapt(Object o, Class 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: - *
    - *
  • Supported input selection objects: IStructuredSelection and - * Collection<?>, IHintContext, IAdaptable, direct instances of the - * requested class
  • - *
  • Selection elements are assumed to be either instances of - * IHintContext, IAdaptable or direct instances of the requested class
  • - *
  • If an IHintContext is found, the result object is searched within it - * with the specified key.
  • - *
  • Searching involves testing whether the hint value is an instance of - * clazz or adaptable to it through {@link IAdaptable}.
  • - *
- * - * - * - * @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, null is returned - */ - @SuppressWarnings("unchecked") - public static T getSinglePossibleKey(Object object, Key key, Class 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: - *
    - *
  • Supported input selection objects: IStructuredSelection and - * Collection<?>, IHintContext, IAdaptable, direct instances of the - * requested class
  • - *
  • Selection elements are assumed to be either instances of - * IHintContext, IAdaptable or direct instances of the requested class
  • - *
  • If an IHintContext is found, the result object is searched within it - * with the specified key.
  • - *
  • Searching involves testing whether the hint value is an instance of - * clazz or adaptable to it through {@link IAdaptable}.
  • - *
- * - * - * - * @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, null is returned - */ - @SuppressWarnings("unchecked") - public static T getSinglePossibleKey(Object object, Key key, Class 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 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: - *
    - *
  • Supported input selection objects: IStructuredSelection and - * Collection<?>
  • - *
  • Selection elements are assumed to be IHintContext instances
  • - *
  • The result objects are searched for in the IHintContexts with the - * specified key.
  • - *
  • Searching involves testing whether the hint value is an instance of - * clazz or adaptable to it through {@link IAdaptable}.
  • - *
- * - * 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 List getPossibleKeys(Object selection, Key key, Class 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 List extractPossibleKeys(Collection objects, Key key, Class clazz) { - if (objects.isEmpty()) - return Collections.emptyList(); - - ArrayList result = new ArrayList(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 List extractPossibleKeys(Object[] objects, Key key, Class clazz) { - if (objects.length==0) - return Collections.emptyList(); - - ArrayList result = new ArrayList(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 o3 = new Long(1); - - ISelection s1 = createSelection(o1, o2, o3); - - List f1 = convertSelection(s1); - List 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)); - } - -} +/******************************************************************************* + * 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 { + + /** + * 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 type of interest + * @param sel selection + * @return list + * @throws ClassCastException if the selection contains elements not + * instance of T + */ + @SuppressWarnings("unchecked") + public static List convertSelection(ISelection sel) throws ClassCastException + { + if (sel == null || sel.isEmpty() || (!(sel instanceof IStructuredSelection))) + return Collections.emptyList(); + + List result = new ArrayList(); + //Class tClass = (Class)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 type of interest + * @param sel selection + * @return set + * @throws ClassCastException if the selection contains elements not + * instance of T + */ + @SuppressWarnings("unchecked") + public static Set convertSetSelection(ISelection sel) throws ClassCastException + { + if (sel.isEmpty() || (!(sel instanceof IStructuredSelection))) + return Collections.emptySet(); + + Set result = new HashSet(); + //Class tClass = (Class)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 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 type of interest + * @param sel selection + * @return list + */ + @SuppressWarnings("unchecked") + public static List filterSelection(ISelection sel, Class assignableFrom) + { + if (sel == null || sel.isEmpty() || (!(sel instanceof IStructuredSelection))) + return Collections.emptyList(); + + List result = new ArrayList(); + 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 type of interest + * @param sel selection + * @return all instances of T in sel + */ + public static Set filterSetSelection(Object sel, Class assignableFrom) + { + if (sel instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) sel; + if (!ss.isEmpty()) + return filterCollection(ss.toList(), assignableFrom, new HashSet()); + } else if (sel instanceof Collection) { + Collection c = (Collection) sel; + if (!c.isEmpty()) + return filterCollection(c, assignableFrom, new HashSet()); + } + + return Collections.emptySet(); + } + + @SuppressWarnings("unchecked") + public static T filterSingleSelection(Object sel, Class 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 findFirstAdaptable(Object sel, Class 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 findFirstAdaptable_(Collection objects, Class assignableTo) { + for (Object o : objects) { + T t = tryAdapt(o, assignableTo); + if (t != null) + return t; + } + return null; + } + + private static > C filterCollection(Collection objects, Class 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 tryAdapt(Object o, Class 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: + *
    + *
  • Supported input selection objects: IStructuredSelection and + * Collection<?>, IHintContext, IAdaptable, direct instances of the + * requested class
  • + *
  • Selection elements are assumed to be either instances of + * IHintContext, IAdaptable or direct instances of the requested class
  • + *
  • If an IHintContext is found, the result object is searched within it + * with the specified key.
  • + *
  • Searching involves testing whether the hint value is an instance of + * clazz or adaptable to it through {@link IAdaptable}.
  • + *
+ * + * + * + * @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, null is returned + */ + @SuppressWarnings("unchecked") + public static T getSinglePossibleKey(Object object, Key key, Class 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: + *
    + *
  • Supported input selection objects: IStructuredSelection and + * Collection<?>, IHintContext, IAdaptable, direct instances of the + * requested class
  • + *
  • Selection elements are assumed to be either instances of + * IHintContext, IAdaptable or direct instances of the requested class
  • + *
  • If an IHintContext is found, the result object is searched within it + * with the specified key.
  • + *
  • Searching involves testing whether the hint value is an instance of + * clazz or adaptable to it through {@link IAdaptable}.
  • + *
+ * + * + * + * @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, null is returned + */ + @SuppressWarnings("unchecked") + public static T getSinglePossibleKey(Object object, Key key, Class 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 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: + *
    + *
  • Supported input selection objects: IStructuredSelection and + * Collection<?>
  • + *
  • Selection elements are assumed to be IHintContext instances
  • + *
  • The result objects are searched for in the IHintContexts with the + * specified key.
  • + *
  • Searching involves testing whether the hint value is an instance of + * clazz or adaptable to it through {@link IAdaptable}.
  • + *
+ * + * 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 List getPossibleKeys(Object selection, Key key, Class 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 List extractPossibleKeys(Collection objects, Key key, Class clazz) { + if (objects.isEmpty()) + return Collections.emptyList(); + + ArrayList result = new ArrayList(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 List extractPossibleKeys(Object[] objects, Key key, Class clazz) { + if (objects.length==0) + return Collections.emptyList(); + + ArrayList result = new ArrayList(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 o3 = new Long(1); + + ISelection s1 = createSelection(o1, o2, o3); + + List f1 = convertSelection(s1); + List 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)); + } + +}