package org.csstudio.ui.util; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import static org.csstudio.ui.util.ReflectUtil.*; /** * Utilities for using adapters, particularly against selections. * * @author Gabriele Carcassi * @author Kay Kasemir */ public class AdapterUtil { /** * Returns all class names that an object of that class can be * converted to. * * @param clazz a class * @return all the class names with registered adapterFactories */ public static String[] getAdaptableTypes(Class<?> clazz) { if (Platform.isRunning()){ // Check for adapters in platform return Platform.getAdapterManager().computeAdapterTypes(clazz); } // No types found return new String[0]; } /** * Returns the current selection converted to an array of the desired type, * or to an empty array if not possible. * * @param <T> requested type * @param selection a selection * @param clazz the desired type * @return an array of the desired type */ public static <T> T[] convert(ISelection selection, Class<T> clazz) { if (selection instanceof IStructuredSelection) { IStructuredSelection strucSelection = (IStructuredSelection) selection; @SuppressWarnings("unchecked") T[] result = (T[]) convert(strucSelection.toArray(), ReflectUtil.toArrayClass(clazz.getName())); if (result != null) return result; } @SuppressWarnings("unchecked") T[] result = (T[]) Array.newInstance(clazz, 0); return result; } /** * Adapts an object to the desired type. This method, on top of * the standard adapter facility, adds support for arrays. If any of the * arguments represents an array, it will * use object to object adaptation to create it. * * @param obj Object to adapt * @param targetClass Desired class name * @return Object that matches the <code>targetClass</code> or <code>null</code> */ public static Object convert(Object obj, String targetClass) { // If object is of the right class, do not adapt if (isInstance(obj, targetClass)) { return obj; } // If object is of the right class, but the target is an array, // return a single element array if (isArray(targetClass) && isInstance(obj, getComponentType(targetClass))) { Object[] result = (Object[]) Array.newInstance(obj.getClass(), 1); result[0] = obj; return result; } // If the object to adapt is an array, // adapt each element if (obj instanceof Object[]) { Object[] elementsToAdapt = (Object[]) obj; // If target class is not an array, and // there is only one element, adapt only that // and return it if (!isArray(targetClass)) { if (elementsToAdapt.length == 0) { return null; } else if (elementsToAdapt.length == 1) { return convert(elementsToAdapt[0], targetClass); } else { throw new IllegalArgumentException("Trying to adapt an array " + obj + " to a single object of type " + targetClass); } } // Target class is an array List<Object> adaptedElements = new ArrayList<Object>(); String adaptedElementType = getComponentType(targetClass); Object[] savedArrayToGetType = null; for (Object element : elementsToAdapt) { // Try to use the conversion to array first Object[] newAdaptedElements = (Object[]) convert(element, targetClass); if (newAdaptedElements != null) { adaptedElements.addAll(Arrays.asList(newAdaptedElements)); savedArrayToGetType = newAdaptedElements; } else { // If no conversion to array is found, try converting the single element Object newAdaptedElement = convert(element, adaptedElementType); if (newAdaptedElement != null) { adaptedElements.add(newAdaptedElement); } } } if (adaptedElements.size() == 0) { // We got no result (and we got no class to create // the array of the proper type). This can only mean that all the elements // where adapted to empty arrays. See if you got a saved array, // and use that. if (savedArrayToGetType != null) { return Array.newInstance(savedArrayToGetType.getClass().getComponentType(), 0); } else { return null; } } else { Object[] result = (Object[]) Array.newInstance(adaptedElements.get(0).getClass(), adaptedElements.size()); return adaptedElements.toArray(result); } } // Time to try out the registered adapterFactories to the platform if (Platform.isRunning()) { final Object adapted = Platform.getAdapterManager().loadAdapter(obj, targetClass); if (adapted != null) return adapted; } // No adapter was found. Check if target class is array, and try the single // element conversion if (isArray(targetClass)) { Object newElement = convert(obj, getComponentType(targetClass)); if (newElement != null) { Object[] result = (Object[]) Array.newInstance(newElement.getClass(), 1); result[0] = newElement; return result; } } // Really cannot adapt, sorry! return null; } }