How to design your own extension-point for Eclipse
来源:互联网 发布:拳皇mugen软件 编辑:程序博客网 时间:2024/05/17 01:48
Eclipse allow you to extend its functionalities by implementing its extension-point. We often write a Eclipse plugin which implement some of Eclipse's existing extension-points, e.g. if we want to contribute a popup menu for Eclipse, we need implement org.eclipse.ui.popupMenus extension-point, and follow the org.eclipse.ui.popupMenus's API contract which defined by org.eclipse.ui.popupMenus extension-point schema, then Eclipse will do things as we wish.
So what happened here? Why Eclipse know how to process your popup menu contribution? How to add a pretty new functionality to Eclipse, which can't find or defined by Eclipse's existing extension-point?The answer is: contribute a extension-point for Eclipse by yourself.
Here I will use a example to explain how to define a extension-point by yourself, suppose I want to write a view that will show services status which deploy in a container like tomcat, spring, websphere etc., and customer can add any unknown containers support by implement my new extension-point for this view.
1. The requirements
I want to get service from container, also I need support unknown container type, so a client will be needed, i.e. I can user that client to get what I want to show in my view. So here I will define a client extension-point and this client will follow the interface contract below:
The three methods at beginning will set connection information for client and create a client instance, then listServices() will get service back
2. Define client extension-point
You can use PDE extension-point schema editor do this, here's my client schema:
3. Extension-point handle classes
When my view need get services status back, I need load all contributed extension, and instance client which know how to get service status back, here's code:
4. A example client extension
5. Use client extension
In the view code:
6. Summary
So write a extension-point is not so hard? It's pretty easy actually! Could you imagine all the powerful functionalities of Eclipse are based on this extension mechanism?
- ClientsEntry, ClientsRegistry can be reused, they are similar with code in Eclipse itself that process extension-point
- the most important thing is design your extension-point API contract and select a suitable opportunity to load your extension, apply lazy loading when possible
So what happened here? Why Eclipse know how to process your popup menu contribution? How to add a pretty new functionality to Eclipse, which can't find or defined by Eclipse's existing extension-point?The answer is: contribute a extension-point for Eclipse by yourself.
Here I will use a example to explain how to define a extension-point by yourself, suppose I want to write a view that will show services status which deploy in a container like tomcat, spring, websphere etc., and customer can add any unknown containers support by implement my new extension-point for this view.
1. The requirements
I want to get service from container, also I need support unknown container type, so a client will be needed, i.e. I can user that client to get what I want to show in my view. So here I will define a client extension-point and this client will follow the interface contract below:
public interface IClient { public void setHost(String host); public void setPort(int port); public void createClient(); public List<IService> listServices(); }
The three methods at beginning will set connection information for client and create a client instance, then listServices() will get service back
2. Define client extension-point
You can use PDE extension-point schema editor do this, here's my client schema:
<?xml version='1.0' encoding='UTF-8'?><!-- Schema file written by PDE --><schema targetNamespace="com.example.services"><annotation> <appInfo> <meta.schema plugin="com.example.services" id="clients" name="Clients"/> </appInfo> <documentation> this extension-point will be used to connect different container </documentation> </annotation> <element name="extension"> <complexType> <sequence minOccurs="1" maxOccurs="unbounded"> <element ref="client"/> </sequence> <attribute name="point" type="string" use="required"> <annotation> <documentation> </documentation> </annotation> </attribute> <attribute name="id" type="string"> <annotation> <documentation> </documentation> </annotation> </attribute> <attribute name="name" type="string"> <annotation> <documentation> </documentation> <appInfo> <meta.attribute translatable="true"/> </appInfo> </annotation> </attribute> </complexType> </element> <element name="client"> <complexType> <attribute name="id" type="string" use="required"> <annotation> <documentation> </documentation> </annotation> </attribute> <attribute name="name" type="string" use="required"> <annotation> <documentation> </documentation> </annotation> </attribute> <attribute name="clientType" type="string" use="required"> <annotation> <documentation> </documentation> </annotation> </attribute> <attribute name="class" type="string" use="required"> <annotation> <documentation> </documentation> <appInfo> <meta.attribute kind="java" basedOn="com.example.services.client.IClient"/> </appInfo> </annotation> </attribute> </complexType> </element> <annotation> <appInfo> <meta.section type="since"/> </appInfo> <documentation> 2007/09 </documentation> </annotation> <annotation> <appInfo> <meta.section type="examples"/> </appInfo> <documentation> <pre><extension point="com.example.services.clients"> <client class="com.example.services.TomcatClient" clientType="tomcat" id="com.example.services.TomcatClient" name="Tomcat Client"/></extension></pre> </documentation> </annotation> <annotation> <appInfo> <meta.section type="apiInfo"/> </appInfo> <documentation> extension of this extension-point must implement <samp>com.example.services.client.IClient</samp> </documentation> </annotation> <annotation> <appInfo> <meta.section type="implementation"/> </appInfo> <documentation> see com.example.services plugin for a implementation example </documentation> </annotation> <annotation> <appInfo> <meta.section type="copyright"/> </appInfo> <documentation> alexgreenbar </documentation> </annotation></schema>
3. Extension-point handle classes
When my view need get services status back, I need load all contributed extension, and instance client which know how to get service status back, here's code:
//describe every client contributionpublic class ClientsEntry { private final static String ATTR_TYPE = "clientType"; private final static String ATTR_CLAZZ = "class"; private IConfigurationElement element; private String type; public ClientsEntry(IConfigurationElement aElement) { element = aElement; type = element.getAttribute(ATTR_TYPE); } public String getType() { return type; } public IClient createClient() throws CoreException { return (IClient)element.createExecutableExtension(ATTR_CLAZZ); }}
//ClientsRegistry manage all client contribution, use singleton patternpublic class ClientsRegistry { private final static Logger LOG = Logger.getLogger(ClientsRegistry.class.getName()); private final static String EXTENSION_POINT_ID = "com.example.services.clients"; private final static ClientsRegistry INSTANCE = new ClientsRegistry(); private List<ClientsEntry> entries = new ArrayList<ClientsEntry>(); private ClientsRegistry() { // } public static ClientsRegistry getInstance() { return INSTANCE; } private void load(){ entries.clear(); IExtensionRegistry registry = Platform.getExtensionRegistry(); IExtensionPoint point = registry.getExtensionPoint(EXTENSION_POINT_ID); for (IExtension extension : point.getExtensions()){ for (IConfigurationElement element : extension.getConfigurationElements()){ entries.add(new ClientsEntry(element)); } } } public List<ClientsEntry> getEntries() { load(); return entries; } public IClient getClient(String type) { IClient client = null; load(); for (ClientsEntry entry : entries) { if (entry.getType().equalsIgnoreCase(type)) { try { client = entry.createClient(); } catch (CoreException e) { LOG.log(Level.FINE, "can't instance client extension: ", e); client = null; continue; } break; } } return client; }}
4. A example client extension
<extension point="com.example.services.clients"> <client class="com.example.services.TomcatClient" clientType="tomcat" id="com.example.services.TomcatClient" name="Tomcat Client"/></extension>
5. Use client extension
In the view code:
String newClientType = "tomcat"IClient client = ClientRegistry.getInstance().getClient(newClientType);client.setHost("localhost");client.setPort(8080);client.createClient();List<IService> allServices = client.listServices();
6. Summary
So write a extension-point is not so hard? It's pretty easy actually! Could you imagine all the powerful functionalities of Eclipse are based on this extension mechanism?
- ClientsEntry, ClientsRegistry can be reused, they are similar with code in Eclipse itself that process extension-point
- the most important thing is design your extension-point API contract and select a suitable opportunity to load your extension, apply lazy loading when possible
- How to design your own extension-point for Eclipse
- How to write your own custom Form
- How to make your own VST host
- How To Create Your Own Smarty Function
- How to make your own maps/tiles
- How to develop your own Boot Loader
- How to learn on your own
- How to install your own zImage
- How to set trace for others sessions, for your own session and at instance level
- How to design your model
- SAP CRM How to Create your own BOL Object for webclient
- How to Build Your Own Rogue GSM BTS for Fun and Profit
- How to play XM Music From your own code
- How to create your own ListBox in C#
- Hack Attacks Testing: How to Conduct Your Own Security Audit
- How To Build Your Own IPTV-VoD System
- How to insert your own activity after Setup Wizard finishes
- How to Set Up Your Own Home Seedbox (in Windows)
- A good introduction for RCP and Create it quickly
- Unit test help me find bug in class today
- A simple sample show generic interface usage
- Is this a good/right way to use generic interface?
- jquery attr和name的应用
- How to design your own extension-point for Eclipse
- See out Friends, so long...
- We lost Beijing team kudos
- Model is king: EMF will play a main role in Eclipse
- Four years in IONA
- NSDictionary 使用总结
- A good article on Eclipse Job
- A simple program reveal thread synchronization
- Lesson: use *.tar.gz but *.zip under Unix