Search code examples
javaeclipseeclipse-plugin

When to use IAdaptable?


Given an object of type A, and a desire to convert it to type B if possible, when is it appropriate to use each of the following?

  1. A direct cast and/or instanceof check

    if(a instanceof B) {
        B b = (B)a;
        // ...
    }
    
  2. Conversion through IAdaptable.getAdapter

    // assuming A implements/extends IAdaptable
    B b = (B)a.getAdapter(B.class);
    if(b != null) {
        // ...
    }
    
  3. Conversion through IAdaptable when A cannot be implicitly converted to `IAdaptable

    B b = (a instanceof IAdaptable ? (B)((IAdaptable)a).getAdapter(B.class) : a instanceof B ? (B)a : null);
    if(b != null) {
        // ...
    }
    
  4. Conversion through IAdapterManager

    B b = (B)Platform.getAdapterManager().getAdapter(a, B.class);
    if(b != null) {
        // ...
    }
    

Solution

  • This is very difficult to give general rules for.

    When you get something like the current selection from an Eclipse project view the object is a user interface rather than the underlying object (such as a project or file). instanceof will not work.

    The conversion from a user interface object to the underlying object is often done using an IAdapterFactory which specifies a separate factory class that does the conversion. In this case you must use Platform.getAdapterManager().getAdapter.

    When an object implements IAdaptable you have to look at the documentation or source code to see which classes it supports adapting too.

    I don't think case 3 ever occurs.

    I often use this code which copes with most things:

    public final class AdapterUtil
    {
      /**
       * Get adapter for an object.
       * This version checks first if the object is already the correct type.
       * Next it checks the object is adaptable (not done by the Platform adapter manager).
       * Finally the Platform adapter manager is called.
       *
       * @param adaptableObject Object to examine
       * @param adapterType Adapter type class
       * @return The adapted object or <code>null</code>
       */
      public static <AdapterType> AdapterType adapt(Object adaptableObject, Class<AdapterType> adapterType)
      {  
        // Is the object the desired type?
    
        if (adapterType.isInstance(adaptableObject))
          return adapterType.cast(adaptableObject);
    
        // Does object adapt to the type?
    
        if (adaptableObject instanceof IAdaptable)
         {
           AdapterType result = adapterType.cast(((IAdaptable)adaptableObject).getAdapter(adapterType));
           if (result != null)
             return result;
         }
    
        // Try the platform adapter manager
    
        return adapterType.cast(Platform.getAdapterManager().getAdapter(adaptableObject, adapterType));
      }
    }
    

    Note: More recent versions of Eclipse have an org.eclipse.core.runtime.Adapters class which has a similar adapt method.