Jeffrey Ricker is an experienced technology development executive with 15 years of leadership in defense and the private sector. He is the principal of Jeffrey Ricker LLC, providing expertise in Eclipse, RCP and OSGi to Fortune 500 and start-up clients. Previously, he was the founder of Distributed Instruments and XML Solutions Corp. Jeffrey has posted 5 posts at DZone. You can read more from them at their website. View Full User Profile

Eclipse Adapters - A Hands-On, Hand-Holding Explanation

04.09.2008
| 30308 views |
  • submit to reddit

Adapter Factories

To enable the platform to manage the adaptations, you need to register one or more adapter factories with the platform. The registration can be a bit confusing, so I am going to be very specific.

package com.jeffricker.fruit;
import org.eclipse.core.runtime.IAdapterFactory;
import com.jeffricker.fruit.apples.IApple;
import com.jeffricker.fruit.apples.Macintosh;
import com.jeffricker.fruit.oranges.IOrange;
import com.jeffricker.fruit.oranges.Mandarin;
/**
* Converts apples to oranges
* @author Ricker
*/
public class OrangeAdapterFactory implements IAdapterFactory {
public Object getAdapter(Object adaptableObject, Class adapterType) {
if (adapterType == IOrange.class) {
if (adaptableObject instanceof Macintosh) {
return new Mandarin();
}
}
return null;
}
public Class[] getAdapterList() {
return new Class[]{ IOrange.class };
}
}

Listing 5: Apples to Oranges adapter factory 

Listing 5 shows an adapter factory that converts apples to oranges. The factory enables the behavior shown earlier in Listing 2. We will detail its behavior.

  • The adaptableObject is the object that we are starting with, the apple. The adaptableObject is always an object instance.

  • The adapterType is the object to which we are adapting, the orange. The adapterType is always a class type, not an object instance

  • The adapterType is always a class type, not an object instance. The adapter list is the list of class types to which this factory can adapt objects. In this case, it is only oranges.

We must register the adapter factory with the Eclipse platform in order for it to be useful. Listing 6 shows the registration entry from the plug-in manifest file. The extension point is org.eclipse.core.runtime.adapters. This is where I usually mess up, so pay attention. The adaptableType is what we are adapting from. In this case, it is apples. The adapter is what we are adapting to. In this case, it is oranges.

<extension
point="org.eclipse.core.runtime.adapters">
<factory
adaptableType="com.jeffricker.fruit.apples.IApple"
class="com.jeffricker.fruit.OrangeAdapterFactory">
<adapter
type="com.jeffricker.fruit.oranges.IOrange">
</adapter>
</factory>
</extension>

Listing 6: Registering the adapter factory

There can be multiple adapter entries for the factory. The adapters listed in the extension point should be the same as those provided by the getAdapterList() method in the adapter factory. If we look at the listings together and trace through the logic, the adapters start to make sense.

  1. We create an instance of the Macintosh object.

    IApple macintosh = new Macintosh();
    
  2. We request the Macintosh to adapt to an IOrange

    IOrange orange = (IOrange) macintosh.getAdapter(IOrange.class);
    
  3. The Macintosh object forwards the request to the platform

    public Object getAdapter(Class adapter){
    return Platform.getAdapterManager().getAdapter(this, adapter);
    }
    
  4. The platform finds the appropriate adapter factory through the
    registry.

    <factory
    adaptableType="com.jeffricker.fruit.apples.IApple"
    class="com.jeffricker.fruit.OrangeAdapterFactory">
    <adapter type="com.jeffricker.fruit.oranges.IOrange"/>
    </factory>
    
  5. The platform calls the factory method, passing it an instance of the
    Macintosh object and the IOrange class type.
  6. The adapter factory is creates an instance of the Mandarin object

    public Object getAdapter(Object adaptableObject, Class adapterType) {
    if (adapterType == IOrange.class) {
    if (adaptableObject instanceof Macintosh) {
    return new Mandarin();
    }
    }
    return null;
    }
    

The confusion arises for me with the adaptableType parameter in the extension point. We do not have that specified in the adapter factory interface. It is buried within the logic of the factory’s getAdapter() method. Its presence in the registry makes sense when you think about it.
We ask the platform to find an adapter for a Macintosh object. The factories must somehow be associated to the class hierarchy of Macintosh. In our case the factory is registered with IApples. Figure 1 shows the relation between declarations in the extension point registry and the adapter factory class.

Figure 1: Relation between factory and extension pointFigure 1: Relation between factory and extension point

Published at DZone with permission of its author, Jeffrey Ricker.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)