Document directory
- Type conversion
- Scalable Interfaces
- Implement the iadaptable Interface
- Platformobject
- Adapt to existing classes
- Summary
Address: http://www.cnblogs.com/bjzhanghao/archive/2005/09/24/243312.html
Http://www.eclipsezone.com/articles/what-is-iadaptable/
Iadaptable is a very important interface in eclipse. For eclipse developers, it is just as common as exception handling and abstract classes, but it is confusing and daunting for new users. This article will explain to you what iadaptable is and what it plays in eclipse.
Type conversion
Java is a strongly typed language. That is to say, each instance corresponds to a type. There are two types: Declaration type and runtime type (also known as static type and dynamic type ). A weak type language like python is often called a non-type language. In fact, this is not the case strictly, because each instance corresponds to a runtime type, but you do not need to declare this.
Now back to Java, in order to be able to execute a class method, this method must be visible in the declared type, in other words, even if the instance is a child type at runtime, you can only execute the methods defined in the parent type.
List list = new arraylist ();
List. Add ("data"); // correct. Add is the method defined in list.
List. ensurecapacity (4); // incorrect. ensurecapacity () is defined only in arraylist.
If you must execute a specific type of method, we must first forcibly convert this instance to the correct type. For the above example, we can convert the list to arraylist (in this case, we can cast arraylist to list, which is suspected to be incorrect), because arraylist implements the list interface, you can even run the instanceof keyword to check whether the list is an arraylist instance.
Scalable Interfaces
Unfortunately, a class may not implement the interface you need, so you cannot perform forced type conversion. There are many reasons. For example, this interface is only required in a few cases, or the interface you need is in another unrelated library, or the interface is developed only after the class is available.
Then you need iadaptable. Iadaptable can be considered as a way to dynamically convert data types. Compare the following direct type conversion:
Object o = new arraylist ();
List list = (list) O;
In another way, we can do this:
Iadaptable adaptable = new arraylist (); //: The arraylist here should not be Java. util. arraylist
List list = (list) adaptable. getadapter (Java. util. List. Class );
This is the dynamic type conversion mentioned above. What we do is to convert adaptable into a list instance.
So why is it necessary to use getadapter () for direct conversion? In fact, this mechanism allows us to convert the target class to an interface that is not implemented. For example, we may want to use a hashmap as a list. Although these two classes have different properties, we can do this:
Iadaptable adaptable = new hashmap (); // Note: The hashmap here should not refer to Java. util. hashmap
List list = (list) adaptable. getadapter (Java. util. List. Class );
Implement the iadaptable Interface
Most iadaptable implementations are the superposition of some if statements. For example, if we want to implement the getadapter () method of hashmap, it may look like this:
Public class hashmap implements iadaptable {
Public object getadapter (class clazz ){
If (clazz = java. util. List. Class ){
List list = new arraylist (this. Size ());
List. addall (this. Values ());
Return list;
}
Return NULL;
}
//
}
What you do is to return an adapter (adapter, more specifically a copy), rather than directly converting the type. If the parameter type is not supported, a null value (instead of an exception) is returned, which indicates that this method has failed. Therefore, when calling this method, it should not be assumed that it always returns a non-null value.
Platformobject
Of course, if you want to add a new supported adapter type, you must edit this class. Besides, since you already know this type, why not modify the interface declaration directly? In fact, there are many reasons that you do not want to directly edit this class (for example, it is easier to maintain downward compatibility), and do not want to change its type (although hashmap is not a list, it can be converted in the past ).
Eclipse solves the above problems through the platformobject abstract class. It implements the iadaptable interface for you. The eclipse platform (Platform) provides an implementation of iadaptermanager and can use platform. getadaptermanager () is accessed. It delegates all requests (CALLS) to getadapter () to an item named iadaptermanager. You can think of it as a huge map that saves the class and adapter information, and platformobject's getadapter () method will look for this map.
Adapt to existing classes
In this way, platformobject can support the new adapter type without re-compilation, which is widely used in eclipse to support workspace extension points.
Now suppose we want to convert a list containing only string elements into an XML node. The format of this node is as follows:
<List>
<Entry> first string </entry>
<Entry> second string </entry>
<Entry> third string </entry>
</List>
Because the tostring () method may have other purposes, we cannot override the tostring () method to implement this function. Therefore, we need to associate the list with a factory class to process the adaptation requests of the XML node type. The following three steps are required to manage the factory class:
1. A node is generated by list. We wrap the conversion process with iadapterfactory:
Import Nu. XOM .*;
Public class nodelistfactory implements iadapterfactory {
/* Types that can be converted */
Private Static final class [] types = {
Node. Class,
};
Public class [] getadapterlist (){
Return types;
}
/* Function code for converting to node */
Public object getadapter (Object List, class clazz ){
If (clazz = node. Class & list instanceof list ){
Element root = new element ("list ");
Iterator it = List. iterator ();
While (it. hasnext ()){
Element item = new element ("entry ");
Item. appendchild (it. Next (). tostring ());
Root. appendchild (item );
}
Return root;
} Else {
Return NULL;
}
}
}
2. register the factory class to the adaptermanager of platform. In this way, when we want to obtain a node instance from the list instance, we will find our factory class. Registering a factory class is also simple:
Platform. getadaptermanager (). registeradapters (
New nodelistfactory (), list. Class
);
This statement associates nodelistfactory with the list type. When the adapter is requested from the list, the adaptermanager of platform finds nodelistfactory, because the node class is included in the returned results of the getadapterlist () method of the latter, therefore, it is feasible to obtain a node instance from the list instance. In eclipse, this registration step is generally completed at plugin startup, but it can also be completed through the org. Eclipse. Core. runtime. adapters extension point.
3. Get node from list. The following is the sample code:
Node getnodefrom (iadaptable list ){
Object adaptable = List. getadapter (node. Class );
If (adaptable! = NULL ){
Node node = (node) adaptable;
Return node;
}
Return NULL;
}
Summary
To sum up, to add a function to an existing class at runtime, all you need to do is define a factory class for conversion and register it with the adaptermanager of platform. This method is particularly useful in maintaining the separation of UI components and non-UI components. For example. rcpapps. rcpnews. UI and org. rcpapps. in the two plug-ins of rcpnews, The ipropertysource of the former needs to be associated with the Data Object of the latter. when the former is initialized, it registers ipropertysource to platform, when the data object is selected in the navigator, the correct attribute is displayed in the property view.
Obviously, java. util. List is not a subclass of platformobject, so if you want to compile the example mentioned here, you must create a subtype of list. Note: You can directly implement the iadaptable interface, instead of inheriting the abstract platformobject class.
Public class adaptablelist implements iadaptable, list {
Public object getadapter (class adapter ){
Return platform. getadaptermanager (). getadapter (this, adapter );
}
Private list delegate = new arraylist ();
Public int size (){
Return delegate. Size ();
}
//
}
Finally, the XML generated in the example uses the XOM class library.