Some basics about extension points
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.
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
Extension point: com.ibm.commons.Extension
This extension point is similar to
java.util.ServiceLoader. Each service has to specify a
type and a
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
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
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:
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.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.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
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:
Some service-types that are loaded with findApplicationServices:
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.RequestParameters=> has to implenent RequestCustomizerFactory, may filter RequestParameters