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:
Creating a NetBeans Module Project
- Choose File > New Project. Under Categories, select NetBeans Plug-in Modules.
- Select Module Project. Click Next.
- 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.
- 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.
Click Finish. The IDE creates the MyJackpotModule project. You can view its logical
structure in the Projects window (Ctrl-1):
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:
- 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.
- Select the Libraries panel, and set the Java Platform to Java 5 or 6.
- Add the "Jackpot Engine", "Javac API Wrapper", and "Utilities API" to the
Module Dependencies list.
- 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).
- 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).
- Click on the Navigator Files view, then select your module's src directory.
- Choose File > New File. Under Categories select Other, then under File Types select Folder.
- Name the folder META-INF/services (note: this name is case-sensitive). Click Finish.
- Select the META-INF/services folder, choose File > New File. Under Categories select Other,
then under File Types select Empty File.
- 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.
Your Projects window now looks like:
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.
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.
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.
- 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.
- 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.
- 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.
- 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.
- 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:
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:
- Create an NetBeans module (NBM) file by right-clicking the project in the Inspector window and
selecting Create NBM.
- 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: