Skip to content

Some basics about extension points

Roland Praml edited this page May 2, 2014 · 2 revisions

Basics

Every plugin can define its own extension points (a schema.xsd can be created that specify the extension point properties). Other plugins can contribute an extension to an extension point.

To get an extension point, you must query the extension registry.
Example:

IExtensionRegistry registry= Platform.getExtensionRegistry();  
IConfigurationElement[] arr= 
    registry.getConfigurationElementsFor("com.ibm.commons.Extension");

Now you have an array of IConfigurationElements. The element contains the XML data that are defined in the plugin.xml (in a format specified by a schema.xsd of the extension point). See here for more details.
Reading data from the registry does not yet activate the plugin.

The most important extension points in XPages are com.ibm.commons.Extension and com.ibm.commons.ExtensionBundle. They are handled by the com.ibm.commons.extension.ExtensionManager class.

Extension point: com.ibm.commons.Extension

This extension point is similar to java.util.ServiceLoader. Each service has to specify a type and a class. Compared to the ServiceLoader, the type corresponds to the file name in "META-INF/services" and the classname to the content of this file. A plugin will get activated, if it defines a service-type that was queried from the extension manager.

Extension point: com.ibm.commons.ExtensionBundle

This extension point defines a bundle of estensions. It has to specify a class, that implements com.ibm.commons.extension.OSGiExtensionService. This Interface has one method (getBundle) and must return the current bundle. If the extension manager was queried for a service-type, the classes are then loaded by using "META-INF/services" files in the plugin.

Compared to the com.ibm.commons.Extension point, this extension point must activate the plugin, otherwise the files in META-INF/services are not accessible for the class loader. This could be also used as "AutoStart" for a plugin :) and maybe fix the issue described here: http://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html

The ExtensionManager

The com.ibm.commons.extension.ExtensionManager has two different modes. If it runs inside an OSGI environment, it tries to locate services definde by the the two extension points.
As fallback it uses the definitons in the "META-INF/services" files that are visible by the current class loader. (This could be also a META-INF-file stored in the current NSF-file if findApplicationService was used.)

There are two different ways to load a service:

ExtensionManager.findServices

Does NOT load services specified in the NSF. This is for services that should only be extended by plugins and not in an NSF.

Some service-types that are loaded with findServices:

  • com.ibm.commons.platform.Factory => has to implement IPlatformFactory and creates a new platform (makes no sense to override)
  • com.ibm.xsp.adapter.serviceFactory => has to implement IServiceFactory and can create own HTTP-service handlers for example. (This service is loaded at server start)
  • com.ibm.xsp.runtime.resources => has to implement ResourceFactoryProvider / TODO
  • com.ibm.domino.oauth.service => has to implement OAuthService / TODO
  • com.ibm.designer.runtime.extensions.RuntimeInitializationEvent => TODO
  • com.ibm.designer.runtime.extensions.JavaScriptProvider => TODO
  • com.ibm.xsp.renderkit.ContentTypeRenderer => TODO
  • com.ibm.xsp.DefaultPropertyProvider => has to implement IDefaultPropertyProvider and can override default properties on the server
  • com.ibm.xsp.context.DojoLibraryFactory => has to implement DojoLibraryFactory, can add dojo components
  • com.ibm.xsp.Library => a XPage-Lib (selectable in NSF)
  • com.ibm.xsp.library.Contributor => a XspContributor. Can control certain factories, like "com.ibm.xsp.DESIGNER_IMPLICITOBJECTS_FACTORY" (could be useful)
  • com.ibm.xsp.minifier.loader => a ResourceLoader (for minified css/js resources)
  • com.ibm.xsp.model.domino.ViewNavigatorFactory => a Factory for ViewNavigators (already uses in the openntf-plugin)
  • com.ibm.xsp.resource.DojoModulePathResource => has to implement DojoModulePathResource / TODO
  • com.ibm.xsp.stylekit.ThemeExtension => TODO
  • com.ibm.xsp.SerializableAdapter => adapter to extend FacesUtil. Used for example to serialize Notes DateTimes.
  • com.ibm.xsp.GlobalResourceProvider => implements FacesResourceServlet. Global resources, accessable via /xsp/.ibmxspres/
  • com.ibm.xsp.LocalResourceProvider => same, but per NSF

ExtensionManager.findApplicationServices

First look in the NSF for a "META-INF/services" file (if correct ModuleClassLoader was specified), then do the same as findServices

This should NOT be called directly, better use findServices in the Application-class. e.g: ((ApplicationEx)ctx.getApplication()).findServices(serviceType)

Some service-types that are loaded with findApplicationServices:

  • com.ibm.xsp.adapter.servletFactory
  • com.ibm.xsp.core.events.ApplicationListener => has to implenent ApplicationListener/ApplicationListener2, will be notified about applicationCreated / Destroyed / Refreshed
  • com.ibm.xsp.core.events.SessionListener => has to implenent SessionListener, will be notified about sessionCreated / Destroyed (could be useful to log the open HTTP sessions)
  • com.ibm.xsp.JavaScriptLibFactory
  • com.ibm.xsp.stylekit.StyleKitFactory
  • com.ibm.xsp.acf.HtmlFilteringFactory
  • com.ibm.xsp.RequestParameters => has to implenent RequestCustomizerFactory, may filter RequestParameters