# JabRef Plugin System

Starting with version 2.4, JabRef can be extended using a plugin system which was built using Java Plugin Framework (JPF).

To use a plugin, it needs to be put in one of the directories where JabRef looks for plugins. One such directory is the one called `plugins` below the directory where the JabRef jar file is located. Another is the user plugin directory, `~/.jabref/plugins` under Linux or OS X and `.jabref/plugins` under your user home directory under Windows.

The simplest way of installing plugins is through the Plugin manager, accessed from the Plugins menu. The plugin manager lists all plugins installed in your user plugin directory, and allows you to both delete installed plugins and install new ones.

## How to write a plugin

JabRef offers the following extension-points for developers:

- `ImportFormat` - Add importers to JabRef accessible from the 'Import into ... database'.
- `EntryFetcher` - Add access to databases like Citeseer or Medline to the Web Search menu.
- `ExportFormatTemplate` - Add a template based export like the ones accessible using the Manage Custom Exports.
- `ExportFormat` - Add an export filter to JabRef's export dialog, that is more complicated than the simple template based one.
- `ExportFormatProvider` - A more powerful way to add export formats to JabRef.
- `LayoutFormatter` - Add formatters that can be used in the layout based exporters.
- `SidePanePlugin` - Add a side pane component that can do any kinds of operations. The panel is accessed from a Plugins menu in JabRef's main window.

These extension-points are defined in the `plugin.xml` of the JabRef-core-plugin, which can be found in `JabRef/src/plugins/net.sf.jabref.core/`.

To start developing follow these rough steps:

1. Checkout the JabRef trunk from subversion (`https://jabref.svn.sourceforge.net/svnroot/jabref/trunk`). This contains both JabRef itself and plug-ins contributed so far to JabRef (you don't need the htdocs folder), which make great starting points for your own plugins.
2. Compile JabRef using `ant jars`.
3. Create your own project and define your extension in your own plugin.xml that satisfy the extension points of the core plugin.xml. In particular make sure that:
   - ...your plugin.xml has a `requires`-section that imports the core plugin (`net.sf.jabref.core`).
   - ...your plugin.xml has a `runtime`-section, where you tell JPF, where in your project you have stored your class files and resources.
4. Create a jar of your project and put it into the `plugins`-folder of JabRef.
5. Your plugin should be loaded when you run JabRef from the jar.

Feel free to ask us questions related to the plugin system on the mailing-list!

## How to add an extension point to JabRef

This documentation is intended for JabRef developers who want to add further extensions points.

To add a new extension-point, you need to declare this extension-point in the plugin.xml of the core plugin similar to this:

    <extension-point id="PushToApplication">
    	<parameter-def type="string" id="pushToApp"
    		custom-data="<classname of the interface that plugin providers need to implement>" />
    	<!-- optionally other parameters (we currently do not use any of these for anything)
    		<parameter-def type="string" id="name" />
    		<parameter-def type="string" id="description"
    			multiplicity="none-or-one" />
    			-->
    </extension-point>

Then you need to re-run the plugin code generator "`ant generate`", which will re-create the helper class in "`net.sf.jabref.plugin.core.generated`" so that it includes a method `getPushToApplicationExtensions()` which returns a list of all PushToTalk extensions registered with the system.

This list then can be used like this (here an example what we do with the entry fetcher extensions):

    /*
     * Load fetchers that are plug-in extensions
     */
    JabRefPlugin jabrefPlugin = JabRefPlugin.getInstance(PluginCore.getManager());
    if (jabrefPlugin != null){
    	for (EntryFetcherExtension ext : jabrefPlugin.getEntryFetcherExtensions()){
    		EntryFetcher fetcher = ext.getEntryFetcher();
    		if (fetcher != null){
    			fetchers.add(fetcher);
    		}
    	}
    }

    // and later...

    for (EntryFetcher fetcher : fetchers){
      GeneralFetcher generalFetcher = new GeneralFetcher(sidePaneManager, this, fetcher);
      web.add(generalFetcher.getAction());
      fetcherActions.add(generalFetcher.getAction());
    }