NetBeans Version Control Systems API (VCS API)
VCS API concentrates on integration of Versioning Systems into Netbeans IDE. It provides what is necessary to build a full-featured, fully integrated versioning module. The API touches three areas: filesystem integration, annotations (coloring) and menu actions.
One way to start a new versioning system plug-in module is to get an already existing versioning module and modify and extend it to your needs. The modules are located in netbeans mercurial repository - http://hg.netbeans.org/main. Currently available modules are:
- Clearcase in the clearcase folder
- Mercurial in the mercurial folder
- Subversion in the subversion folder
- Git in the git folder
- CVS in the versioning.system.cvss folder
The command to clone the NetBeans repository is $hg clone http://hg.netbeans.org/main
An alternative way to start would be to follow the VCS Cookbook and implement your plugin from scratch.
Basics and registration
Every versioning system extends the VersioningSystem abstract class and implements the getDisplayName() method. All other things are optional. To register itself with the Versioning manager, it puts a reference to itself in the META-INF/services folder. See a template module for examples.
Points of Integration
Coexistence of Multiple Versioning Systems
VCS API is designed to handle multiple versioning systems simultaneously. The API defines the concept of a Versioning Owner. Every file has one or no Owner. The Versioning Owner is a versioning system that manages the file. To take ownership of files, a versioning system implements the VersioningSystem.getTopmostManagedAncestor() method. Once an owner of a file or folder, the versioning system is then asked to annotate the file's name, provide actions for it and handle filesystems events on it (see below).
Running a Versioning Command
If you want to run a command in response to user action, you first need to create an Action, implement VCSAnnotator class to return that action and run your versioning command once the action is invoked by the user (see the following paragraph for more details) If you want to run a command when some file is created/deleted/changed in the IDE, implement the VCSInterceptor class and run the command in response to such event. See the Filesystem interceptor chapter for more details.
Main Menu and Popup menu
To place an action into the main Versioning menu, a versioning system implements the VCSAnnotator abstract class and returns set of desired actions from the getActions() method. For more detailed information about the topic please see VCSAnnotator javadoc or the template VCS module.
The same applies to popup menus. Destination (main/popup menu) for returned actions is specified as a parameter to the getActions() method.
To annotate labels (change their text and color) in the IDE, a versioning system implements the VCSAnnotator abstract class and formats labels in HTML in the annotateName() method. Every file or folder label that is displayed in the IDE first asks a versioning system to annotate its name. Annotations are used to signal files' versioning status (modified, new, etc.)
To annotate icons (change their image) in the IDE, a versioning system implements the VCSAnnotator abstract class and changes the icon in the annotateIcon() method. The idea and principle is the same as annotating labels.
To provide automatic versioning in the background, versioning systems listen for events on the filesystem and take appropriate actions. For example, when a file is created on disk, a versioning systems may add it to the remote repository automatically. It can also leverage this information to annotate the file's label in green and badge its parent folders so that the user is aware that there are now some changes in the folder. To listen for filesystem events, a versioning system implements the VCSInterceptor abstract class. It is called interceptor because it is designed in a way to allow a versioning system to actually peform a file operation. For example, some versioning systems handle the MOVE operation in a special way to record the file's history (subversion). In this example case the system would implement the beforeMove() method, return true from it to signal its will to handle this operation and eventually do the move in the doMove() mehod. In short, if the versioning system implements the VCSInterceptor class, it can listen for file operations and can also decide to handle them itself. For more detailed information about the topic please see VCSInterceptor javadoc or the template VCS module.
Typical Workflow Scenarios
User invokes a versioning command from main or popup menu
When the user needs to invoke a versioning command, it opens a menu and this is what happens that concerns a versioning module:
- a request to provide menu items is sent from the IDE to the Versioning Manager
- Versioning Manager determines the operating context of requested actions (eg. currently selected files)
- Versioning Manager queries all registered versioning systems to determine the context's owner: VersioningSystem.getTopmostManagedAncestor() is called
- if all files in the context belong to just one versioning system, the owner is asked to provide menu items (actions) on the context:
VersioningSystem.getVCSAnnotator().getActions() is called
- the menu opens and user selects some menu item
- performAction() method of the selected menu item's underlying Action is called
A file is deleted in the IDE
When a user or some background module deletes a file, this is what happens that concerns a versioning module:
- before the file is actually deleted, a BeforeFileDelete event is fired from the IDE Filesystem and routed to the Versioning Manager
- Versioning Manager queries all registered versioning systems to determine the affected file's owner: VersioningSystem.getTopmostManagedAncestor() is called
- if a file has a versioning owner, the owner is queried whether it wishes to handle the operation: VersioningSystem.getVCSInterceptor().beforeDelete() is called
- if beforeDelete() returns true, VersioningSystem.getVCSInterceptor().doDelete() is called, otherwise the file is deleted by the IDE Filesystem
- VersioningSystem.getVCSInterceptor().afterDelete() is called
IDE displays a file in an Explorer view
When a file name is rendered on screen, this is what happens that concerns a versioning module:
- a request to format the name is sent from the IDE to the Versioning Manager
- Versioning Manager queries all registered versioning systems to determine the file's owner: VersioningSystem.getTopmostManagedAncestor() is called
- if a file has a versioning owner, the owner is asked to format (annotate) the file's name: VersioningSystem.getVCSAnnotator().annotateName() is called
-- Main.MarosSandor - 02 June 2007