Code Conversion

#### Search Results

Search

# Code Conversion

This document covers the following topics:

- General Information

- Generating Adapters

- Structure of a Map-Based Application

- Structure of a Natural for Ajax Application

- Tasks of the Code Conversion

- DEFINE DATA Statement

- INPUT Statement

- REINPUT Statement

- PF-Key Event Handling

- SET KEY Statement

- Array Data

- Processing Rules

- System Variables

- Variable Names Containing Special Characters

## General Information

After the Map Converter has been used to create page layouts from map extract files, the last step in the conversion process is adapting the application code to the new user interface. This step can either be performed manually or, with Natural Engineer, partly automatically. In the following, the manual code conversion is described.

## Generating Adapters

First of all, it is necessary to generate HTML code and Natural adapters from the page layouts that have been created by the Map Converter. This is the same procedure as with page layouts that have been created manually with the Layout Painter. Then, the adapters are imported into the Natural development environment.

## Structure of a Map-Based Application

In this context, we need not consider the application code as a whole, but only the layer that handles the user interface. Often, the user interface handling part of a map-based application is structured in the following way:

- `DEFINE DATA`

- Initialization

- `REPEAT`

  - `INPUT [USING MAP map-name]`

    - Includes client-side validations (processing rules)

  - Server-side validations

    - `REINPUT` or `ESCAPE TOP`

  - `DECIDE ON *PF-KEY`

    - Function key handler 1

      - Processing

      - `REINPUT` or `ESCAPE TOP`

    - Function key handler 2

      - Processing

      - `REINPUT` or `ESCAPE TOP`

    - Function key handler n

      - Processing

      - `ESCAPE BOTTOM`

    - ...

  - `END-DECIDE`

- `END-REPEAT`

- Cleanup

- `END`

In practice,

- the `REPEAT` loop might or might not be there, and

- there might not be a clean `DECIDE` structure for the function key handlers. Instead, checks for the pressed function key might be spread all over the code.

However, accepting these differences, the above structure should match a large number of applications.

## Structure of a Natural for Ajax Application

The corresponding part of a Natural for Ajax application looks as follows:

- `DEFINE DATA`

- Initialization

- `REPEAT`

  - `PROCESS PAGE USING adapter-name`

    - Includes client-side validations

  - Server-side validations

    - `PROCESS PAGE UPDATE FULL`

  - `DECIDE ON *PAGE-EVENT`

    - Event handler 1

      - Processing

      - `PROCESS PAGE UPDATE FULL` or `ESCAPE TOP`

    - Event handler 2

      - Processing

      - `PROCESS PAGE UPDATE FULL` or `ESCAPE TOP`

    - Event handler n

      - Processing

      - `ESCAPE BOTTOM`

    - ...

  - `END-DECIDE`

- `END-REPEAT`

- Cleanup

- `END`

## Tasks of the Code Conversion

The code conversion should achieve the following:

- It should be minimal invasive.

- It should not duplicate business code.

- The converted application should be able to run not only with the new user interface, but also in a terminal session, in a Natural Web I/O Interface session and in batch, if it did so before the code conversion.

In detail, the code conversion needs to deal with the statements and constructs mentioned below.

## DEFINE DATA Statement

The `DEFINE DATA` statement must be extended because the data structures exchanged between a program and map are not fully identical to those exchanged between a program and the corresponding adapter.

The default conversion rules delivered with the Map Converter perform a data type mapping that tries to ensure that the data elements in the map interface are mapped to data elements of the same type and name in the adapter interface.

The Application Designer controls are usually not only bound to business data elements, but also to additional control fields. Which control fields these are depends on the way in which the elements of a map are mapped to Application Designer controls by the Map Converter rules. For instance, a `statusprop` can be assigned to a field, which results in an additional parameter in the parameter data area of the adapter. An array on a map can have been converted to a grid control with server-side scrolling. In this case, the additional data structures needed to control server-side scrolling need to be added to the `DEFINE DATA` statement.

### statusprop

The `statusprop` is needed to control the error status or focus of a FIELD (Java or Natural) control dynamically (see example 3 for the `REINPUT` statement below where it is used to replace the `MARK *field-name` clause). The default conversion rules contain a rule that creates a `statusprop` property for each map field that is controlled by a control variable. The adapter generator creates from this property a corresponding status variable and a comment line that identifies the status variable as belonging to the field.

#### Example

The parameter data area of the map contains:

    01 LIB-NAME (A8)
    01 LIB-NAME-CV (C)

The parameter data area of the adapter will then contain:

    * statusprop= STATUS_LIB-NAME-CV
    01 LIB-NAME (A8)
    01 STATUS_LIB-NAME-CV (A) DYNAMIC

The variable `STATUS_LIB-NAME-CV` is not yet known to the main program and must be defined there.

## INPUT Statement

The replacement for the `INPUT` statement is the `PROCESS PAGE` statement. In its simplest form, the `INPUT` statement just references the map. In this case, it is just replaced by a `PROCESS PAGE` statement with the corresponding adapter.

#### Example 1

Main program before conversion:

    INPUT USING MAP 'MMENU'

Main program after conversion:

    IF *BROWSER-IO NE 'RICHGUI'
      INPUT USING MAP 'MMENU'
    ELSE
      PROCESS PAGE USING 'AMENU'
    END-IF

The `INPUT` statement can come with a message text that is displayed in the status bar. There is no direct replacement for this construction because the `PROCESS PAGE` statement (in contrast to the `PROCESS PAGE UPDATE` statement) does not support the `SEND EVENT` clause.

#### Example 2

Main program before conversion:

    INPUT WITH TEXT MSG01 USING MAP 'MMENU'

Main program after conversion (no message will be displayed):

    IF *BROWSER-IO NE 'RICHGUI'
      INPUT WITH TEXT MSG01 USING MAP 'MMENU'
    ELSE
      PROCESS PAGE USING 'AMENU'
    END-IF

## REINPUT Statement

The replacement for the `REINPUT` statement is the `PROCESS PAGE UPDATE` statement. In its simplest form, the `REINPUT` statement comes with a message text that is displayed in the status bar. In the converted code, this is handled by the `SEND EVENT` clause of the `PROCESS PAGE UPDATE` statement.

#### Example 1

Main program before conversion:

    REINPUT [FULL] WITH TEXT MSG01

Main program after conversion:

    IF *BROWSER-IO NE 'RICHGUI'
      REINPUT [FULL] WITH TEXT MSG01
    ELSE
      PROCESS PAGE UPDATE [FULL]
        AND SEND EVENT 'nat:page.message'
        WITH PARAMETERS
          NAME 'type' VALUE 'E'
          NAME 'short' VALUE MSG01
        END-PARAMETERS
    END-IF

The `REINPUT` statement can come with a message number and replacements. In this case, the message must be created from number and replacements before it is sent to the status bar with the `SEND EVENT` clause.

#### Example 2

This example uses a subprogram `GETMSTXT` that builds the message text from number and replacements.

Main program before conversion:

    REINPUT [FULL] WITH TEXT *MSGNR, REPL1, REPL2

Main program after conversion:

    IF *BROWSER-IO NE 'RICHGUI'
      REINPUT [FULL] WITH TEXT *MSGNR, REPL1, REPL2
    ELSE
      CALLNAT 'GETMSTXT' MSTEXT MSGNR REPL1 REPL2
      PROCESS PAGE UPDATE [FULL]
        AND SEND EVENT 'nat:page.message'
        WITH PARAMETERS
          NAME 'type' VALUE 'E'
          NAME 'short' VALUE MSTEXT
        END-PARAMETERS
    END-IF

#### Example 3

The `REINPUT` statement can come with a `MARK` clause in order to put the focus on a field. This case requires that a `statusprop` property is created for the field during map conversion. The variable bound to the `statusprop` property is then used before the `PROCESS PAGE UPDATE` statement to set the `FOCUS` to the field.

Main program before conversion:

    REINPUT [FULL] WITH TEXT MSG01 MARK *LIB-NAME

Main program after conversion:

    01 STATUS_LIB-NAME-CV (A) DYNAMIC
    ...
    IF *BROWSER-IO NE 'RICHGUI'
      REINPUT [FULL] WITH TEXT MSG01 MARK *LIB-NAME
    ELSE
      STATUS_LIB-NAME-CV := 'FOCUS'
      PROCESS PAGE UPDATE FULL
        AND SEND EVENT 'nat:page.message'
        WITH PARAMETERS
          NAME 'type' VALUE 'W'
          NAME 'short' VALUE MSG01
        END-PARAMETERS
    END-IF

## PF-Key Event Handling

The original application might contain checks for the content of the system variable `*PF-KEY` at arbitrary places in the code. In order to handle function key events correctly in the converted application, several things need to be achieved:

- In response to the function keys, the converted application must raise events that are named like the possible contents of `*PF-KEY`. This can be achieved by using a page template such as NATPAGEHOTKEYS_TEMPLATE.xml which contains the required hot key definitions.

- A common local variable must be set up right after the `INPUT` or `PROCESS PAGE` statement that contains either the value `*PF-KEY` or `*PAGE-EVENT`, depending on the execution environment. The name of the variable can be freely chosen. In the example below, the name `XEVENT` is used.

- The events `nat:page.end` and `nat:browser.end` must be handled in such a way so that the program terminates. See also Built-in Events and User-defined Events.

- A default event handler must be set up that takes care of the values of `*PAGE-EVENT` that are not expected by the original application code. These unexpected events are simply replied with a `PROCESS PAGE UPDATE FULL` statement.

#### Example

    01 XEVENT (U) DYNAMIC
    ...
    PROCESS PAGE USING ...
    ...
    IF *BROWSER-IO = 'RICHGUI'
      DECIDE FOR FIRST CONDITION
        WHEN *PAGE-EVENT = 'nat:page.end'
          STOP
        WHEN *PAGE-EVENT = MASK ('PF'*) OR = MASK ('PA'*)
        OR = 'ENTR' OR = 'CLR'
          XEVENT := *PAGE-EVENT
        WHEN NONE
          PROCESS PAGE UPDATE FULL
      END-DECIDE
    ELSE
      XEVENT := *PF-KEY
    END-IF

All references to `*PF-KEY` in the code must then be replaced by references to `XEVENT`.

## SET KEY Statement

Natural for Ajax provides two controls (NJX:BUTTONITEMLIST and NJX:BUTTONITEMLISTFIX) that represent a row of buttons. These controls can be used to replace the visual representation of the function keys from the original application. If the page template NATPAGEPFKEYS_TEMPLATE.xml or a similar individually adapted template is used during map conversion, each resulting page will contain a row of function key buttons. The subject of this section is how the converted application can control the labeling and the program-sensitivity of the function keys with only little code changes.

Natural controls the labeling and program-sensitivity of the function keys in a highly dynamic way. The corresponding application code (`SET KEY` statements) can be distributed across program levels and can be lexically separated from the corresponding `INPUT` statements. Also, the `SET KEY` statement has several flavors, some affecting all keys and others affecting only individual keys. As a result, the status of the function keys at a given point in time can only be determined at application runtime.

Therefore, the following approach is chosen: Natural provides the application programming interface (API) `USR4005` that reads the current function key naming and program-sensitivity at runtime. During code conversion, a call to this API is inserted after each `SET KEY` statement or into each round trip. This call reads the function key status and passes it to the user interface.

#### Example

Main program before conversion:

    SET KEY ENTR NAMED 'Enter' PF1 NAMED 'F1' PF2 NAMED 'F2'
    PF3 NAMED 'Modify' PF4 NAMED 'Delete' PF5 NAMED 'F5'
    PF6 NAMED 'F6' PF7 NAMED 'Create' PF8 NAMED 'Display'
    PF9 NAMED 'F9' PF10 NAMED 'F10' PF11 NAMED 'F11' PF12 NAMED 'F12'
    *
    INPUT USING MAP "KEYS-M"
    *
    END

Map before conversion:

                                      *** PF-Keys ***

    Enter-PF1---PF2---PF3---PF4---PF5---PF6---PF7---PF8---PF9---PF10--PF11--PF12---
    Enter F1    F2    Modif Delet F5    F6    Creat Displ F9    F10   F11   F12

Main program after conversion:

    DEFINE DATA LOCAL
    1 PFKEY (1:*)
    2 METHOD (A) DYNAMIC
    2 NAME (A) DYNAMIC
    2 TITLE (A) DYNAMIC
    2 VISIBLE (L)
    1 METHODS (A4/13) CONST <'ENTR','PF1','PF2','PF3','PF4',
    'PF5','PF6','PF7','PF8','PF9','PF10','PF11','PF12'>
    END-DEFINE
    *
    SET KEY ENTR NAMED 'Enter' PF1 NAMED 'F1' PF2 NAMED 'F2'
    PF3 NAMED 'Modify' PF4 NAMED 'Delete' PF5 NAMED 'F5'
    PF6 NAMED 'F6' PF7 NAMED 'Create' PF8 NAMED 'Display'
    PF9 NAMED 'F9' PF10 NAMED 'F10' PF11 NAMED 'F11' PF12 NAMED 'F12'
    *
    IF *BROWSER-IO NE "RICHGUI"
      INPUT USING MAP "KEYS-M"
    ELSE
      EXPAND ARRAY PFKEY TO (1:13)
      METHOD(1:13) := METHODS (*)
      CALLNAT "GETKEY-N" PFKEY (*)
      PROCESS PAGE USING "KEYS-A"
    END-IF
    *
    END

Page after conversion:

#### Explanation

The structure `PFKEY` is generated into the Natural adapter of the page as the application interface to the BUTTONITEMLISTFIX control.

The subprogram `GETKEY-N` is a convenience wrapper for the API subprogram `USR4005`. It uses `USR4005` to determine the labeling and the program-sensitivity status for a given list of function keys. Each function key is identified by the `*PF-KEY` value it raises. `GETKEY-N` returns the function key information in a data structure suitable for the application interface of the BUTTONITEMLISTFIX control. The subprogram is delivered in source code with the Natural for Ajax demos and can be adapted to the needs of the application.

## Array Data

To use grid controls like TEXTGRIDSSS2 and ROWTABLEAREA2, you need to bind the `griddataprop` attribute to an array structure at level 1. For the example Natural data definitions below the `griddataprop` attribute needs to be bound to the `level1` field.

#### Example 1

    1 level1 (00001:00005)
    2 arrayfield1 (a10)
    2 arrayfield2 (a10)

#### Example 2

    1 level1
    2 arrayfield1(a10/00001:00005)
    2 arrayfield2(a10/00001:00005)

Natural however, also allows to have a combination of single fields and arrays as shown in the following example:

#### Example 3

    1 level1
    2 field1 (a10)
    2 arrayfield1(a10/00001:00005)
    2 arrayfield2(a10/00001:00005)

To bind a TEXTGRIDSSS3 or ROWTABLEAREA2 to structures as shown in example 3 you basically have two options:

#### Option 1

Change the original Natural data definition structure, which is usually the preferred and recommended way.

#### Option 2

Add an extra set of variable definitions to your Natural code like:

    1 level1x
    2 field1 (a10)
    1 level1
    2 array1(a10/00001:00005)
    2 array2(a10/00001:00005)

You may need to add extra Natural code to transfer the values to/from the original fields. However, if the Natural source code only references the variables without level 1 qualifiers (for example, using `reset array1(*)` instead of `reset level1.array1(*)`) no source change is required except for the initial data definitions.

If Option 1 is not possible, the convrulesCVVariables.xml example rules file offers semi-automated support for Option 2. It automatically splits the original structure into two and adds an "x" to the name of the newly created structure for the non-array fields in the adapter and adapter interface as shown in Option 2.

## Processing Rules

The Natural maps in the application to be converted may contain processing rules. In the sense of a Natural for Ajax application, the processing rules are server-side validations because they are executed on the Natural server side of the application.

In order to extract processing rules from the maps and to turn them into server-side validations in the converted application, the Natural Engineer function "Separate Processing Rules from Maps" can be used.

There is currently no function available that automatically turns processing rules into client-side validations in Application Designer.

## System Variables

If a map displays a system variable (for example, `*DATX`), a specific default conversion rule takes care that the necessary code for handling the system variable is generated into the Natural adapter of the resulting page layout.

#### Example 1

The map displays the contents of the system variables `*DATX` and `*TIMX`. The contents of these system variables are not modifiable.

The `DEFINE DATA` statement of the adapter will then contain:

    LOCAL
    01 XDATX (A8)
    01 XTIMX (A8)

The body of the adapter will then contain:

    XDATX := *DATX
    XTIMX := *TIMX
    *
    PROCESS PAGE ... WITH
    PARAMETERS
    ...
     NAME U'XDATX'
      VALUE XDATX
     NAME U'XTIMX'
      VALUE XTIMX
    END-PARAMETERS

The main program needs no special adaptation.

#### Example 2

The map displays the content of the system variable `*CODEPAGE`. The content of this system variables is modifiable.

The `DEFINE DATA` statement of the adapter will then contain:

    LOCAL
    01 XCODEPAGE (A64)

The body of the adapter will then contain:

    XCODEPAGE := *CODEPAGE
    *
    PROCESS PAGE ... WITH
    PARAMETERS
    ...
     NAME U’XCODEPAGE’
      VALUE XCODEPAGE
    ...
    END-PARAMETERS
    *
    *CODEPAGE := XCODEPAGE

The main program needs no special adaptation.

## Variable Names Containing Special Characters

A similar procedure applies to special characters contained in variable names. These are the following special characters:

+
#
/
@
§
&
$

Note
The hash (#) can occur only as the first character.

Variables names containing these special characters cannot be directly bound to Application Designer control attributes. A specific default conversion rule replaces the names containing these special characters with configurable replacements. The original field name is generated into the parameter data area of the Natural adapter and a corresponding mapping is generated into the `PROCESS PAGE` statement of the adapter.

#### Example

The map displays the variables `#FIRST` and `#LAST`.

The `DEFINE DATA` statement of the adapter will then contain:

    DEFINE DATA PARAMETER
    1 #FIRST (A16)
    1 #LAST (A20)

The body of the adapter will then contain:

    ...
    PROCESS PAGE ... WITH
    PARAMETERS
    ...
    NAME U'HFIRST'
      VALUE #FIRST
     NAME U'HLAST'
      VALUE #LAST
    ...
    END-PARAMETERS

The main program needs no special adaptation.

### On this page

- General Information
- Generating Adapters
- Structure of a Map-Based Application
- Structure of a Natural for Ajax Application
- Tasks of the Code Conversion
- DEFINE DATA Statement
- INPUT Statement
- REINPUT Statement
- PF-Key Event Handling
- SET KEY Statement
- Array Data
- Processing Rules
- System Variables
- Variable Names Containing Special Characters