cornercorner
FeaturesPluginsDocs & SupportCommunityPartners

Jackpot Transformer Module Tutorial

This tutorial is a follow-on to the Jackpot Tutorial that demonstrates how to build a NetBeans module which adds new transformers (and queries) to Jackpot so they can be distributed to other developers. New Jackpot transformers are defined using either the Jackpot rule language or writing Query or Transformer classes in Java with the Jackpot API. Since rule files are just text files, the easiest way to distribute them is to just pass them around, be it via a web page, email or perhaps stored as a project source file. There are several problems with distributing rule files as text files or embedded text, however:

  • It places the burden of installing the rule file upon the user;
  • All descriptive information must be defined by that user, before they have any experience with the transformer;
  • You cannot add the transformer to a new or existing Query Set (a group of queries which are executed as a single command); and
  • It is harder to distribute updates to the rule file.

To avoid these issues, it is recommended that Jackpot queries be developed using NetBeans module projects. These plug-ins handle all installation details, allow you to clearly describe the query, and can be easily distributed and updated via a NetBeans Update Center.

The following topics are covered below:

This tutorial can be completed in 20 minutes.

For more information on Jackpot, see the Jackpot Project home on the NetBeans website.


Setting Up a Jackpot Module Project

Before you start writing the Jackpot transformer module, you have to make sure you have all of the necessary software and that your project is set up correctly. NetBeans provides a wizard that sets up all the basic files needed for a module.

Installing the Software

Before you begin, you need to install the following software on your computer:

  • NetBeans IDE 5.x (download)
  • Java Standard Development Kit (JDK™) version 5.0 (download) or a very recent version of Java Standard Development Kit (JDK™), Standard Edition 6 (download)
  • Jackpot Developer Module (installation instructions)

    Note:all of the Jackpot and Javac modules need to be installed globally if you are using the Jackpot API. They do not need to be installed globally if you are just developing rule files.

Creating a NetBeans Module Project

  1. Choose File > New Project. Under Categories, select NetBeans Plug-in Modules.
  2. Select Module Project. Click Next.
  3. In the Name and Location panel, type MyJackpotModule in Project Name. Change the Project Location to any directory on your computer, such as c:\mymodules. Leave the Standalone Module radio button and the Set as Main Project checkbox selected. Click Next.
  4. In the Basic Module Configuration panel, replace yourorghere in Code Name Base with myorg, so that the whole code name base is org.myorg.myfirstmodule.
  5. Click Finish. The IDE creates the MyJackpotModule project. You can view its logical structure in the Projects window (Ctrl-1):

    Initial Projects window

Adding Project Support for Transformers

These steps add project support for writing Jackpot transformer classes. If your module will just have rule file transformers, you may skip to the Adding a New Transformer section.

Update the project properties to support Jackpot transformers as follows:

  1. In the Projects window, right-click the project node and choose Properties. In the Sources panel, set the Source Level to 1.5. It is recommended that you accept the Enable Warnings dialog to turn on additional Java compiler checking, since Jackpot uses generics.
  2. Select the Libraries panel, and set the Java Platform to Java 5 or 6.
  3. Add the "Jackpot Engine", "Javac API Wrapper", and "Utilities API" to the Module Dependencies list.
  4. Select the API Versioning panel, and check the checkbox for your module's package to make it public. This is necessary so that the Jackpot engine can find your transformer(s).
  5. Click Finish to update your project's properties.

Next, create the file which declares that the module's transformers are are visible to the rest of the IDE via the Lookup service. Jackpot uses this service to find your transformer(s).

  1. Click on the Navigator Files view, then select your module's src directory.
  2. Choose File > New File. Under Categories select Other, then under File Types select Folder.
  3. Name the folder META-INF/services (note: this name is case-sensitive). Click Finish.
  4. Select the META-INF/services folder, choose File > New File. Under Categories select Other, then under File Types select Empty File.
  5. Name the file org.netbeans.jackpot.query.Query. This is the base class for all Jackpot queries and transformers, which Jackpot finds using the Lookup service. As each transformer is added to the module, an entry for it is added to this file.
  6. Your Projects window now looks like:

    Updated Projects window


Add Transformers

Add Source Files to the Project

Creating transformers is very similar to creating other extensions to NetBeans. Source files are either Jackpot rule files or Java files written to the Jackpot API and Compiler API. One additional task is to declare all transformers written in Java so the NetBeans Lookup service can find them. This is done by specifying them in a configuration file in a META-INF/services directory, and by make their packages public.

  • Copy your rule files, query and transformation classes into the module's src hierarchy, in the same manner as regular Java files and resources. For this tutorial, save this rule file AvoidDuplicateObjects.rules and this query class TreeCounter.javato the org.myorg.myjackpotmodule package.
  • -- OR --

  • Create new source files, using File > New File under the Jackpot category.
  • Your Projects window now looks like:

    Projects window with source files

Add Query Names to Services File

  • Edit the org.netbeans.jackpot.query.Query in the META-INF/services package (it is really just a source directory, but the IDE displays it as a Java package in the Projects window). Add the following line:
  • org.myorg.myjackpotmodule.TreeCounter

  • Add additional lines for any query or transformation Java classes. Note: no entry is added for rule files.

Declare Java Package as Public

  • In the Projects window, right-click the project node and choose Properties. Select the API Versioning panel.
  • Declare the Java package(s) as public by checking their box in the Public Packages list.

Adding New Jackpot Refactorings to the IDE

All Jackpot queries and transformers available to the IDE are handled by the Tools > Refactoring Manager dialog. This section shows how to make a module add new refactorings to this list.

Refactoring Manager dialog

Jackpot refactorings are created by defining system filesystem entries in the module's XML Layer. Each refactoring is a separate file in a /Jackpot/Inspections directory (inspections were the old name for queries). A Jackpot refactoring is a virtual system file which has attributes for:

  • Its associated physical or XML description file;
  • An "inspector", which is a short description of what code pattern is being searched;
  • A "transformer", which is a short description of what the code will be changed to (not specified for search-only queries); and
  • A "description", which fully describes the refactoring.

Looking at the Refactoring Manager dialog above, the "Search For" column lists all the "inspector" attributes, the "Refactoring" column lists the "transformer" attributes", and the "Description" text box displays the "description" attribute for the selected refactoring. Refactorings which are Java classes have an additional attribute, "command", which is the class name; neither the "command" attribute nor any filesystem information is displayed.

Add a Refactoring Declaration to the XML Layer

  • Edit the XML Layer file to create the /Jackpot/Inspections folder:
  • <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" 
                         "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
    <filesystem>
       <folder name="Jackpot">
          <folder name="Inspections">
          </folder>
       </folder>
    </filesystem>
  • Add an entry for the AvoidDuplicateObjects.rules transformation:
  • <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" 
                         "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
    <filesystem>
       <folder name="Jackpot">
          <folder name="Inspections">
             <file name="AvoidDuplicateObjects.rules" url="AvoidDuplicateObjects.rules">
                <attr name="inspector" stringvalue="Duplicate immutable objects"/>
                <attr name="transformer" 
                      stringvalue="Replaces with methods that share these objects"/>
                <attr name="description" 
                      stringvalue="Eliminates creating duplicate immutable objects."/>
             </file>
          </folder>
       </folder>
    </filesystem>
  • Add an entry for the TreeCounter query (note that it doesn't define a "transformer" attribute since it does not make any source file changes):
  • <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" 
                         "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
    <filesystem>
       <folder name="Jackpot">
          <folder name="Inspections">
             <file name="AvoidDuplicateObjects.rules" url="AvoidDuplicateObjects.rules">
                <attr name="inspector" stringvalue="Duplicate immutable objects"/>
                <attr name="transformer" 
                      stringvalue="Replaces with methods that share these objects"/>
                <attr name="description" 
                      stringvalue="Eliminates creating duplicate immutable objects."/>
             </file>
             <file name="TreeCounter.settings" 
                   url="nbresloc:/org/netbeans/modules/jackpot/resources/jackpotCommand.xml">
               <attr name="inspector" stringvalue="Counts abstract syntax trees"/>
               <attr name="description" 
                     stringvalue="Counts the number of abstract syntax trees in a project."/>
               <attr name="command" 
                     stringvalue="org.myorg.myjackpotmodule.TreeCounter"/>
             </file>
          </folder>
       </folder>
    </filesystem>

Testing and Troubleshooting the Module Project

Jackpot modules are executed and debugged like other NetBeans modules. When the Run > Run Main Project action is invoked, the NetBeans platform is run with the module(s) under development installed in it. Here are the Jackpot-specific steps for running a new transformation.

  1. Click the Run toolbar button or choose Run > Run Main Project, which will cause the module to be built and an instance of the NetBeans platform to start with the module installed. Wait for the platform to finish loading.
  2. Choose Tools > Refactoring Manager to display the available refactorings. If that dialog is not on the Tools menu, it is probably due to Jackpot not being globally installed in your IDE. If so, you can either uninstall and reinstall Jackpot in your IDE, or install it again in the NetBeans platform instance.
  3. Scan the list of refactorings to verify that the two new refactorings defined by the tutorial module are displayed. If not, verify that the module's XML is correct; a malformed XML file will display error badges on the broken nodes in the Inspector window.
  4. Open a project you want to inspect. Select it in the Inspector window and choose Refactor > Query and Refactor. The new refactorings will be in the Single Query combo-box list.
  5. Select each of the new refactorings and click the Query button to run it against the project. The AvoidDuplicateObjects refactoring will not return any matches unless the selected project has them; to test, try adding statements to one of its classes such as:
  6. Boolean b = new Boolean(true);

Distributing the Jackpot Module

A major advantage to defining Jackpot transformations at NetBeans modules is that they can then be easily distributed and maintained using NetBeans Module (NBM) files:

  1. Create an NetBeans module (NBM) file by right-clicking the project in the Inspector window and selecting Create NBM.
  2. This module is installed using the NetBeans Update Center action. The module can be manually downloaded and installed, or distributed via your own Update Center.

Next Steps

For more information about creating and developing Jackpot transformer modules, see the following resources: