Home Page   We Generate Your Software.
Products Services Company Technology Demo Contact Site Map Search
Please note: this document is currently under revision.
The information herein contained, while still valid, does not reflect the latest state of the described technology.
The Somusar/SoProTech[tm] Booklet Series
Volume VIII

"somusar/tjpp: User's Guide"

Printer friendly


Contents
1. Introduction
2. Overview
3. Installing tjpp[tm]
4. SimpleClass Example
5. ComplexClass Example
6. Running a Test
7. Exercise: Improving Multitier Code Consistency
7.1 Code Examples
8. Contacting Somusar
9. Further Reading
Appendix A - tjpp Directives and Macros

Chapter 7 - Exercise: Improving Multitier Code Consistency

Multitier applications replicate the same data item, such as a "Last Name", at various levels: database tables, Java classes (for both business logic and system infrastructure), user interface dialogs.

A familiar example of this is shown by the following code fragment, where data items retrieved from a database are copied to Java variables:

  // Get results from "results" by column name
  int rCustId = results.getInt("CUST_ID");
  String rFirstName = results.getString("FIRST_NAME");
  String rLastName = results.getString("LAST_NAME");
  float rBalance = results.getFloat("BALANCE");
  String rEmail = results.getString("EMAIL");
Similar code fragments are frequent and lend themselves to be generated by a tjpp macro. The new user-defined macro will directly generate a block of code, instead of returning a short string of code as do my_macro/timestamp and my_macro/perc.

The new macro my_macro/get_results is commented below, as are the input "Results.tj" and output "Results.java" files. Input and output fragments are listed below.

Input:

  : MY_MEMBERS=int/cust_id       ,%
               String/first_name ,%
               String/last_name  ,%
               float/balance     ,%
               String/email
  $   my_macros/get_results(BY_NUMBER,rs,MY_MEMBERS)

  $   my_macros/get_results(BY_NAME,results,MY_MEMBERS)
Output:
  int      rCustId     = rs.getInt(    1);
  String   rFirstName  = rs.getString( 2);
  String   rLastName   = rs.getString( 3);
  float    rBalance    = rs.getFloat(  4);
  String   rEmail      = rs.getString( 5);

  int      rCustId     = results.getInt(    "CUST_ID");
  String   rFirstName  = results.getString( "FIRST_NAME");
  String   rLastName   = results.getString( "LAST_NAME");
  float    rBalance    = results.getFloat(  "BALANCE");
  String   rEmail      = results.getString( "EMAIL");
An alternative and more exhaustive solution to the problems deriving from multitier data redundancy is discussed in booklet "somusar/SoProTech: A Sample Project".

7.1 - Code Examples        top

Code Example 10 - Input code to generate Results.java
Line 8 uses column numbers to get the query result values.
Line 11 uses column names to get the query result values.
Note that reuse of tjpp variable MY_MEMBERS can help increase consistency across different sections or classes of Java code.
Source code - File "input_code/Results.tj"
    1      : MY_MEMBERS=int/cust_id       ,%
    2                   String/first_name ,%
    3                   String/last_name  ,%
    4                   float/balance     ,%
    5                   String/email      ,%
    6                   wrongType/sthg_else
    7              // Get results from "rs" by column number
    8      $       my_macros/get_results(BY_NUMBER,rs,MY_MEMBERS)
    9      
   10              // Get results from "results" by column name
   11      $       my_macros/get_results(BY_NAME,results,MY_MEMBERS)
	       

Code Example 11 - Code generated from Results.tj
Lines 5-10 result from calling my_macro/get_results with mode BY_NUMBER.
Lines 13-18 result from calling my_macro/get_results with mode BY_NAME.

Note that a wrongType, supplied to get_results, purposely produced the wrong statements of lines 10 and 18, and caused tjpp to issue a warning message. The Java compiler would then detect the error and the generated code would not be compiled.

Source code - File "generated_code/Results.java"
    1      // WARNING: file "Results.java" generated from "Results.tj"
    2      //          Changes should be applied on the source file.
    3      
    4              // Get results from "rs" by column number
    5              int         rCustId     = rs.getInt(    1);
    6              String      rFirstName  = rs.getString( 2);
    7              String      rLastName   = rs.getString( 3);
    8              float       rBalance    = rs.getFloat(  4);
    9              String      rEmail      = rs.getString( 5);
   10              wrongType   rSthgElse   = rs.get UNKNOWN (      6);
   11      
   12              // Get results from "results" by column name
   13              int         rCustId     = results.getInt(       "CUST_ID");
   14              String      rFirstName  = results.getString(    "FIRST_NAME");
   15              String      rLastName   = results.getString(    "LAST_NAME");
   16              float       rBalance    = results.getFloat(     "BALANCE");
   17              String      rEmail      = results.getString(    "EMAIL");
   18              wrongType   rSthgElse   = results.get UNKNOWN ( "STHG_ELSE");
   19      
   20      // WARNING: file "Results.java" generated from "Results.tj"
   21      //          Changes should be applied on the source file.
	       

Code Example 12 - A macro to generate result-get statements
This macro generates result-set getXXX statements from a parametric source variable for the type/id pairs supplied as arguments.
A mode parameter specifies whether the getXXX should use the column name or column number.
Source code - File "input_code/tjpp_lib/my_macros/get_results"
    1      @ INTERFACE(mode,source)
    2      |
    3      |   Generate statements in the form (mode = BY_NUMBER) 
    4      |       int         rCustId      = source.getInt(1);
    5      |   or (mode = BY_NAME) 
    6      |       int         rCustId      = source.getInt("CUST_ID");
    7      |   Actually, more arguments are supplied, namely a 
    8      |   list of type/id arguments, like in "int/cust_id".
    9      |
   10      @ DASH ^
   11      |   Create a mapping between Java types and getXXX accessors
   12      @ SET     jmap^int=Int
   13      @ SET   jmap^float=Float
   14      @ SET  jmap^double=Double
   15      @ SET  jmap^String=String
   16      @ SET jmap^boolean=Boolean
   17      |   Scan list of type/id pairs, skipping mode and source
   18      @ SET I=2
   19      @ WHILE I<REG_COUNT
   20      @    SET FIELD=REG_^I
   21      |    Strip leading and trailing blanks
   22      @    SET FIELD=$WORD(FIELD,0)
   23      |    Retrieve type
   24      @    SET JTYPE=$FIELD(FIELD,0,/)
   25      |    Retrieve identifier
   26      @    SET   JID=$FIELD(FIELD,1,/)
   27      |    Check if type mapping is known, issue a warning otherwise
   28      |    and propagate error into Java code
   29      @    SET JRESTYPE=$VALUE(jmap^JTYPE)
   30      @    IF JRESTYPE~jmap
   31      @       SET JRESTYPE= UNKNOWN 
   32      $       warning($jfileloc(src_only): don't know how to map type "JTYPE")
   33      @    ENDIF
   34      |    Select mode of getXXX
   35      @    IF mode=BY_NAME
   36      @       SET JKEY="$MAKE_ID(JID,ABC_DEF)"
   37      @    ELSE
   38      @       SET JKEY=I
   39      @       SUB JKEY 1
   40      @    ENDIF
   41      |    Prepare a local identifier
   42      @    SET JID=$MAKE_ID(r_^JID,abcDef)
   43      |    Prepare right-hand side of assignment
   44      @    SET JVAL=source.get^JRESTYPE(      JKEY)
   45      |    Generate tab-aligned code
   46      @    ECHO $TABS(        JTYPE   JID     = JVAL;,8,20,32,48)
   47      @    ADD I 1
   48      @ ENDWHILE
   49      @ DASH
	       

[Previous chapter]    [Next chapter]    [Back to top]

http:// www.somusar.com  / doc  / booklets  / tjpp_manual  - Powered by SoProMach
Copyright © 2003-2012 Somusar - Trademarks - Legal - Privacy - Webmaster