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?
A direct cast and/or instanceof
check
if(a instanceof B) {
B b = (B)a;
// ...
}
Conversion through IAdaptable.getAdapter
// assuming A implements/extends IAdaptable
B b = (B)a.getAdapter(B.class);
if(b != null) {
// ...
}
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) {
// ...
}
Conversion through IAdapterManager
B b = (B)Platform.getAdapterManager().getAdapter(a, B.class);
if(b != null) {
// ...
}
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.