Plugin Guide

RazorSQL provides the ability for developers to write plugins, which are programs that can interact with RazorSQL to produce custom results. This guide describes the process for registering plugins with RazorSQL, and gives examples for making calls to the exposed methods of the RazorSQL plugin API.

Language Requirements:

RazorSQL requires plugins to be written using the Java programming language. It is recommended that plugins are written to be executed on Java Runtime Environment (JRE) version 1.4.2. Please test your plugin with RazorSQL to make sure it is compatible. To guarantee compatibility across all current versions of RazorSQL, the plugin should be compiled using the 1.4.x compiler.

Plugin Requirements:

Plugin code must be placed in a JAR file. This jar file must be placed in the following directory:

<RAZORSQL_INSTALL_DIR>/plugins/

There must be a Java class contained in the JAR file with the same name as the name of the JAR file. This class must implement the razorsql.plugins.Plugin interface and must be a member of the following package:

razorsql.plugins

Listed below is the Plugin interface:

public void load(); public String getName(); public String getVersion(); public String getDescription();

Plugin Example:

Example:

Create the following file (PluginTest.java):

package razorsql.plugins; import javax.swing.*; public class PluginTest implements Plugin { public void load() { System.out.println("in load() Plugin Test"); PluginManager pluginManager = PluginManagerFactory.getInstance(); pluginManager.log("in load() in PluginTest "); //add a menu item to the Plugins menu JMenuItem menuItem = new JMenuItem("Plugin Test"); pluginManager.addPluginMenuItem(menuItem); } public String getName() { return "Plugin Test"; } public String getVersion() { return "1.0"; } public String getDescription() { return "An Example Plugin"; } }

Compiling

To compile PluginTest.java, the pluginAPI.jar file that ships with RazorSQL needs to be placed in the CLASSPATH. The pluginAPI.jar file is located in the <RAZORSQL_INSTALL_DIR>/plugin_api/ directory.

Storing

Once the PluginTest.java class is compiled, create a JAR file called PluginTest.jar that contains the following file:

razorsql/plugins/PluginTest.class

After creating the jar file, move it to the following directory:

<RAZORSQL_INSTALL_DIR>/plugins/

The next time RazorSQL loads, PluginTest will be available via the Plugins menu.

Referencing other JARs from a Plugin

If the plugin class must reference an external jar, that external jar can be placed in the following directory:

<RAZORSQL_INSTALL_DIR>/plugins/lib/

PluginManager API

RazorSQL exposes a PluginManager class that contains methods to allow plugins to interact with RazorSQL. Here is the PluginManager interface:

package razorsql.plugins; import java.sql.*; import javax.swing.*; import java.util.*; public interface PluginManager { /** * Returns the current major version of RazorSQL in int format. * For example, if using RazorSQL version 1.04, 1 would be returned * If using RazorSQL version 10.4, 10 would be returned */ public int getMajorVersion(); /** * Returns the current minor version of RazorSQL in int format. * For example, if using RazorSQL version 1.04, 4 would be returned * If using RazorSQL version 1.4, 40 would be returned. */ public int getMinorVersion(); /** * Returns the version as as String. If using RazorSQL 1.04, * 1.04 would be returned. */ public String getVersionString(); /** * Adds a menu item to the plugin menu. */ public void addPluginMenuItem(JMenuItem item); /** * Adds a separator to the plugin menu */ public void addPluginMenuSeparator(); /** * Legacy version of getText method */ public String getEditorContents(); /** * Returns the current contents of the SQL editor in the * currently displayed window in String format */ public String getText(); /** * Returns the text of the editor in the currently * displayed tab in String format starting at the start position * until the specified length */ public String getText (int start, int length); /** * Returns the selected text of the editor in the currently * active tab, or null if there is no text selected */ public String getSelectedText(); /** * Sets the text in the editor in the currently displayed tab */ public void setText (String text); /** * Replaces the current selection with the text, or * if there is not selection, inserts the text into the editor * at the current cursor position */ public void setSelectedText (String text); /** * Returns the line number (0 based) that the cursor is currently on */ public int getCursorLine(); /** * Returns the offset in the editor for the cursor position */ public int getCursorPosition(); /** * Returns the line number which contains the passed in position */ public int getLineForPosition (int position); /** * Returns the total number of lines in the editor */ public int getLineCount(); /** * Returns the text of the line for the lineNumber */ public String getLineText (int lineNumber); /** * Selects text from start to end */ public void select (int start, int end); /** * Sets the cursor position to the specified position */ public void setCursorPosition (int position); /** * Returns the current Connection being used in * the currently displayed window */ public Connection getConnection(); /** * Logs to the RazorSQL log file * The logfile is located in the razorsql/logs * directory under $USER_HOME directory. $USER_HOME * is retrieved by doing a System.getProperty("user.home") */ public void log(Object obj); /** * Logs a query to the query log */ public void logQuery(String query); /** * Gets the number of columns returned * from the last executed query on the currently * displayed window */ public int getColumnCount(); /** * Gets the names of the columns * returned from the last executed query on the * currently displayed window */ public String[] getColumnNames(); /** * Gets the number of rows fetched from the ResultSet * from the last executed query on the currently displayed window * NOTE: There may or may not be more rows in the ResultSet that * have yet to be fetched. */ public int getDisplayedRowCount(); /** * Gets the values for each column in the * displayed row at the passed in index on the * currently displayed window */ public String[] getDisplayedRow (int rowIndex); /** * Tries to fetch the next row from the ResultSet * from the last executed query on the currently displayed * window. If there is not a next row, null is returned. */ public String[] getNextUndisplayedRow(); /** * Returns all rows tied to the current query. Both the * rows already displayed in the query results table, and * rows not yet fetched from the result set * returns a java.util.List of java.lang.String[] objects */ public List getAllRows(); /** * Returns the catalog / database of the currently selected * Navigator node, or null if there is no node selected. */ public String getCurrentNavigatorCatalog(); /** * Returns the schema / owner of the current selected * Navigator node, or null if there is no node selected or * the selected node is above the schema / owner level */ public String getCurrentNavigatorSchema(); /** * Returns the name of the currently selected Navigator node, * or null if no node is selected */ public String getCurrentNavigatorNode(); /** * Returns the type of the selected Navigator node. Returns null * if the current selected node is not a database object, but just a * descriptor node such as "Tables", etc. Returns null if the selected * object is not one of the options listed below. * Options include the following: CATALOG SCHEMA TABLE SYSTEM_TABLE VIEW INDEX PROCEDURE FUNCTION TRIGGER PACKAGE PACKAGE_BODY SEQUENCE SYNONYM CONSTRAINT COLUMN */ public String getCurrentNavigatorNodeType(); /** * Open a new tab sharing the connection of the current tab */ public void openNewConnectedTab (); /** * Executes a query that returns results on the current * connection and displays the results * in a query results tab */ public void executeQuery (String query); /** * Returns a handle to the main RazorSQL frame */ public JFrame getMainFrame(); /** * Returns whether or not the user has a registered * copy of RazorSQL */ public boolean isRegistered(); }

Complete Plugin Example

Here is an example plugin that shows the uses of the PluginManager.

package razorsql.plugins; import javax.swing.*; import java.awt.event.*; import java.sql.*; import java.util.*; public class PluginExample implements Plugin { public void load() { PluginManager pluginManager = PluginManagerFactory.getInstance(); pluginManager.log("in load() in PluginExample "); //add a menu item to the Plugins menu JMenuItem menuItem = new JMenuItem("Plugin Example"); pluginManager.addPluginMenuItem(menuItem); //add an ActionListener to perform operations when the //menu item is selected menuItem.addActionListener(new PluginExampleListener()); } public String getName() { return "Plugin Example"; } public String getVersion() { return "1.0"; } public String getDescription() { return "Example of how to use RazorSQL plugins"; } private static class PluginExampleListener implements ActionListener { public PluginExampleListener() {} public void actionPerformed(ActionEvent e) { PluginManager pluginManager = PluginManagerFactory.getInstance(); pluginManager.log("in actionPerformed"); int majorVersion = pluginManager.getMajorVersion(); int minorVersion = pluginManager.getMinorVersion(); String versionString = pluginManager.getVersionString(); boolean registered = pluginManager.isRegistered(); String editorContents = pluginManager.getEditorContents(); int columnCount = pluginManager.getColumnCount(); String[] columnNames = pluginManager.getColumnNames(); int displayedRowCount = pluginManager.getDisplayedRowCount(); String[] displayedRow0 = null; if (displayedRowCount > 0) { displayedRow0 = pluginManager.getDisplayedRow(0); } String[] nextUndisplayedRow = pluginManager.getNextUndisplayedRow(); List allRows = pluginManager.getAllRows(); Connection con = pluginManager.getConnection(); JPanel testPanel = new JPanel(); JTextArea textArea = new JTextArea(20,50); JScrollPane scrollPane = new JScrollPane(textArea); testPanel.add(scrollPane); textArea.append("Major Version: "+majorVersion); textArea.append("\n"); textArea.append("Minor Version: "+minorVersion); textArea.append("\n"); textArea.append("Version String: "+versionString); textArea.append("\n"); textArea.append("Registered: "+registered); textArea.append("\n"); textArea.append("Editor Contents: "+editorContents); textArea.append("\n"); textArea.append("Column Count: "+columnCount); textArea.append("\n"); if (con != null) { Statement stmt = null; ResultSet rs = null; try { DatabaseMetaData metaData = con.getMetaData(); String databaseProduct = metaData.getDatabaseProductName(); textArea.append( "Database Product Name: " +databaseProduct); textArea.append("\n"); stmt = con.createStatement(); String query = "select id from data"; pluginManager.logQuery(query); rs = stmt.executeQuery(query); if (rs.next()) { textArea.append("Query Result 0: " + rs.getString(1)); textArea.append("\n"); } } catch (SQLException ex) { pluginManager.log(ex); } finally { if (rs != null) { try { rs.close(); } catch (Exception ex) {} } if (stmt != null) { try { stmt.close(); } catch (Exception ex) {} } } } if (columnNames != null) { textArea.append("Column Names: "); int len = columnNames.length; int check = len-1; for (int i = 0; i < len; i++) { textArea.append(columnNames[i]); if (i < check) { textArea.append(","); } } textArea.append("\n"); } textArea.append("Displayed Row Count: " + displayedRowCount); textArea.append("\n"); if (displayedRow0 != null) { textArea.append("Displayed Row 0: "); int len = displayedRow0.length; int check = len-1; for (int i = 0; i < len; i++) { textArea.append(displayedRow0[i]); if (i < check) { textArea.append(","); } } textArea.append("\n"); } if (nextUndisplayedRow != null) { textArea.append("Displayed Row 0: "); int len = nextUndisplayedRow.length; int check = len-1; for (int i = 0; i < len; i++) { textArea.append(nextUndisplayedRow[i]); if (i < check) { textArea.append(","); } } textArea.append("\n"); } if (allRows != null) { textArea.append("All Rows:"); Iterator iter = allRows.iterator(); while (iter.hasNext()) { String[] arr = (String[])iter.next(); if (arr != null) { int len = arr.length; int check = len-1; for (int i = 0; i < len; i++) { textArea.append(arr[i]); if (i < check) { textArea.append(","); } } } textArea.append("\n"); } textArea.append("\n"); } JFrame testFrame = new JFrame("PluginExample"); testFrame.setSize(400,400); testFrame.getContentPane().add(testPanel); testFrame.pack(); testFrame.setVisible(true); } } }