3. Plugin System

You are viewing an old version (v. 5) of this page.
The latest version is v. 23, last edited on Jan 17, 2010 (view differences | )
<< View previous version | view page history | view next version >>
  • Plugin Main Class

Each plugin has a main class (Refer to [QBTEAM:Write a Simple Plugin] for steps of how to create plugin main class) which should be extend the class AbstractPlugin. Plugin extensions and settings are defined by overriding appropriate methods of the AbstractPlugin class.

  • Plugin Dependency

Each plugin will depend on the QuickBuild framework, ie. the bundle with ID com.pmease.quickbuild, and it can depend on other plugins if you want to extend extension point (see below) defined in those plugins. Refer to [QBTEAM:Write a Simple Plugin] for how to declare plugin dependencies.

  • Extension Point and Extension

Extension point is the point of extension in QuickBuild, and it must be defined as interface or abstract class. The QuickBuild framework is defined a set of extension points existing in package com.pmease.quickbuild.extensionpoint. Each QuickBuild plugin can define their own extension points if it wants other plugins to extend the plugin's functionality. Extension is an implementation of a certain extension point, and it is defined in a plugin. A plugin can have one or more extensions. Taking the artifact plugin (this plugin extends the system with the ability to publish and display artifacts) for example, the extensions are defined as follows:

public class MyPlugin extends AbstractPlugin {
    ...
    public Object[] getExtensions() {
        return new Object[] {
	    new PublishStepTypeProvider() {

                public Class<? extends PublishStep> getPublishStepTypeClass() {
		    return ArtifactPublishStep.class;
                }

            },
            new BuildTab() {

                public String getTitle() {
                    return "Artifacts";
                }

                public boolean isApplicable(Build build) {
                    return new File(build.getDir(), ARTIFACTS_DIR).exists();
                }

                public BuildPanel getPanel(String panelId, Build build) {
                    return new ArtifactPanel(panelId, build);
                }
            }

    }
    ...
}

We have defined two extensions, one extends the extension point PublishStepTypeProvider, and the other extends the extension point BuildTab.
For those plugins who define their own extension point, the code used to get all extensions for a particular extension point is as follows:

Quickbuild.getInstance(PluginManager.class).getExtensions(<extension point class>)

The returned extension collection might be contributed from multiple plugins.

  • Plugin Setting

Plugin might have settings, for example, Ant plugin has a setting defining a path to Ant executable. There are four types of plugin setting:

    • Global plugin setting
    • User level plugin setting
    • Group level plugin setting
    • Configuration level plugin setting
  1. Global plugin setting
    Gobal plugin setting can be specified by overriding method getPluginSettingClass in the plugin class as follows:
    public class MyPlugin extends AbstractPlugin {
        ...
        Class<?> getPluginSettingClass() {
            return MyPluginSetting.class;
        }
        ...
    }
    

    The class MyPluginSetting should be provided by plugin developer, for example:

    public class MyPluginSetting {
        private String property1;
        private String property2;
    
        @Editable(order=100)
        public String getProperty1 {
            return property1;
        }
        public void setProperty1(String property1) {
            this.property1 = property1;
        }
    
        @Editable(order=200)
        public String getProperty2 {
            return property2;
        }
        public void setProperty2(String property2) {
            this.property2 = property2;
        }
    }
    

    With property annotations, QuickBuild will generate the user interface to edit and save setting for this plugin. Refer to Bean Editor for details about how to use annotation to define the setting's user interface.
    The defined plugin setting object can be retrieved by using following code:

    MyPluginSetting myPluginSetting = (MyPluginSetting)PluginSettingHelper.getPluginSetting(MyPlugin.class);
    
  2. User level plugin setting
    User level plugin setting can be specified by overriding method getPluginUserSettingClass in the plugin class. Let's take the MSN Notifier plugin as example:
    public class MsnPlugin extends AbstractPlugin {
        ...
        Class<?> getPluginUserSettingClass() {
            Return MsnUserSetting.class;
        }
        ...
    }
    

    And the MsnUserSetting class is defined as follows:

    public class MsnUserSetting {
        private String msnAccount;
    
        @Editable(order=100)
        @Email
        @NotEmpty
        public String getMsnAccount() {
            return msnAccount;
        }
    
        public void setMsnAccount(String msnAccount) {
            this.msnAccount = msnAccount;
        }
    }
    

    This setting adds an attribute "msnAccount" to each user's user interface when a user is edited and displayed:

    For a particular user, this attribute can be retrieved as follows:

    UserSetting userSetting = (UserSetting)PluginSettingHelper.getPluginSetting(MsnPlugin.class, user);
    String msnAccount = userSetting.getMsnAccount();
    
  3. Group level plugin setting
    Group level plugin setting is very similar to user level plugin setting, except that:
    • Group setting is attached to each group and will be displayed and edited if you view or edit particular group.
    • The setting class is specified by overriding method getPluginGroupSettingClass
    • The setting object can be retrieved by calling PluginSettingHelper.getPluginSetting(<Plugin Main Class>, <group instance>)
  4. Configuration level plugin setting
    Configuration level plugin setting is very similar to user level plugin setting, except that:
    • Configuration setting is attached to each configuration and will be displayed and edited if you view or edit particular configuration
    • The setting class is specified by overriding method getPluginConfigurationSettingClass
    • The setting object can be retrieved by calling PluginSettingHelper.getPluginSetting(<Plugin Main Class>, <configuration instance>)
  5. Plugin setting migration
    Refer to [QBTEAM:Bean Migrator] for how to migrate plugin settings between different plugin versions.
  • Plugin Data Storage

Besides plugin setting, plugins might need to generate and save data on the fly when the plugin runs, and use the data later. There are two types of plugin data storage: build storage, and configuration storage.

  1. Build storage
    Build storage is used by plugin to store data related to specific build. It is simply a sub directory under the build directory of the server node (refer to glossary chapter in User's Guide for build directory definition). If the build is deleted, its companion build storage will also be deleted. Plugin developer should choose the sub directory name carefully to avoid conflict with other plugins.
    A typical usage of build storage is the artifact plugin: when publishing artifacts for a particular build, the artifact plugin creates a directory named artifacts under the build directory on the server node, and it will copy the specified files into this directory. The plugin will also add a tab to this build, and display these artifacts so they can be selected for download.
  2. Configuration storage
    Configuration storage is used by plugin to store data related to specific configuration, it is simply a sub directory under the configuration directory of server node (refer to glossary chapter in User's Guide for configuration directory definition). If the configuration is deleted, its companion configuration storage will also be deleted. Plugin developer should choose the sub directory name carefully to avoid conflict with other plugins.
    A typical usage of configuration storage is the build statistics plugin: when a build is finished, the statistics plugin collect build metrics, it processes them and it saves the processed results into a sub directory named build-stats under the corresponding configuration directory on server node. It will also add a tab to the configuration statistics page, and display the build statistics charts using the pre-processed data saved in the build-stats directory.
    Please note that it is also possible that a single plugin can use both build and configuration storage. For example, the junit report plugin generates two types of reports: the junit report for specific build, and the junit statistics report for a particular configuration. Data corresponding to build related report are stored in the build storage, and data corresponding to configuration related reports are stored in the configuration storage.
  3. Plugin data migration
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.