Creating and running hook methods that run before and after inline or annotated methods

You can use the com.ibm.pdq.runtime.statement.Hook interface to create methods that run before and after inline or annotated methods.
If a Data object that is used by inline methods, or a generated implementation of an annotated interface, has a Hook registered, the following steps occur when an application calls a method:

The Data interface, which defines inline methods, contains a number of JDBC methods on Connection objects, such as close(), commit(), rollback(), setAutoCommit(), and getAutoCommit(). You cannot bracket these methods with the pre() and post() methods.

Example

For example, the sendFormLetter() annotated method has an int parameter that supplies the code that identifies a form letter to use. The method also has String parameters that supply information to put in the form letter and the city, state, and zip code for mailing the form letter. Finally, the sendFormLetter() method updates a table that tracks whether a letter needs to be printed and sent.

Suppose an application that calls the sendFormLetter() method might not supply either the city, state, or zip code, or perhaps might supply two of them but not all three. You want to write application logic that checks for the presence of all three values, but you cannot easily do so in the database and you cannot do so in the definition of the sendFormLetter() method. One place that you could write that application logic is in a Hook that you could define like this:

import com.ibm.pdq.runtime.statement.*;                      1 

public class ZipHook implements Hook
{
  public void pre (                                          2 
    String methodName, Data dataInstance, SqlStatementType sqlStatementType, Object... parameters)
  {
      if (methodName.startsWith(
             "sendFormLetter(int, java.lang.String"))
      { // right method; params 2,3, & 4 are city, state, zip
        if (parameters[1] == null || parameters[2] == null ||
              parameters[3] == null)
        {  
			  ...                                3 
        }
      }
  }            

  public void post (                                         4 
	  	String methodName, Data dataInstance, Object returnValue, SqlStatementType sqlStatementType, Object... parameters)
  {
   return;  // no action
  }
}
  1. Import the package that contains the Hook interface.
  2. Define the pre() method.
    String methodName
    pureQuery passes the signature of the method to the pre() method.
    Data dataInstance
    pureQuery passes the object that implements the Data interface.
    SqlStatementType sqlStatementType
    pureQuery passes the type of the SQL statement: SELECT, UPDATE, INSERT, and so on.
    Object... parameters
    pureQuery passes the parameters that are passed to the sendFormLetter() method.
  3. Supply logic to find the city or state by using the zip code, or to find the zip code by using the city and state. Update the parameters before passing them to the sendFormLetter() method.
  4. Define the post() method to do nothing.

If the sendFormLetter() method is defined in the interface com.company.NotSpam, then the application logic to associate an instance of the Hook ZipHook with use of the sendFormLetter() method might look like this:

Connection con = DriverManager.getConnection(...);           1 
ZipHook zHook = new ZipHook();                               2 
Data db = DataFactory.getData(NotSpam.class, con, zHook);    3 

The code performs the following steps:

  1. Create a connection to the database.
  2. Create an instance of the implementation of the ZipHook interface.
  3. Create an instance of the implementation of the Data interface. This implementation implements the NotSpam interface and is assigned the Hook ZipHook.

Feedback