浏览 3914 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-09-13
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 contribution public 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 pattern public 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 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-05-06
Good article。Thank you
I know how to develop an extension point for a plug-in. |
|
返回顶楼 | |