programming with troia · programming with troia, release 0.5.beta 1.1.3license server license...

174
Programming with TROIA Release 0.5.beta Bahtiyar Tan Jun 20, 2018

Upload: duongnguyet

Post on 25-Nov-2018

232 views

Category:

Documents


2 download

TRANSCRIPT

Programming with TROIARelease 0.5.beta

Bahtiyar Tan

Jun 20, 2018

Contents

1 Platform Basics 31.1 Components and Network Architecture Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Software Architecture Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.3 About Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 Language Basics 72.1 Understanding the Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2 Basic Language Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.3 Some Key Terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.4 Development Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.5 Hotline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.6 Comments in TROIA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3 Built-in Data Types and Structures 133.1 Built-in Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.2 StringBuilder & String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.3 Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.4 Vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143.5 Keywords and Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

4 Variables and Scope 154.1 Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154.2 Defining Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164.3 Variable Definition Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164.4 System Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.5 Some Facts About Defining Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

5 Operators and Expressions 215.1 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215.2 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225.3 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225.4 Type Conversion and Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235.5 Exercise 1: Integer Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

6 Flow Control 276.1 IF Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276.2 SWITCH Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

i

6.3 WHILE Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296.4 LOOP Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296.5 Other Looping Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306.6 BREAK & CONTINUE Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306.7 Exercise 1: Fibonacci Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316.8 Exercise 2: Factorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

7 Strings / String Manipulation 337.1 Some Facts About Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337.2 Escaping & Special Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337.3 Basic String Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347.4 String Concatenation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357.5 Looping on Strings: PARSE Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367.6 Exercise 1: Basic String Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367.7 Exercise 2: List Numeric Tokens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

8 Dialog Basics 398.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398.2 Basic Dialog Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418.3 Basics of Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428.4 Switching Between Dialogs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448.5 Functions & Right Click Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448.6 Timers on Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448.7 Exercise 1: Counting Words . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458.8 Exercise 2: Defining a Clock with Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

9 Transactions 479.1 Defining Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479.2 Transactions and Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479.3 Running & Calling Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489.4 Input Parameters & TRANSCALLED Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499.5 Scheduled Tasks and Batch Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499.6 Exercise 1: Defining Transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

10 Messages and Alerts 5110.1 MESSAGE Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5110.2 Message on Batch/Server Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5210.3 Message on Database Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5310.4 Other Alerting Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5310.5 Exercise 1: Reading Message Text/Answer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

11 Classes 5511.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5511.2 Basic Class Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5611.3 Defining Class Instances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5711.4 Calling Class Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5711.5 Accessing Class Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5811.6 Class Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5811.7 Exercise 1: Scope of Class Member (Math) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5811.8 Exercise 2: Defining Unexisting Class Instances . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

12 Basics of Table 6112.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6112.2 Defining/Filling Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6112.3 Adding Rows To Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

ii

12.4 Accessing Table Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6312.5 Table Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6412.6 Looping on Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6512.7 Locating on Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7012.8 Sorting Table Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7112.9 Working on Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7312.10 Data Transfer Between Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7612.11 Exercise 1: Compare LOOP Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8012.12 Exercise 2: Locating Using Hash Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8012.13 Exercise 3: Sort Users Like a Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8012.14 Exercise 4: Copying Rows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

13 Working With Date/Datetime 8313.1 Date Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8313.2 Type Conversion & Casting on Date Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8313.3 Some Useful Functions and Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8513.4 What is NULLDATE? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8813.5 Min Date & Max Date Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8813.6 Basic Date Formatting/Parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8913.7 Database & Date Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9113.8 Timezone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9113.9 Work Calendar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

14 Inheritance & Cross 9314.1 What is “Inheritance”? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9314.2 Inheritance on TROIA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9314.3 Using SUPER() Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9514.4 Using SUPER Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9814.5 What is “Cross”? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9914.6 Cross Levels & Loading Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9914.7 How to Define Crosses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10014.8 Example 1: Inheriting Class and Overriding Methods . . . . . . . . . . . . . . . . . . . . . . . . . . 10014.9 Example 2: Understanding Cross Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

15 File Operations 10315.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10315.2 Opening/Closing Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10415.3 Writing Files & Reading Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10715.4 Copying Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10915.5 Other File & Directory Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11015.6 File Compression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11115.7 Exercise 1: Writing Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11115.8 Exercise 2: Working With Multiple Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11215.9 Exercise 3: Prepare Zip Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

16 Custom TROIA Components 11316.1 How Components Stored? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11316.2 Nested Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11516.3 Accessing Variables Which Defined in Component . . . . . . . . . . . . . . . . . . . . . . . . . . . 11716.4 Calling Dialogs from Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

17 Working with FTP Servers 11917.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11917.2 Connection to FTP Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11917.3 Working Directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

iii

17.4 Transferring Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12117.5 Listing Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12217.6 Creating/Deleting Folders and Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

18 Web Services 12518.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12518.2 Service Definition & Permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12618.3 Log-in/Log-out over Web Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12618.4 Listing Available Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12718.5 Calling Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12718.6 Encryption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13018.7 Compression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

19 Parsing XML & JSON 13319.1 Conversion Between XML & JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13319.2 Reading XML Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13519.3 Some Useful XML Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13519.4 Validating XML Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13619.5 Parsing XML Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13719.6 XML Parsing Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13819.7 Exercise 1: Parse using READXMLSTRUCTURE . . . . . . . . . . . . . . . . . . . . . . . . . . . 14719.8 Exercise 2: Parsing Simple XML Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14819.9 Exercise 3: Parsing Complex XML Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14919.10 Exercise 4: Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

20 HTTP Operations & Calling Web Services 15120.1 Sending data over HTTP Post Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15120.2 Calling Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152

21 Port Communication (Serial & TCP) 15521.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15521.2 Opening/Closing Serial Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15521.3 Opening/Closing TCP Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15621.4 Reading Data From Port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15621.5 Writing Data To Port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

22 Shared Libraries & Running Other Programs 15922.1 Introduction to Shared Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15922.2 Using Shared Libraries in TROIA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15922.3 Opening Files with Default App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16022.4 Invoking Other Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16022.5 Exercise 1: Checking domain availability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

23 Client Plugin Development 16323.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16323.2 Types of Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16423.3 How to Develop a Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16423.4 Sources of a Simple Generic Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16423.5 Sending Message to a Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167

iv

Programming with TROIA, Release 0.5.beta

This is an open and unofficial book to learn TROIA Platform and Programming Language. Although it targets theprogrammers who are new to TROIA, it also contains useful information for experienced programmers, consultantsand system administrators.

Contents 1

Programming with TROIA, Release 0.5.beta

2 Contents

CHAPTER 1

Platform Basics

TROIA Platform is the software framework which TROIA Programming Language works on. This section introducesmain components and architecture of TROIA Platform for better understanding of next sections.

1.1 Components and Network Architecture Overview

1.1.1 Application Server

Application server is one of the most important components of TROIA platform. As it is obvious, it is a serverside service that serves for all kind of TROIA clients. Basically application server is responsible for user sessionmanagement, handling troia application lifecycle, database transaction management etc.

The most important responsibility of application server is running TROIA programming language and handling troiaapplication lifecycle. Application server is the only platform component that is able to run TROIA codes. There-fore it is not possible to run a troia code without an application server.

A single application server is able to serve multiple clients. User count that an application server is able to serveproperly depends on the workload of application server. It is possible to run multiple servers simultaneously to serverfor numerous concurrent users.

1.1.2 Client(s)

It is not possible to log in an application server and run a troia application directly on application server. To do thisoperations you need a TROIA client. Most used TROIA client is desktop client (also called java client or swingclient) that is able to connect application server and draw troia applications on user interface. The main functionalityof this client is getting user actions passing them to application server and drawing resulting screen to user interface.Additonally, development environment of TROIA Language is a part of java client, in other words to develop a TROIAApplication you have to connect application server via a desktop client.

There are different kind of clients such as desktop client, android client, web client and web services. Clients are notable to run TROIA codes, their basic responsibility is transferring user interactions to server and handling applicationserver response in ui or presentation layer.

3

Programming with TROIA, Release 0.5.beta

1.1.3 License Server

License Server, a server side service that handles licencing issues considering user count and modules (TROIA Appli-cation groups). In general, License Server serves for application servers, although some other server side componentsneeds license server.

After its launch, an application server tries to access License Server at first login attempt. If your License Server isdown or not accessible, application servers do not allow users to log in. If license server gets down while applicationservers have already logged users, this users can work properly. But it is not possible to log in new users until yourapplication server access license server.

To serve properly, license server and the application servers that it serves for must have same version.

1.1.4 RMI Registry

RMI Registry is a server side service that provides a communication infrastructure between all components of TROIAPlatform. RMI Registry uses RMI Infrastructure of java which provides cummunicatation method for different javaapplications. Any two components of the platform uses RMI Registry (server to server, client to server, server tolicense server etc), so running a single RMI registry is a must to run other platform components properly.

1.1.5 Other Components

Although most important tools and components are listed above, TROIA Platform has other components for loadbalancing, administration, single sign on, monitoring, SMS handling etc. Some of this components are listed below:

Load Balancer is a server side service that redirects clients to best available server considering server resources andthe rules that are defined its configuration.

SSO Gateway is a server side service that provides single sign on options for TROIA Platform users.

SMS Gateway is another server side service for handling SMS handling.

Workbench is an administration tool(a kind of client) to manage and monitor server side components such as applica-tion server,license server,load balancer. Using this tool system administrators can view and manage application servercache, users sessions and their running applications etc.

System Reporter is a tool that reports status of your server side components in a configurable period.

1.1.6 Network Architecture Overview

Here is an overview of all TROIA Plaform’s main components and network structure from database to user interface.This overview clearly shows which components of TROIA Platform are server or client. Additionally, it is possibleto see, directions of communication lines. Understanding this structure is too important to overcome some advancedquestions about platform by yourself.

Please discuss question below considering the network structure:

Is it possible to push an information to client sidewhen an instant message recieved from another user?

1.2 Software Architecture Overview

Basically, TROIA Platform allows programmer to develop applications that access data, manipulate it and save. Tounderstand platform architecture its very important to understand the roles of application server and client(s). The

4 Chapter 1. Platform Basics

Programming with TROIA, Release 0.5.beta

graphic below, shows the main structures and layers of TROIA Platform from user interface to data. Also, it’s possibleto understand responsibility/functionality share of application server and client.

Understand the roles of each component and their subsystems using this graphic and try to create some statements anddiscuss them for better understanding. Here are some sample statements to discuss:

- TROIA Codes are executed only in application server.- IDE is a part of desktop client,

so TROIA applications are only developed desktop devices.- Desktop, web and android client shares same troia application model layer.

1.3 About Deployment

1.3.1 How to Read Version Number?

As an TROIA application developer or system administrator, it is important to know your version number. Becausesome new features revealed or bugs are fixed with new releases. And you must know whether your version supportsthe features that you need or all your components have same version to be sure that your installation is valid or not.

You can read your version number from the about dialog (Menu->About). Sample version numbers are listed below:

3.08.05 0211015.01.02 0121025.02.04 041201

TROIA Platform version numbers are consisted from two main parts “major version number” and “build number”. As

1.3. About Deployment 5

Programming with TROIA, Release 0.5.beta

usual, version numbers are ordered, for example 3.08.05 0121101 is an older version than 5.02.04 012102, 5.02.04101001 is younger than 5.02.04 090901.

602, 603 and 604 are names CANIAS ERP versions and all are designed to run on a major TROIA Platform version.(602 works on 3.08.xx xxxxxx, 603 works on 5.01.xx xxxxxx and 604 works on 5.02.xx xxxxxx). In other words;602,603,604 are not valid version names for TROIA Platform.

1.3.2 How to Follow Changes & Improvements?

Each version of TROIA Platform fixes some bugs or reveals some new features in different layers. In some cases,version upgrade requires some manual operations by administrators or developers. So you need to follow changesbetween version upgrades. All changes are listed in ReleaseNotes.txt document which is supplied/distributed witheach version. Also it is possible to read release notes document from “SYST17 - Release Notes” TROIA applicationand “Relese Notes Analyser” tool on Workbench.

6 Chapter 1. Platform Basics

CHAPTER 2

Language Basics

This section aims to introduce language and it’s basic terms. Most of subtopics will be discussed in detail in nextchapters.

TROIA is a high level programming language which is designed by IAS (Industrial Application Software) for devel-oping business applications.

As a fourth generation programming language (4GL), TROIA has strong abstraction from all hardware specific details,bytes and bits etc. It has strong ability to operate large collections of information, in a programmer-friendly manner.

TROIA codes are executed by “TROIA Interpreter” which is one of the main components of Application Server.

2.1 Understanding the Purpose

The main purpose of TROIA Language is developing business applications, so it contains too many useful features toaccess, operate and report business layer information.

Thanks to these features, TROIA reduces “the pain” caused by technical details of programming languages, so pro-grammers can focus business layer issues. Time zone, localization, multi-language support, cross platform & database,formatters, validators, api&dlls etc. are the examples of these painful technnical details.

2.2 Basic Language Elements

2.2.1 Class

TROIA is an object oriented language, so it allows programmers to define classes to perform a task or model a businessentity. Like any other object oriented language, classes have members and methods and they support inheritance andencapsulation.

Although TROIA classes able to model any kind of business entity and its behaviours, classes are usually used as a setof methods as a TROIA programming convension. TROIA Programmers usually use tables to store an entity’s fieldsbecause of advantages of using tables.

7

Programming with TROIA, Release 0.5.beta

2.2.2 Dialog

Dialog is a user interface form designed to perform a task on, like a web form or a swing dialog. Usually, dialogis a combination of simple or complex TROIA controls such as textfields, buttons, comboboxes, checkboxes, tables,charts etc.

Dialogs have methods similar to classes, so TROIA programmers define and call methods on dialogs. Additionallythey have predefined events. Events are TROIA methods which are called by TROIA runtime when a specific actionperformed like “form load”, “button clicked” etc.

2.2.3 Report

Reports are similar items to dialog, whose ui output can be redirected to a PDF file, text file or printer. Like diailogs,they have predefined events and also support defining and calling methods. Report also has controls such as labels,symbol fields, images,barcodes, shapes etc, and they are desinged in a graphical user interface.

2.2.4 Transaction

Transaction is simply a database record that defines a standalone TROIA application. The main attributes of a trans-action are name, description and start dialog.

When you call/start a transaction, start dialog of this transaction is opened automatically.

8 Chapter 2. Language Basics

Programming with TROIA, Release 0.5.beta

2.3 Some Key Terms

2.3.1 Trace

Trace is file that contains log records of running TROIA code. Using traces, developers are able to review whole flowafter code executed.

Creating trace is optional and it depends on a simple configuration which is set on runtime, so programmers do notneed to build their application in release or debug mode. It is also possible to get trace in productive environments.

As default, users are not allowed to create trace files, to access trace on/off ui items user must have “TRACE” per-mission. Trace files can be read/managed/downloaded from server using TROIA IDE trace tool or ‘DEVT31 Trace(Files)’ transaction.

Although TROIA Interpreter also supports debugging, TROIA developers usually use traces to detect and fix bugs ofTROIA Applications.

2.3.2 Convert/Save

In TROIA, coverting is parsing and compiling a TROIA item such as dialog, report, class. In this process, TROIAcodes are transformed into a binary form that can be executed by TROIA Interpreter and this binary information isstored temporarily.

Convert process is related about TROIA code and it’s flow, so it is totally language independent. It is obvious that, ifTROIA code contains parse errors, system can not create binary codes so convert operation fails.

Save process is performed after converting,in this stage binary codes are consolidated with language elements andresulting content is written to files with ‘.dlg’ & ‘.cls’ extensions. A ‘.dlg’ is a ready to run binary file that contains allinformation about a TROIA dialog (&report&component) such as controls, events, methods etc. ‘.cls’ file is similar,but its for TROIA classes.

2.4 Development Tools

2.4.1 TROIA IDE

TROIA IDE is the primary development tool of TROIA Platform. It’s main functionality is defining/modifyingTROIA items such as dialogs, classes, reports etc. Additionally, it contains useful tools such as optimization tools,code comparing tools, import/export tools etc.

To open TROIA IDE, click “MENU > TROIA” IDE menu item which is invisible as default. There are two accesslevels to TROIA IDE, first one is “read-only” which allows users only read/view existing TROIA items and codes.Second one is read-write which allows create/modify TROIA codes and items. “TROIA IDE” menu is only visible forusers which has one of this access rights.

IDE Access Permission*No accessRead-Only DEVELOPMENT(READ-ONLY)Read-Write DEVELOPMENT

(*) Permissions will be discussed in detail on next chapters.

2.3. Some Key Terms 9

Programming with TROIA, Release 0.5.beta

2.4.2 SYS & DEV Transactions

Although most of operations about TROIA development can be performed on TROIA IDE, there are useful toolswhich is implemented using TROIA.

Most used TROIA Applications are listed below, for all applications please check all transactions that starts with SYSand DEV prefix. (SYS & DEV Modules)

Name Description NoteSYST00 System Transactions & GadgetsSYST01 System Locks also an TROIA IDE toolSYST02 System MessagesSYST17 Release NotesDEVT01 Database Browser (ODBA) also available on TROIA IDE for limited operationsDEVT02 Dialog TranslatorDEVT04 Dialog-ToolsDEVT06 Hotline ManagementDEVT07 Search on Codes also an TROIA IDE toolDEVT11 Runcode Test TransactionDEVT31 Trace (Files) also an TROIA IDE toolDEVT40 Execute SQL

2.5 Hotline

Hotline is “Change Request” in TROIA Platform. Hotlines are created/managed on ‘DEVT06 Hotline Management’transaction (application) and they are stored in database.

10 Chapter 2. Language Basics

Programming with TROIA, Release 0.5.beta

It is not allowed to change any TROIA Item(dialog, class etc.) without a change request. All development tools askprogrammer to select hotline before modification and modifications are logged related with selected hotline.

2.6 Comments in TROIA

Using /* */ block is the only way to add comment to TROIA Code.

/* this is a single line comment */RESULT = THIS.CALCULATE(P1, P2);

/*first line of multiline commentsecond line of multiline comment

*/RESULT = RESULT * 3;

Line comment with // , # or any other character(s) is not supported.

2.6. Comments in TROIA 11

Programming with TROIA, Release 0.5.beta

12 Chapter 2. Language Basics

CHAPTER 3

Built-in Data Types and Structures

Like other programming languages, TROIA has built-in data types and all these types have some specific features. Thissection aims to introduce all primitive and complex data types. Details about complex data types will be discussed inrelated sections.

3.1 Built-in Data Types

Built-in data types are listed below:

INTEGER (Ex: 5, default value is: 0)LONG (Ex: 12312312, default value:0)DECIMAL (Ex: 1.32 , all floating point numbers, default value:0.0)BOOLEAN (0 or 1, default value:0)

DATETIME (Ex: 29.10.1923 16:30:30, default value:definition time)DATE (Ex: 23.04.1920, default value:definition date)TIME (Ex: 21:30)TIMES (Ex: 21:30:13)

STRING (Ex: 'Hello World', default value is empty string)STRINGBUILDER (default value is empty string)

TABLEVECTOR

BOOLEAN data type is supported on 5.01 and following releases, so usually INTEGER type is used instead ofBOOLEAN type as 1 or 0.

TROIA does not support low level types like byte, char, short, float etc.

13

Programming with TROIA, Release 0.5.beta

3.2 StringBuilder & String

STRINGBUILDER is a string like symbol type which is designed for only string building operation.

Using a STRINGBUILDER variable instead of STRING increases string concatenation performance dramatically. Toget higher performance on string concatenation, you must use APPENDSTRING command instead of ‘+’ operator.

Although there is not any other distinctive feature between STRINGBUILDER and STRING, it is not recommendedto use STRINGBUILDER type instead of STRING on regular string opreations except string concateantion.

Both STRING and STRINGBUILDER types don’t have hard-coded maximum length.

Single quote (‘) is used to limit hardcode strings.

3.3 Table

TABLE is the most important build in type of TROIA programming language. TABLE type represents a two dimen-sional in memory structure similar to database tables. We will discuss TABLE Type, related commands and functionsin next sections, in detail.

3.4 Vector

VECTOR is a kind of one dimensional array type that is able to store different types of variables. VECTOR Type,related commands and functions will be discussed in next sections, in detail.

3.5 Keywords and Identifiers

As mentioned in previous sections TROIA is a command based language. As a result of it’s structure TROIA hasmore reserved words compared to an ordinary programming language. Basically, TROIA keywords are consistedfrom command, function and predefined system variable names.

It is not allowed to use these words as variable and functions name. To avoid using TROIA keywords as vari-able/function name programmers must not use the word that has extra color in TROIA Editor.

Some of the most subtle/used TROIA identifiers are listed below.

GET IF MARKERSET RETURNVALUE COPYEXECUTE MESSAGE SELECT MARKERPOINT RETURNBREAK DECIMAL INSERT MOVE SELECTEDBREAKPOINT DELETE INSERTED NOTFOUND SETCALL DELETED ZOOMID NOTSELECTED SQLCLASS DEQUE JAVA NULL ZOOMCLEAR ENQUE VOID PAGENUM WHILECONFIRM ENTITYID LOOP RETURN SWITCHTRUE TIMES FALSE UPDATED ZOOMFYIPUT BEGINTRAN COMMITTRAN ROLLBACKTRAN BOOLEANSTRINGBUILDER

14 Chapter 3. Built-in Data Types and Structures

CHAPTER 4

Variables and Scope

4.1 Scope

Simply, scope of a variable definition is the part or range of software that definition is valid.

In TROIA there are three levels of scope: global, member, local.

4.1.1 Global Scope

If a variable defined as global variable, it is accessible from any part of the software. In TROIA, largest scope is globaland it is bounded by transaction (application). In other words, if you define a global variable, you can access it fromany dialog or class method/event providing that all items run in a transaction (application).

4.1.2 Member Scope

If a variable defined as a member variable, it is accessible in all methods of the class that is defined in, so class is thelargest boundary for a member variable.

It is not possible to access member variables using only their name outside of the class, because they are defined foreach instance of class. To access a member variable of a class instance @ operator is used. (It is similar to . operatorin other languages, INSTANCE1@XPOS : XPOS member of a class instance named INSTANCE1)

In a class method, a member variable overrides variables that isdefined for a larger scope (global).

For example if you have an integer type member variable named XPOS and a global variable with same name, allmethods use member when XPOS is accessed to do anything.

15

Programming with TROIA, Release 0.5.beta

4.1.3 Local Scope

If a variable defined as a local variable, it is accessable only in the method/event that it is defined in, so method/eventis the largest boundary for a local variable.

In TROIA, it is not possible to define a variable for a narrower scope like a block, so if you define a local variable youcan access it anywhere in method/event.

A local variable overrides other variableswhich are defined for a larger scope (member, global).

Local variables are created for each instance of the method/event like any other language (think on recursive calls).

A static local variable is a variable that is defined for onceand shared by all instances of method.

Static local variables are not supported in TROIA.

Function parameters are local symbols that, programmer can access them only inside the method using parametername.

4.2 Defining Variables

In TROIA, there are multiple variable definition methods. The first and most common method is using data definitioncommands such as LOCAL, GLOBAL, MEMBER and OBJECT.

Another common method is using controls on dialogs. For example, when a dialog containing textfield is opened,system automatically defines a global string symbol which has same name with textfield. They are called as “controlsymbols”. All control symbols are global. Each control type/subtype has a corresponding variable type to defineautomatically. Controls, types and subtypes will be discussed in next sections detailly.

Additionally, there are (limited) special commands which are able to define fixed type global variables if target vari-ables do not exist. (ex:SELECT, TABLE), however this method is not recommended because of readibility.

4.3 Variable Definition Commands

4.3.1 GLOBAL Command

GLOBAL command defines a global variable with given data type. Defining multiple variables with a single GLOBALcommand is allowed, even if data types are different.

/* define a single variable */GLOBAL:

STRING STRINGVAR1;

/* define multiple variables */GLOBAL:

STRING STRINGVAR1,STRING STRINGVAR2,TABLE TABLEVAR1,INTEGER INTVAR,MYCLASS MYCLASSREC;

16 Chapter 4. Variables and Scope

Programming with TROIA, Release 0.5.beta

4.3.2 MEMBER Command

MEMBER command defines a member variable which is accessible from all methods of the class. It can be usedin only class methods including constructor and others, so using MEMBER command in dialogs, reports (etc.) is aprogramming error. It is possible to define multiple members variables in a single MEMBER command even if datatypes are different.

/* define a single member */MEMBER:

STRING STUDENTNAME;

/* define multiple members */MEMBER:

STRING FIRSTNAME,STRING LASTNAME,TABLE ITEMLIST,INTEGER XPOSITIONMYCLASS MYCLASSREC;

All kind of data types such as STRING, INTEGER, TABLE or TROIA classes can be defined as member variable.

TROIA Classes and its constructors (_CONSTRUCTOR & _VARIABLES) will be discussed detailly in next sections.

4.3.3 LOCAL Command

LOCAL Command defines a local variable with given data type. Similar to other data definition commands it ispossible to define multiple variables with a single LOCAL command.

/* define a single local variable */LOCAL:

STRING STRINGVAR1;

/* define multiple local variables */LOCAL:

STRING STRINGVAR1,STRING STRINGVAR2,TABLE TABLEVAR1,INTEGER INTVAR,MYCLASS MYCLASSREC;

4.3.4 OBJECT Command

OBJECT command is the oldest and most used variable definition command. When a variable is defined with OBJECTcommand, it’s scope depends on data type of the variable and which method that OBJECT command is used in.

The main parameter is data type to decide scope. Tables and class instances are always global. But scope of simpletype (STRING, DECIMAL, LONG, INTEGER,. . . ) variables depends on the method that they defined in. Simpletyped variables are defined as global if definition is made on a dialog/report method or event, if method is a classconstructor ( _CONSTRUCTOR & _VARIABLES) scope is member, but if method is a regular class method simplevariables are defined as local.

Here is a simple table that shows how OBJECT command decides scope, depending on data type and method type.

4.3. Variable Definition Commands 17

Programming with TROIA, Release 0.5.beta

Dialog/Report Events&Methods Class Constructor&Variables Class MethodsTable Global Global GlobalClass Instance Global Global GlobalSimple Types Global Member Local

It is also supported multiple variable definitions on a single OBJECT command.

/* suppose that this is a dialog method, think on its scope */OBJECT:

STRING STRINGVAR1;

/* suppose that this is a class method, think on their scope */OBJECT:

STRING STRINGVAR1,STRING STRINGVAR2,TABLE TABLEVAR1,INTEGER INTVAR,MYCLASS MYCLASSREC;

At first glance, it is a little bit hard to decide scope of a variable that is defined by OBJECT command. As a result ofthis fact, using GLOBAL, LOCAL and MEMBER instead of OBJECT is recommended to increase readibility. (Un-fortunately, you must know that OBJECT is the most used data definition command on existing TROIA applications.)

4.4 System Variables

System variables are global and predefined variables that stores information about system, user session or some specificactions to use these values on TROIA level. Most of system variables are read-only and their data types depends onvariable’s purpose.

Some examples of system variables are listed below, for more please view TROIA Help.

SYS_CURRENTDATE : Returns long value of now.SYS_CLIENT : Client value that is used while login.SYS_LANGU : Language value that is used while login.SYS_USER : Username of current user.SYS_VERSION : TROIA platform server version.SYS_AFFECTEDROWCOUNT : Number of affected rows after db update/insert/delete.SYS_CURRENTDIALOG : Name of current dialog.CONFIRM : Selected value after a confirm or option message.SQL : Latest SQL Query that is sent to database.

It is not allowed to define variables which have same name with a system variable. Most of them starts with SYSprefix, although there are exceptions such as SQL, CONFIRM etc.

Defining variables that start with 'SYS' prefixis not a good programming practice.

18 Chapter 4. Variables and Scope

Programming with TROIA, Release 0.5.beta

4.5 Some Facts About Defining Variables

4.5.1 Using Undefined Variables

Using undefined variables do not cause compiling errors because of TROIA’s structure (data transfer between dialogs).If a variable is used before it is defined, it returns its name as value like a string variable that has same value with itsname. Although undefined variables are similar to string variables, we must know that they are not STRING.

LOCAL:STRING MYVAR;

MYVAR = MYUNDEFINEDVAR;

/* MYVAR's value: MYUNDEFINEDVAR */

4.5.2 Defining Same Variable More Than Once

The first way of defining same variable more than once is writing different definition commands which define samevariable. In this case second command ignores the definition. Here is the sample:

OBJECT:STRING RESULT,STRING MYVAR;

MYVAR = 'Hello World';

OBJECT:STRING MYVAR;

RESULT = MYVAR;

/* RESULT's value: Hello WorldSecond OBJECT command ignored the MYVAR definition. */

Second method is running same definition command multiple times. In a loop or an event which is triggered multipletimes. In this case, the definition command which defines the variable initializes it (sets its default value, to see thedefault values please see data types section).

start loop block that runs twice:OBJECT:

STRING MYVAR;

RESULT = MYVAR;

MYVAR = 'Hello World';end loop

OBJECT:STRING MYVAR;

RESULT = MYVAR;

/* in first and second iteration RESULT's value is empty string.after last assignment RESULT's value: Hello World */

4.5. Some Facts About Defining Variables 19

Programming with TROIA, Release 0.5.beta

Looping and assignments will be discussed detailly in next sections, in this section please focus on defining samevariable in multiple times.

Third method is running a data definition command for a variable that is already defined as control symbol. This caseis ignored by the interpreter.

4.5.3 To Learn Data Type of a Variable

In some cases, programmers may need data type of a variable. In TROIA, GETVARTYPE() system func-tion(predefined function) returns type of given variable as string.

For undefined variables GETVARTYPE returns ‘UNKNOWN TYPE’ even if undefined variables are similar to strings.Here is an example of GETVARTYPE() function.

OBJECT:STRING STRINGVAR,INTEGER INTVAR,STRING RESULT;

RESULT = GETVARTYPE(STRINGVAR); /* RESULT : 'STRING' */RESULT = GETVARTYPE(INTVAR); /* RESULT : 'INTEGER' */RESULT = GETVARTYPE(NOVAR); /* RESULT : 'UNKNOWN TYPE' */

4.5.4 Naming & Conventions

• Although using numbers in variable names is supported, using a number as a first character is not recommended.

• Defining a variable which has same name with a TROIA command, function, system variable or data type isconsidered as TROIA coding error.

• As a TROIA programming convention TROIA codes are written in upper-case, so using upper-case for variablenames is recommended.

• Defining all variables as global is not a good programming convention, variables must be defined narrowestscope that is possible, to save memory, eliminate possible bugs and readability.

20 Chapter 4. Variables and Scope

CHAPTER 5

Operators and Expressions

5.1 Operators

Operators are the commands which tells the TROIA interpreter to do some mathematical,relational and logical opera-tions using their operands.

5.1.1 Arithmetic Operators

Operator Meaning+ add, string concatenate- subtract* multiply/ divide% module^ power

5.1.2 Relational Operators

Operator Meaning== is equal to!= is not equal to> is greater than>= is greater than or equal to< is less than<= is less than or equal to

21

Programming with TROIA, Release 0.5.beta

5.1.3 Logical Operators

In TROIA codes, there are two set of logical operators. The first set is about TROIA expressions that is used on if,where, loop etc. conditions.

Operator Meaning! not&& and|| or

Elements of second logical operator set are OR, AND and NOT. This operators are not elements of TROIA language,they are just used in SQL commands that written inside TROIA codes. This operators are not supported on if, whereor loop statement conditions etc. Although these are not used as logical operators, it is not recommended to definevariables with this names.

5.2 Assignment

There are two assignment methods in TROIA. First method is using MOVE command, which does not support ex-pressions for source value.

MOVE 'Hello World' TO STRINGVAR1;MOVE STRINGVAR1 TO STRINGVAR2;MOVE 3 TO INTEGERVAR1;

MOVE 3 + 1 TO INTEGERVAR1; /* not valid, no expression support*/MOVE THIS.F1() TO INTEGERVAR1; /* not valid, no expression support*/

Second assignment method is using = operator. This method also supports expressions in right hand side.

STRINGVAR1 = 'Hello World';STRINGVAR1 = STRINGVAR1 + 'Hello World';INTEGERVAR1 = 3 * (5 + INTEGERVAR1);

INTEGERVAR1 = ABS(5 - 10);

5.3 Expressions

Simply an expression is right hand side of = operator and it can be consisted of even a single variable or combinationsof multiple operators and function calls. Expressions are not for only using assignment operations. They are also usedon function calls as a parameter or on RETURN command when you need to return result of an expression. Here is asimple list of mostly used commands that support expressions, details of this commands discussed in next sections.

on function call as function parameteron IF command conditionon WHILE command conditionon LOOP command conditionon RETURN command

. . .INTEGERVAR1 = THIS.F1(4+INTEGERVAR2, 'parameter value', P3);

(continues on next page)

22 Chapter 5. Operators and Expressions

Programming with TROIA, Release 0.5.beta

(continued from previous page)

RETURN INTEGERVAR1 + 5;

5.3.1 THIS Keyword

One of the most used elements of expressions is function call. In TROIA language, specifying instance name ofclass/dialog is a must. THIS keyword is used for indicating same instance. In other words, if you want to call anothermethod of the class/dialog in its method you must use THIS keyword.

A function calls which does not include instance name is considered as a system function. System functions arepredefined functions to ease some mostly used operations like mathematical operations, string operations etc.

Most used system functions will be discussed in related sections, for all system functions please see TROIA Help.

CUSTREC.CALCULATE(P1); /* call CALCULATE method of CUSTREC object */THIS.SEARCH(P1); /* call SEARCH method of same class/dialog */RESULT = ABS(5 - 10); /* call a system function */

5.3.2 Some facts about calling functions/methods

Sending more parameters than called method requests is not considered a TROIA programming error. System justignores extra parameters. If you send less parameters, system assigns default values to missing parameters.

If you want to pass default values for parameters except last parameter, you must leave parameter empty.

RESULT = MYINS1.CALCULATE(P1,,,P4);

/* send default values to P2 and P3 */

In system function calls, sending less or more parameters is not recommended, if it is not documented in function help.

5.4 Type Conversion and Casting

In TROIA, simple typed variables are casted automatically, so there is not an extra operator or method for type casting.For example, you can directly assign an double to string, or a string to a double symbol. If system fails to converttypes assigns default value of destination symbol.

Type casting is not supported for complex types such as TABLE, VECTOR or class instance. Actually, assigning thiscomplex types is not a usual method, because TROIA has special commands for data transfer between complex types,especially for tables.

OBJECT:STRING SOURCESTR,DOUBLE DESTDOUBLE,INTEGER DESTINT,DATE DESTDATE,LONG DESTLONG,DATETIME DESTDATETIME;

SOURCESTR = '6.0';

DESTDOUBLE = SOURCESTR; /* double is now 6.0 */

(continues on next page)

5.4. Type Conversion and Casting 23

Programming with TROIA, Release 0.5.beta

(continued from previous page)

DESTINT = DESTDOUBLE; /* integet is now 6 */

SOURCESTR = '25.11.1984';

DESTDATE = SOURCESTR; /* date is now 25.11.1984 */DESTLONG = DESTDATE; /* long is now long value of given date */DESTDATETIME = DESTLONG; /* datetime is now 25.11.1984 00:00:00 */SOURCESTR = DESTDATETIME; /* string is now '25.11.1984 00:00:00' */

Here is as simple table that shows casting operation between source and destination simple types. In this table x-axisshows destination variable type and y-axis shows source variable type.This conversion table is valid for both of MOVEand assignment operator.

DESTINATION TYPESTRING INTEGER LONG DECIMAL DATE DATETIME

STRING parse,if fails-> 0

parse,if fails-> 0

parse,use . assep. if fails->0.0

parse, if failsset NULL-DATE(1)

parse, if failsset NULL-DATE(2)

INTEGER convert tostring

no extra oper-ation, just as-sign

assign int val,use .0 as frac-tional part

add valueas ms. to01.01.1970

add valueas ms. to01.01.197000:00:00

LONG convert tostring

assign, if ex-ceeds set->0(??)

assign longval use .0as fractionalpart

add valueas ms. to01.01.1970

add valueas ms. to01.01.197000:00:00

DECIMAL convert tostring

assign onlywhole part

assign onlywhole part

add wholepart as ms. to01.01.1970

add wholepart as ms.01.01.197000:00:00

DATE convert tostring withdd.MM.YYYYpattern

assign longvalue from01.01.197000:00:00

assign longvalue from01.01.197000:00:00

not allowedassigns 0

uses00:00:00as hour part

DATETIME convert tostring withdd.MM.YYYY

HH:mm:ss

assign longvalue from01.01.197000:00:00

assign longvalue from01.01.197000:00:00

not allowedassigns 0

assign onlydate part

(?) NULLDATE : .

(??) Limits of Integer : .

5.5 Exercise 1: Integer Arithmetic

Here is a simple arithmetic example. Please think on this example and try to find why DECIMALVAR1 and DECI-MALVAR2 values are different even if divide operation is same.

24 Chapter 5. Operators and Expressions

Programming with TROIA, Release 0.5.beta

OBJECT:INTEGER INTEGERVAR1,DECIMAL DECIMALVAR1,DECIMAL DECIMALVAR2;

INTEGERVAR1 = 3;INTEGERVAR1 = INTEGERVAR1 * (1 + 2);INTEGERVAR1 = INTEGERVAR1 ^ 2 + 4;INTEGERVAR1 = INTEGERVAR1 % 60;

DECIMALVAR1 = INTEGERVAR1 / 6.0;DECIMALVAR2 = INTEGERVAR1 / 6;

5.5. Exercise 1: Integer Arithmetic 25

Programming with TROIA, Release 0.5.beta

26 Chapter 5. Operators and Expressions

CHAPTER 6

Flow Control

6.1 IF Statement

Like other programming languages, IF statement is the main and most used conditional statement in TROIA language.TROIA Interpreter decides to run or ignore IF block depending on conditional expression result. Here is the syntax ofIF Statement in TROIA:

IF condition THENblock

ENDIF;

As it is obvious on syntax above, there is not any kind of enclosing brackets both for condition and true block, threekeywords ( IF, THEN, ENDIF) enclose ‘condition’ and ‘block’. ‘condition’ is an expression which is a combinationof relational and logical operators and function calls. ‘block’ is another TROIA code block. Here is an example:

IF A > 1 && A < THIS.GETMAXVALUE(P1) THENRESULT = 'A is between one and maximum value';

ENDIF;

In TROIA all logical expression is executed even if first condition is enough to calculate logical expression’s re-sult, unlike most programming languages. Lets say A is 0 before the IF statement, so A > 1 condition returnsfalse. If one of && (and) operator’s operands is false, result is always false. TROIA Interpreter executes A <THIS.GETMAXVALUE() condition, although condition result is obvious. Behaviour is same for || (or) operatorwhen its first operand is true.

6.1.1 IF-ELSE Statement

ELSE keyword is used to define another block that will be executed when ‘if condition’ is false.

IF A == 1 THENRESULT = 'A equals to one';

ELSE

(continues on next page)

27

Programming with TROIA, Release 0.5.beta

(continued from previous page)

RESULT = 'A is less or more than one';ENDIF;

ELSE IF is not supported in TROIA, to run multiple conditions you must use nested if blocks. Here is a valid ELSEIF example:

IF A == 1 THENRESULT = 'A equals to one';

ELSEIF A < 1 THEN

RESULT = 'A is less than one';ELSE

RESULT = 'A is more than one';ENDIF;

ENDIF;

6.2 SWITCH Statement

SWITCH statement is another way of defining conditional blocks. Here is the syntax of SWITCH statement in TROIA:

SWITCH itemCASE value[,value]:

case block 1CASE value:

case block 2..CASE value:

case block nDEFAULT:

default blockENDSWITCH;

SWITCH Statement allows using only variables as switch item so you can not use an expression. SWITCH commandcompares item’s text value with string values of cases defined with CASE keyword, so programmers must considerstring values of cases and given item.

If you want to execute same block for more than one CASE values you can list values in a single case using comma(,) as separator. In TROIA, BREAK keyword is not supported and required in SWITCH statements. Here is a simpleexample of SWITCH statement:

OBJECT:STRING VAR,STRING RESULT;

VAR = '8';

SWITCH VARCASE 5:

RESULT = 'It is five';CASE 6:

RESULT = 'It is six';CASE '7','8':

RESULT = 'It is seven or eight';

(continues on next page)

28 Chapter 6. Flow Control

Programming with TROIA, Release 0.5.beta

(continued from previous page)

DEFAULT:RESULT = 'I do not know what it is.';

ENDSWITCH;

6.3 WHILE Loop

While loop is a flow-control statement that allows executing a block of code repeatedly based on a condition. Likemost of programming languages, TROIA also supports while loops. Here is the syntax of while loop in TROIA.

WHILE conditionBEGIN

blockENDWHILE;

Here is a simple example of WHILE command that tries to find if numbers are even or odd.

OBJECT:INTEGER VAR,STRING RESULT;

VAR = 1;RESULT = '';

WHILE VAR < 10BEGIN

IF VAR % 2 == 0 THENRESULT = RESULT + VAR + ':even, ';

ELSERESULT = RESULT + VAR + ':odd, ';

ENDIF;

VAR = VAR + 1;ENDWHILE;

In most programming languages there are alternative looping statements like for, foreach, even if programmers areable to implement same behaviour using different looping statements. TROIA does not support FOR and FOREACHstatements.

6.4 LOOP Command

As mentioned before, TABLE is the most important data type of the language and programming approach is mostlydepends on tables. So TROIA supports many options, commands, functions etc. to manipulate tables. One of thistable specific commands is “LOOP” which is an alternative looping command for only tables.

The LOOP command has many options such as condition or performance issues, but “for now” simply it can thoughtof as a kind of “foreach row”.

LOOP AT tableBEGIN

blockENDLOOP;

6.3. WHILE Loop 29

Programming with TROIA, Release 0.5.beta

We will discuss LOOP command and other table options in next sections. For now we must know only its basic usage.As it is obvious in syntax below, you must specify the name of table variable to loop on and the code block that willbe executed for each row.

6.5 Other Looping Options

Another looping option in TROIA is PARSE command which allows you loop on strings which is splitted by a givenseparator(delimiter). This command also will be discussed in next sections.

6.6 BREAK & CONTINUE Statements

In some cases within loop/while block, there is need to skip the remaining part of loop/while block and continuewith the next iteration of the loop. To cancel remaining part of loop and jump to the beginning of loop/while block,CONTINUE statement is used.

Similarly, BREAK statement is used to cancel whole loop.

Here is a simple example that combines BREAK and CONTINUE statements to find list and total of odd numbersbetween 0 and 10. In this example, condition of WHILE loop is always TRUE, so at first glance this loop is an infiniteloop. But in first IF block, code limits re-execution count of loop block with BREAK command. In second IF block,condition checks whether value is even and if value is even CONTINUE skips remaining parts of block and jumpsbeginning of while block.

OBJECT:INTEGER INDEXNUM,INTEGER ODDNUMBERSTOTAL,STRING ODDNUMBERS;

ODDNUMBERSTOTAL = 0;INDEXNUM = 0;ODDNUMBERS = '';

WHILE 1 == 1BEGIN

INDEXNUM = INDEXNUM + 1;

/* if block 1 */IF INDEXNUM == 10 THEN

BREAK;ENDIF;

/* if block 2 */IF INDEXNUM % 2 == 0 THEN

CONTINUE;ENDIF;

ODDNUMBERSTOTAL = ODDNUMBERSTOTAL + INDEXNUM;ODDNUMBERS = ODDNUMBERS + INDEXNUM + ',';

ENDWHILE;

Please run the example above and try to find values of ODDNUMBERS and ODDNUMBERSTOTAL variables. Anddiscuss the new behaviour of code, when you swap the orders of “if block 1” and “if block 2”.

30 Chapter 6. Flow Control

Programming with TROIA, Release 0.5.beta

6.7 Exercise 1: Fibonacci Numbers

Fibonacci Numbers is a number sequence that each element is the sum of previous two items. In this example we willtry to calculate fibonacci sequence whose maximum item is less than 100.

OBJECT:INTEGER NUMBER1,INTEGER NUMBER2,INTEGER NUMBER3,STRING LISTOFNUMBERS;

OBJECT:INTEGER MAXNUM;

MAXNUM = 100;NUMBER1 = 1;NUMBER2 = 1;LISTOFNUMBERS = '';

WHILE 1 == 1BEGIN

NUMBER3 = NUMBER1 + NUMBER2;

IF NUMBER3 > MAXNUM THENBREAK;

ENDIF;

NUMBER1 = NUMBER2;NUMBER2 = NUMBER3;LISTOFNUMBERS = LISTOFNUMBERS + NUMBER3 + ';';

ENDWHILE;

6.8 Exercise 2: Factorial

Calculating factorial of a given number with a simple while loop. This example can be tested in test transaction, suchas “DEVT11 - Runcode Test Transaction”

LOCAL:INTEGER NUMBER;

LOCAL:INTEGER FACTORIAL,INTEGER INDEXNUM;

NUMBER = 4;

INDEXNUM = 1;FACTORIAL = 1;

WHILE INDEXNUM <= NUMBERBEGIN

FACTORIAL = FACTORIAL * INDEXNUM;INDEXNUM = INDEXNUM + 1;

ENDWHILE;

6.7. Exercise 1: Fibonacci Numbers 31

Programming with TROIA, Release 0.5.beta

Another option is writing a recursive method (simply, a function that calls itself). For now, you can ignore the question“How can i define a method?”, this will be discussed in next sections. Just focus on function call, recursivity and looprelation and discuss the scope of variables that is defined in a recursive function (MINUS1)

/* this is method's code */PARAMETERS:

INTEGER PNUM;

LOCAL:INTEGER MINUS1;

IF PNUM <= 1 THENRETURN 1;

ELSEMINUS1 = PNUM - 1;RETURN PNUM * THIS.FACTORIAL(MINUS1);

ENDIF;

/* this is the code that calls method */OBJECT:

INTEGER FACTORIAL;

FACTORIAL = THIS.FACTORIAL(3);

32 Chapter 6. Flow Control

CHAPTER 7

Strings / String Manipulation

String is a kind of sequence of characters/digits and it is one of most common types of programming languages. Thissection aims to introduce some key features of string type and most used string manipulation functions.

7.1 Some Facts About Strings

In TROIA, STRING type is used for both string and char type compared to other programming languages such as javaetc. There is not hard-coded maximum length (character-limit) of string typed variables and hard code strings, so ifyou have trouble about maximum character length, possibly its about your length of your database table, table columnor editor length etc.

String variables are able to store all kind of characters and digits.

As mentioned previous sections, undefined variables are returns their name. It seems they are STRING variables butundefined variable’s are not string, they are just undefined symbols that stores their name.

Single quote character (‘) is used to limit hard code strings in TROIA code.

7.2 Escaping & Special Characters

To insert a meaningful character (such as ‘) to a hard code string, escape character are used in different program-ming languages. Escape character changes the interpretation method of following characters. For example ‘ (singlequote) character limits hard code strings, when programmer wants to insert a single quote, he/she must use an escapecharacter.

TROIA does not support escape characters for hard code strings. Instead of escaping, TOCHAR() system functionis used to insert special characters to a hard code string. TOCHAR() function gets decimal ASCII correspondent ofrequested character and returns a single character as string. For example programmer must pass 39 to get a singlequote character or 10 for a newline character.

33

Programming with TROIA, Release 0.5.beta

OBJECT:STRING STRVAR;

STRVAR = 'First line, it contains ' + TOCHAR(39) + ' (single quote).';STRVAR = STRVAR + TOCHAR(10) + 'Second line.';

/*value of STRVAR must like:

First line, it contains ' (single quote).This is second line.

*/

7.3 Basic String Functions

Here is system functions that returns basic information about string variables:

STRLEN Returns the length of given stringSTRPOS() Returns index of given string inside anotherISNUMERIC() Check string whether all characters are numericSTRLIKE() Compares string with given pattern like SQL LIKE op.

and most used system functions to modify strings:

TRIM() Removes white spaces from the beginning and the end.REPLACE() Replaces a given string with anotherSTRSTR() Returns substring of string with index and lengthLOWERCASE() Returns lowercase of given string with given languageUPPERCASE() Returns uppercase of given string with given language

For more string manipulation functions or more information about these functions (like parameter order and returntypes etc), please see String Manipulation section of TROIA Help.

7.3.1 Base64 Encoding/Decoding

Base64 is a kind binary-to-text encoding scheme that represent binary data in an ASCII string format. Resulting stringcontains only 64 kind of characters which contains only a-z, A-Z, 0-9, +, / characters so the resulting string can bestored on or transferred between ‘ASCII only’ environments.

To encode strings to Base64 BASE64ENCODE() system function is used, to convert a base64 string to a troia stringBASE64DECODE() system function is used. Both encoding and decoding requires an encoding like ‘UTF-8’ etc toconvert string to binary or binary to string. For more information about BASE64ENCODE() & BASE64DECODE()functions please see TROIA help documents.

Here is an encoding and decoding example:

OBJECT:STRING STRVALUE,STRING STRBASE64,STRING STRDECODED;

(continues on next page)

34 Chapter 7. Strings / String Manipulation

Programming with TROIA, Release 0.5.beta

(continued from previous page)

STRVALUE = 'Programming With TROIA';STRBASE64 = BASE64ENCODE(STRVALUE, 'UTF-8');STRDECODED = BASE64DECODE(STRBASE64, 'UTF-8');

7.3.2 Hashing Strings

Hashing is an operation that maps an arbitrary size data to fixed size. Resulting hash value can not be decoded tooriginal data, because hash values of different input values can be identical. For example length of given string can bethought as a kind of hashing. Most used hashing algorithms are MD5,SHA1, MD2 etc.

In TROIA, GETDIGEST() function is used to hash using multiple algorithms. For more information and supportedalgorithms please see TROIA Help.

OBJECT:STRING STRVALUE,STRING MD5HASH,STRING SHA1HASH;

STRVALUE = 'Programming With TROIA';MD5HASH = GETDIGEST(STRVALUE, 'MD5');SHA1HASH = GETDIGEST(STRVALUE, 'SHA1');

7.4 String Concatenation

As default + operator is used to concatenate strings in TROIA, but it is not recommended to use + operator to buildlarge strings because of performance issues.

OBJECT:STRING FINALSTRING;

FINALSTRING = 'Hello ' + ' World.';

Performance problem of string concatenation is not about only ‘+’ operator, its also about STRING type. To solveperformance issues, programmers must use STRINGBUILDER data type which is mentioned in previous sections.Defining a STRINGBUILDER is not different from defining a STRING variable. To append/concat a given stringto a STRINGBUILDER, APPENDSTRING command is used. Here is STRINGBUILDER & APPENDSTRINGequivalent of previous example.

OBJECT:STRINGBUILDER SBFINALSTRING;

APPENDSTRING 'Hello' TO FINALSTRING;APPENDSTRING ' World' TO FINALSTRING;

STRINGBUILDER is designed for only hi-performance string building operations, so it is not recommended to useSTRINGBUILDER object instead of STRING.

To benchmark using STRING/+ and STRINGBUILDER/APPENDSTRING you can write a while loop that makes onethousand concat operation.

7.4. String Concatenation 35

Programming with TROIA, Release 0.5.beta

7.5 Looping on Strings: PARSE Command

To split a string into tokens (with newline or with a specific delimiter character) and do something for each token,PARSE command is used. As it is obvious PARSE command is a kind of loop statement, so BREAK and CONTINUEstatements also works in parse command. Here is the basic syntax:

PARSE {mainstring} INTO {token} [DELIMITER {delimiter}]BEGIN

parse blockENDPARSE;

Delimiter is an optional parameter; if it is not specified newline (linefeed, n) character is used and main string issplitted into lines.

The sample below tries to calculate length of each line.

OBJECT:STRING STRMAINSTRING,STRING STRTOKEN;

OBJECT:INTEGER NLINECOUNTSTRING STRRESULT;

NLINECOUNT = 0;STRRESULT = '';

STRMAINSTRING = 'I do not trust words.';STRMAINSTRING = STRMAINSTRING + TOCHAR(10) + 'I trust actions.'

PARSE STRMAINSTRING INTO STRTOKENBEGIN

NLINECOUNT = NLINECOUNT + 1;

STRRESULT = STRRESULT + 'Line ' + NLINECOUNT + ':' + STRLEN(STRTOKEN);STRRESULT = STRRESULT + ' char(s).' + TOCHAR(10);

ENDPARSE;

7.6 Exercise 1: Basic String Functions

Here is a simple string functions example, please try to find return values after each function call.

OBJECT:STRING STRMESSAGE,INTEGER NINDEX;

STRMESSAGE = ' Hello TROIA ' + TOCHAR(10);

/* remove whitespaces */STRMESSAGE = TRIM(STRMESSAGE);

/* replace word 'TROIA' with 'world' */STRMESSAGE = REPLACE(STRMESSAGE, 'TROIA', 'World');

(continues on next page)

36 Chapter 7. Strings / String Manipulation

Programming with TROIA, Release 0.5.beta

(continued from previous page)

/* calculate index of 'world' */NINDEX = STRPOS(STRMESSAGE, 'World');

/* get first 5 character*/STRMESSAGE = STRSTR(STRMESSAGE, 0, 5);

7.7 Exercise 2: List Numeric Tokens

OBJECT:STRINGBUILDER SB,STRING STRNEWLINE,STRING MAINSTRING,STRING TOKEN;

SB = '';STRNEWLINE = TOCHAR(10);MAINSTRING = '1|A|2|B|3|C|4|D|5|E';

PARSE MAINSTRING INTO TOKEN DELIMITER '|'BEGIN

IF !ISNUMERIC(TOKEN) THENCONTINUE;

ENDIF;

APPENDSTRING TOKEN TO SB;APPENDSTRING ' is a number.' TO SB;APPENDSTRING STRNEWLINE TO SB;

ENDPARSE;

7.7. Exercise 2: List Numeric Tokens 37

Programming with TROIA, Release 0.5.beta

38 Chapter 7. Strings / String Manipulation

CHAPTER 8

Dialog Basics

8.1 Introduction

Dialogs are user interface forms that user can perform a specific task on. A dialog is consisted of it’s basic dialoginformation, events/methods and the controls on it. “Basic information” is just its size, background color name and itis enough to define an empty dialog.

The main components of a dialog are controls on it. Controls are simple items that is used for user interaction, such asbuttons, textfields, comboboxes, graphics,tab panes, images etc.

Also, It is possible to define methods on dialogs and call these methods from others to add behavior to dialogs. Someof this methods has special names and called by TROIA interpreter. These kind of methods are called “dialog events”.We will discuss dialog events, all types control and their events in next sections.

8.1.1 Creating/Editing Dialogs

TROIA IDE is used to create/edit TROIA dialogs. To open TROIA IDE, you must click “TROIA IDE” item on topmenu of java client. If there is not a TROIA IDE item on your menu please check your development rights which wediscussed on previous sections.

To create a new dialog, you must click TROIA IDE-> New -> New Dialog on menu and fill the new dialog form.

In new dialog form you, must select a hotline (change request) and enter a valid dialog name. A valid dialog namemust be unique and at least four characters length, so you can not create a new dialog whose name is shorter than fourcharacters or same with an existing dialog.

The last field in new dialog form is “Base Dialog”. It is possible to inherit dialogs, so if your dialog has a base dialogyou must enter/select the name of base dialog. For now, we can leave “Base Dialog” field empty, we will discussinheritance in next sections.

After you click “OK” button on new dialog form, IDE creates a new dialog and opens design window.

39

Programming with TROIA, Release 0.5.beta

40 Chapter 8. Dialog Basics

Programming with TROIA, Release 0.5.beta

8.1.2 How Dialogs are Stored?

All development information (codes, design etc) about dialogs are stored in database tables.

SYSDIALOGS Stores dialog information such as size, name etc.SYSDLGTEXTS Stores caption of dialog related with language.SYSDLGCODES Stores events & methods of dialog and dialog controlsSYSDLGFUNCTEXTS Strores the caption of methods related with language.SYSCONTROLS Stores control information such as size, position etc.SYSCTLTEXTS Stores captions of controls related with language.

8.1.3 Binary Format of Dialogs

With “Convert” operation, binary/compilation data is built. This data contains all kinds of dialog information such asname, size, controls, control positions, functions and events etc.

“Save” operation writes binary data and dialog texts on given language to a “.dlg”. It is obvious that dialog files arelanguage dependent because they contains dialog and control texts for a languge.

Dialog files are stored in a folder named user file path. User file path is the folder that user loads all binary infor-mation(dialog, class, report) and it is configured for each user on SYST03. Here is the format and location of dialogfile.

format : {userfilepath}\jdlg\{module}\{languagecode}{dialog}.dlg

Example:SALT01D001 in English> {userfilepath}\jdlg\SAL\ET01D001.dlgSALT01D002 in Deutsch> {userfilepath}\jdlg\SAL\DT01D002.dlg

System reads dialog file when dialog is opened. On runtime system does not access development tables.

8.2 Basic Dialog Events

Events are predefined methods that called by system automatically when a specific action occurs. For example;“button clicked” is an event called automatically when user click a button. Programmers must implement the event todo something on related action occurs.

Here is the most used events of dialogs:

BEFORE First event on dialog open, fired after controls defined (dialog is not visibleAFTER Fired after “BEFORE” event, dialog is still not visible.ONSHOW Fired after “AFTER” event, when dialog is visible on user interface.

In some cases, programmers may need calling dialog events manually. Calling a dialog method is not different fromcalling a dialog method.

THIS.AFTER();THIS.ONSHOW();

Additionally, dialogs have ONTIMER, TRANSCALLED, BEFOREEXTENSION events which are called for somespecific actions. This events will be discussed on related sections.

8.2. Basic Dialog Events 41

Programming with TROIA, Release 0.5.beta

8.3 Basics of Controls

Controls are the ui items such as buttons, textfields, comboboxes etc. Programmers define appropriate controls ondialogs to create interaction with user. All controls have predefined events which is called by interpreter when userperforms a specific action like clicking button or changing value of a textfield. A dialog control is defined by two mainfeatures its type and subtype and both of type and subtype information is stored on SYSCONTROLS table. “Type”defines the main group of control (button or textfield). “Subtype” changes only one or two features control such asevent count, appearance, symbol type etc.

To define a control on a dialog, programmer drags required control from “Toolbox Explorer” to dialog and modifiescontrol features due to process that is imlemented. Location, size, visibility, disable/enable, background color, fore-ground color are the main and common features of all type of controls. Additionally, each control type has its ownfeatures. It is possible to modify control features using “Property Explorer” and TROIA code due to workflow. Hereis a new button control and its events and features:

To add behaviour to defined control, programmer must implement one or more events of control. Each control typehas also its own events. They are listed in right click menu on dialog design screen and at the bottom of “PropertyExplorer” (when control selected).

8.3.1 Sample Control: TextField

TextField is the main type of all text input controls, each subtype defines its own control symbol in a predefined datatype. Also each subtype has its own data input behaviour such as built-in key listener, data/input validator, zooming.

Here is the most used subtypes of TextField and control symbol types.

42 Chapter 8. Dialog Basics

Programming with TROIA, Release 0.5.beta

Sub Type Type Key FeaturesText STRING Default subtype, to get input for short strings.Editor STRING to get large textsFile Chooser STRING to get a file path, built-in file chooserTroia Editor STRING to get/show TROIA code as string, built in formatterPassword STRING to get/show passwordsDecimal DECIMAL to get/show decimal valuesLong LONG to get/show long valuesInteger INTEGER to get/show integer valuesDate DATE to get/show date , built-in date chooser as zoomDatetime DATETIME to get/show datetime , built-in datetime chooser zoom

Color, Money, Quantity, Percent, Factor, Custom Editor, Icon Chooser, Duration, HTML, HTML Viewer, Link, Phone,Rich Editor, Time,Times are the other subtypes of TextField Control. Please test these subtypes on dialog and see theirfeatures and variables that is defined by control.

Here is the basic events of a textfield.

Event Description & Event FireGainFocus When user focuses on a textfield.LoseFocus When user focuses on another control after textfield.TextChanged If user changes value of textfield, before LoseFocus.

Textfields also have additional events named ZoomBefore/ZoomAfter, Drag/Drop and RightClickMenu events. Wewill discuss this kind of event in next sections.

8.3. Basics of Controls 43

Programming with TROIA, Release 0.5.beta

8.4 Switching Between Dialogs

There are two main methods of opening dialogs. First one is defining a dialog as start dialog of a transaction (applica-tion). In this method system automatically calls start dialog when transaction opened. We will discuss how to define atransaction and a start dialog in next section.

Second method is calling a dialog via TROIA codes. To call a dialog using TROIA, “CALL DIALOG” command isused. For example, if we want to call a dialog when user clicks a button on our first dialog we must implement “click”event and write a CALL DIALOG command. After CALL DIALOG is executed system opens new dialog fires itsevents and switches to second dialog.

Its possible to call dialogs as popups. Here is the syntax alternatives for CALL DIALOG command:

CALL DIALOG {dialog};CALL DIALOG WITH LOCATION {x}, {y} SIZE {width}, {height};

CALL DIALOG command stops code execution on running method and opens new dialog on client, remainingpart of caller method executed after dialog close (like calling a function that has a user interface).

To close a dialog, you must use SHUTDOWN command. SHUTDOWN command closes the last opened dialog andswitches to previous dialog. If the closed dialog is the last dialog of transaction system closes transaction automatically.

SHUTDOWN;

In TROIA, transferring a value or variable to dialogs does not require an extra effort, in other words you can access thevalues of control symbols which are defined by previous dialog. This is totally about “scope”. If you don’t understandwhat the scope is or how system works please review related sections.

After a dialog is closes, global variables that are defined by closed dialog are not removed from the memory so theyare still accessible. So programmers must consider symbol names and types on closed dialogs when defining newvariables and controls.

8.5 Functions & Right Click Menu

It is possible to define methods on dialogs and call this methods from control events. To define a dialog method, youmust right click the dialog on “Object Explorer” and select “Add Method” on menu.

After insert required parameters for defining a new method, system automatically opens newly added method. To showa method as dialog right click menu item, you must select “Show on Menu” checkbox and set a caption (text on rightclick menu) on “Property Explorer”. Right click menu items can be bounded to controls on dialog with “BoundedWith” option. If you bind a right click menu item to a control, menu item is disable when control is disabled andinvisible when control is invisible.

8.6 Timers on Dialog

In some cases programmers need to run a piece of TROIA code repeatedly in predefined period such as refreshinga information board or do something in every two minutes. To handle this cases dilaog has a predefined event,ONTIMER which is fired automatically fired in given period. As default timer period is zero (0) and this means timeris disabled. To enable timers period informations must be set by TROIA code which is executed on BEFORE orAFTER event of dialog. To set timer period SETTIMER command is used.

Consider a dialog that has an integer textfield on it and in every 2 seconds we must increase its value and stops whenvalue is 10. Firstly must implement ONTIMER method as:

44 Chapter 8. Dialog Basics

Programming with TROIA, Release 0.5.beta

INTEGERVAR1 = INTEGERVAR1 + 1;STRINGVAR3 = STRINGVAR3 + TOCHAR(10) + 'OnTimer increased the value';IF INTEGERVAR1 == 10 THEN

SETTIMER 0;ENDIF;

And to set the period, we must add the code below to AFTER event of dialog:

SETTIMER 2000;/* 2000 : period is defined as milliseconds. */

If running ONTIMER event takes longer time than time period, system does not create multiple ONTIMER events onevent queue. New ONTIMER event is created after previous event finished. For example, if timer is set to 5 secondsand ONTIMER event takes 10 seconds. Client sends second ONTIMER event, 5 seconds after first event’s responsereturned.

8.7 Exercise 1: Counting Words

Please define a dialog that

• has two buttons and one textfield on it

• has a right click menu item that prints the word count of a string symbol which is defined on previous dialog, totextfield on it.

• one of its buttons closes the dialog

• second button has same behavior with its right click menu.

8.7. Exercise 1: Counting Words 45

Programming with TROIA, Release 0.5.beta

and call your dialog from first dialog of DEVT11-Runcode Test Transaction

8.8 Exercise 2: Defining a Clock with Timer

Please define a dialog that

• has a datetime field which shows current date

• uptates the date value on each second

and call your dialog from first dialog of DEVT11-Runctode Test Transaction. Check the time value on it and try tofind why it jumps/ticks for two seconds in some cases.

46 Chapter 8. Dialog Basics

CHAPTER 9

Transactions

A TROIA Transaction is simply an business level application that users can perform specific task/tasks on, like “SalesDocument Management” or “Funds Management”.

Transactions has a short name/id that is used as transaction id when starting/calling the transaction (DEVT11) and acaption which is a short text that defines transaction (Runcode Test Transaction).

Like other programming languages, TROIA transactions have an entry point that is fired when application started.This “entry point” is called as “start dialog” and it is defined on transaction definition.

9.1 Defining Transactions

Before the definition, you must decide the id/name, the first dialog (entry point) and transaction caption. This threeinformation is the primary data which defines a transaction.

Definition operation is performed on “SYST00 - System Transactions & Gadgets” application. This application is alsoa TROIA transaction. SYST00 stores transaction information on SYSTRANS, SYSTRANSTXT database tables.

Another feature that you must provide while defining a transaction is the “module” of your transaction. A moduleis virtual group of one or more transactions such as “Sales Applications” or “Finance Applications” etc. Module isnot a primary data and relatively negliable, it is just used for documentation. Status (active/passive) information oftransaction is also another data just for docuementation.

While defining a transaction you can also provide icon, color for user interface issues.

9.2 Transactions and Scope

Transaction is the only structure that is able to execute TROIA codes. In other words, to run a TROIA code at leastone transaction must be opened in server side. Also, transactions are able to store store variables defined in TROIAapplications. A transaction is the largest scope of a TROIA variable. A variable which is defined as global, can beaccessed by any dialog or class code which is running on transaction.

47

Programming with TROIA, Release 0.5.beta

9.3 Running & Calling Transactions

When a transaction is starter, application server reads the basic information from transaction tables on database, andcreates a virtual structure in server memory. This virtual structure is server side counterpart of transaction that willopened on client side. After a successful creation of server transaction, client calls start dialog of the transaction. Afterdialog’s events performed, transaction gets ready to user interaction.

Simply, there are two ways of starting a transaction. The first, most used and more natural one is running a transactionfrom client by clicking user menu, quick launch or a shortcut. The other method is called as “calling transaction” andused by programmers to run a transaction on TROIA code.

9.3.1 Calling Transactions by TROIA Code

In some cases, programmers may need call a transaction to perform a task and optionally get some output parametersfrom called transaction. “CALL TRANSACTION” command is used to call a transaction programatically.

Here is the simplest usages of CALL TRANSACTION command:

CALL TRANSACTION {tran_name} [({input_params})];

/*Example:CALL TRANSACTION DEVT11 (PARAM1, PARAM2);

*/

In this variation, TROIA runtime does not stop code execution on CALL TRANSACTION command. Just calls giventransaction after server activity finished (when lastest event/method executed on user interaction.) In this case, gettingoutput parameters from called transaction is not supported.

It is possible to stop code execution and wait for output parameters. Here is the usage:

CALL TRANSACTION {tranname} [({input_params})] WITH WAIT [({output_params})];

/*Example:CALL TRANSACTION (PARAM1, PARAM2) DEVT11 (OUTPUT1, OUTPUT2);

*/

In this case, TROIA runtime stops code execution and starts a new transaction that is interactive with user. When usercloses the transaction, TROIA runtime continues code execution from the command after CALL TRANSACTION,so getting output parameters and use their values on next commands is possible. In WITH WAIT variation, users notallowed to switch caller transaction on user interface without called transaction is closed.

9.3.2 Calling Transactions in Server

As default CALL TRANSACTION command, fires opening a new transaction process drived by client, so new trans-action is opened on client side with its user interface appears in client application. In this case,users are also able tointeract with called transaction.

But in some cases, programmers may need result of a process process which is already implemented on a transactionwithout any user interaction. In this cases, it is possible to call a transaction in server. When a transaction is calledin server, server opens a transaction and it’s first dialog, runs events and closes transaction; in other words serversimulates all client requests which is called when a regular transaction opening process.

Calling a transaction with in server variation is very simple. Here is the syntax:

48 Chapter 9. Transactions

Programming with TROIA, Release 0.5.beta

CALL TRANSACTION {transaction} ({input_params}) INSERVER;CALL TRANSACTION {transaction} INSERVER ({input_params});CALL TRANSACTION {transaction} ({input_params}) INSERVER ({output_params});

9.4 Input Parameters & TRANSCALLED Event

Input parameters are defined on called transaction’s as global variables with same name, value and type. So passingparameters as constant values is not recommended.

/* this is a valid call */CALL TRANSACTION DEVT11 ('paramvalue', 5);

If CALL TRANSACTION command has input parameters, after “AFTER” event of first dialog TRANSCALLED iscalled. If there is not any input parameter TRANSCALLED event is not fired. Implementing TRANSCALLED eventin start dialog is not a compulsory. If dialog does not contain TRANSCALLED event, event call is ignored even ifcaller command passes parameter.

9.5 Scheduled Tasks and Batch Transactions

As mentioned before, transactions are the only structure that is able to execute TROIA codes. So when programmersneeds to run a program as a planned/scheduled task,also they have to open a transaction. In TROIA platform, this caseis called as “batch transaction” or “batch client”.

Due to batch transaction concept, programmers are able to define a TROIA code block for a transction that willbe configured as batch. This code is defined in “Batch Code” tab of “SYST00 - System Transactions & Gadgets”application. When a batch transaction is called, system starts transaction and opens it’s first dialog as a regulartransaction opening additionally runs transaction’s “Batch Code”.

To run a batch transaction, there are two methods. First one is client based batch and this method allows users to seeclien user interface. The other option is a console application which is defined as an Server Admin Utility variation.In both of two methods, scheduling is defined on operating system’s scheduling tools like Window’s task scheduler orlinux’s crontab (TROIA Platform does not have embedded scheduling tools).

For more configuration details about “batch transactions” please see help documents.

9.6 Exercise 1: Defining Transaction

Please define a transaction that

• has a custom start dialog that has a textfield and a button on it.

• calls DEVT11 transaction on button click event and returns STRINGVAR3 variable’s value to textfield.

and try to understand difference between calling transaction with simple method and with “WITH WAIT” variation.

9.4. Input Parameters & TRANSCALLED Event 49

Programming with TROIA, Release 0.5.beta

50 Chapter 9. Transactions

CHAPTER 10

Messages and Alerts

10.1 MESSAGE Command

Programmers use popup messages to inform users or get some critical data such as confirmation, selecting an optionetc.

To show such messages in TROIA, “MESSAGE” command is used. MESSAGE command gets some parameters thatdefines the message instead of message text’s itself (because of multi language support). Here the basic syntax ofMESSAGE command and sample code that shows messagebox above:

MESSAGE {module} {messagetype}{messageid} WITH {inputparamsformessagetext};

/* sample code, there is not any %s in message text,so there is not a paremeter after WITH keyword */

MESSAGE BAS C100 WITH;

This syntax is simples and most used syntax of MESSSAGE command, for more details such as options and defaultoption please see related help documents.

Message texts are defined in “SYST02 - System Messages” transaction using message definition parameters. Thisparameters are the module of messsage and an message id which is simple long number. MESSAGE command findsthe appropriate message text and options using module, id and user’s login language.

51

Programming with TROIA, Release 0.5.beta

In “SYST02 - System Messages” transaction, it is possible to define message texts and options in multiple languages.Message texts can contain ‘%s’ string formatting character for the parameters which will be provided on runtime usingWITH keyword on MESSAGE command. Also it is possible to define indexes for text parameters like ‘%s1’, ‘%s2’for if the word order changes language by language.

10.1.1 Message Types

Message Type effects message appearence on user interface and the way how user will intract with message such asselecting an option, making a text input or just clicking ok button on an information message. All message types arelisted below:

Type CodeINFORMATION I Information icon on message popupERROR E Error icon on message popupWARNING W Warning icon on message popupCONFIRMATION C Yes/No QuestionsOPTION O Custom optionsPARAMETER P User Keyboard Input

10.1.2 Reading User Response & System Variables

CONFIRMATION, OPTION or PARAMETER message types, we need to read which option is selected or the textinput by user. User response is set to CONFIRM and SYS_CONFIRMTEXT system variables, so programmers canread the value and do something due to user input. In confirmation messages, CONFIRM system variable is set toYES when user selects yes option, otherwise it is set to NO.

MESSAGE BAS C100 WITH;

IF CONFIRM == 'YES' THENSTRINGVAR1 = 'User said: yes!';

ELSESTRINGVAR1 = 'User said: no!';

ENDIF;

In option messages, CONFIRM variable is set to an integer which shows the order of selected option andSYS_CONFIRMTEXT is set to text value of selected option.

Another system variable which is set on MESSAGE command is SYSMESSAGE. SYSMESSAGE is set to messagetext for programmers who need message text. Remember message text is calculated using given module, messageid,login language and applied message parameters.

10.2 Message on Batch/Server Transactions

As it is obvious, messages shown on client side and needs a client side interaction, so while interpreter running amessage command, it returns client and waits for a client interaction. This case is called “code breaking” and simplyconsidered as “using a client side resource while code execution in server side”.

In batch transactions, there is no user that is able to interact or answer message dialog, therefore intepreter behav-ior is different on batch and inserver (INSERVER) transactions. In this kind of server only code executions, systemautomatically answer messages with default option, confirms (YES) all confirmation messages and ignores informa-tion/warning messages. Additionally inserts all messages to IASBATCHERR system table which is able to storemessage, session and server information.

52 Chapter 10. Messages and Alerts

Programming with TROIA, Release 0.5.beta

10.3 Message on Database Transactions

Messages on “database transactions” (between BEGINTRAN-COMMITTRAN) are answered automatically by serverand sent to client side as information messages after “database transaction” closed. All messages emerged in “databasetransaction” are transferred to client as a bulk information message. Messages on sql transactions are stored in SYS-BATCHMESSAGES system variable whose type is table. It will be discussed detailly in database access section.

10.4 Other Alerting Options

In TROIA, there are some other options to point out controls or create some popups to take users attention. Please seehelp documents of ATTENTION and ALERT commands which have different user interfaces and interaction methods.

10.5 Exercise 1: Reading Message Text/Answer

• Define an option message.

• Define a confirmation which contains format text (%s)

• Add a button which shows option message first and prints selected message to your second confirmation messagetext.

• Print your confirmation message text and answer to a textfield.

10.3. Message on Database Transactions 53

Programming with TROIA, Release 0.5.beta

54 Chapter 10. Messages and Alerts

CHAPTER 11

Classes

In object oriented programming, a class is an extensible structure that has some features (members), behavior (meth-ods) and an initial state. As an object oriented programming language, TROIA also supports classes. This sectionaims to introduce concept an its key features in TROIA.

11.1 Introduction

Briefly, TROIA classes are software structures that have behaviors as methods, features as members, and constructorsto set initial states. With these features TROIA classes are very similar to most used object oriented language’s classes(such as java, c# etc). When it comes to programming practices, TROIA classes have some different aspects fromother object oriented languages.

In object oriented languages, usually all structures (such as user interface forms, form elements) are also classes whichare included in framework’s itself and programmers able to extend this classes and/or implement new classes. InTROIA, dialogs, reports and other iu items are not considered as class. TROIA classes are same level structures withdialogs or reports. In other words, dialogs are not classes.

Additionally, even if TROIA classes are able to store member fields to represent features, they are considered as “setsof methods” that adds some behavior. Because TROIA has an “alternative structure” to classes for storing object’sfeatures. It is obvious that this “alternative structure” is “table” which will be discussed next sections. But we mustemphasize that there is not a technical constraint to use class members to represend real-life objects, its just aboutprogramming practices.

11.1.1 Creating/Editing Classes

Classes are defined and edit classes in TROIA IDE and “DEVT00 - Class-Browser” transaction. DEVT00 is an olderoption to manage TROIA classes but has some extra features such as creating SQL scripts for classes etc. We willfocus on TROIA IDE to manage classes.

To create a new class you must click TROIA IDE->New->Class on menu and fill the new class form.

As it is obvious that, your class must have a unique name. It is not a compulsory define a base class for your new class,so you can leave base class field if your new class has not a base. “Short description” is a simple documentation text

55

Programming with TROIA, Release 0.5.beta

about your class. “Module” and “Status” are just for documentation issues and have no critical effect on class usage.After you click “OK” button on new class form, IDE creates a new class which contains two emtpty basic methodsand opens your new class on object explorer.

To edit your existing classes you must click TROIA IDE->Open Resource on menu and find and open your classes.It is obvious that both for defining and editing classes requires an hotline which is a change request.

11.1.2 How Classes Stored?

There are two types of information that defines a class. Here is the tables that stores all development informationclasses.

SYSCLSHEAD Stores basic information of class such as class name, base classSYSCLSFUNC Stores class methods information such as codes, return type

When you convert a class, TROIA interpreter reads these two tables, compiles the code and saves binary class fileswith .cls extension to user’s class path. Only these files are read when class instances created, in other words when aclass defined system does not access database tables that stores class information and codes.

11.2 Basic Class Methods

Classes has two predefined methods named _VARIABLES, _CONSTRUCTOR, this methods are called when anvariable definition command defines a new class instance. They are also called “class initializer” methods and mostlylike constructors on other object oriented programming languages.

As a programming convention _VARIABLES method is used for defining members and other required variables and_CONSTRUCTOR method is used to build internal structures of class instance. But there is not a technical constraintto use them different purposes. Also it is possible to call function initializers manually but it is not a recommended.

The only two main difference between regular methods and class initializers:

• This methods are called automatically on class instance definiton.

• OBJECT Command’s behaviour is different compared to its behaviour on regular class methods.

56 Chapter 11. Classes

Programming with TROIA, Release 0.5.beta

For details about OBJECT command and scope issue, please read the related sections of this book.

11.3 Defining Class Instances

Defining a class instance is as simple as defining an integer variable. The only difference is using your new typeinstead of “INTEGER”. Here is an instance definition of “MATHTEST” class and it is same for all data definitioncommands such as GLOBAL, OBJECT, LOCAL etc.

OBJECT:MATHTEST MATHREC;

When you defining a class instance you must consider all variable defintion points which are discussed previoussections. Additionally, when a variable definition command executed to define a class instance, class initilalizermethods are fired. But this methods are fired only once, in other words even if same instance are defined morethan once class initilizers are fired only once. This rule is same both for same or different command instances. Tounderstand the behavior correctly please see the trace of code below:

OBJECT:INTEGER NINDEX;

NINDEX = 0;

WHILE NINDEX < 2BEGIN

OBJECT:RDTA AREC;

OBJECT:RDTA AREC;

NINDEX = NINDEX + 1;ENDWHILE;

11.4 Calling Class Methods

Classes also have methods that can be called from outside of the class over an class instance. There is a not a specialsyntax for calling a TROIA Class method. Most important part while calling a class method is specifying class instancename, because each instance can have an internal state. Here is a simple example of calling a class method:

OBJECT:MATHTEST CLASSINSTANCE,INTEGER RESULT;

RESULT = CLASSINSTANCE.SUM(5, 6);

It is also possible to define class methods as recursive and call other class methods. To call call a class method insideclass THIS keyword is used, because developer of class is not able to possible instances of class. Here is a simpleexample:

/* this is a class method code, which returns a text */PARAMETERS:

INTEGER PA,

(continues on next page)

11.3. Defining Class Instances 57

Programming with TROIA, Release 0.5.beta

(continued from previous page)

INTEGER PB;

LOCAL:INTEGER MAXNUM;

/* class have another method named MAX */MAXNUM = THIS.MAX(PA, PB);

RETURN 'Maximum number is ' + MAXNUM;

11.5 Accessing Class Members

All class members are defined inside class, so each class instance has different memory space for each class field. Soit is not possible to access a class field with its name, also you must specify the instance name. In most programminglanguages dot (.) operator, allows programmers to access fields of an class instance. In TROIA @ operator is used toaccess value of a field.

OBJECT:STRINGUTIL STRUTIL;

STRUTIL@DEFAULTSEPERATOR = '-';

All member fields are considered as public, so there is not a restriction to access fields by its access modifiers. @operator is used for only one level, so ‘STRUTIL@MEMBERCLASS@ITSFIELD’ is not a valid usage.

11.6 Class Inheritance

Even if there are some differences compared to regular object oriented programming languages, its possible to inheritTROIA classes and override methods of base class (also its possible for dialogs). Overriding class initilizer methodsis not supported, if overriding method and base method is executed as if they are a single constructor.

Inheritance, both for dialogs and classes will be discussed detailly in next sections.

11.7 Exercise 1: Scope of Class Member (Math)

Define a class that:

• has a integer member ‘factor’ value whose default value is 1.

• has a method SUM method, calculates sum of given two parameters and returns sum * factor.

After definition:

• create twho different instances of your class

• set different ‘factor’ values to each instance

and compare the results.

58 Chapter 11. Classes

Programming with TROIA, Release 0.5.beta

11.8 Exercise 2: Defining Unexisting Class Instances

Try to create an class instance using OBJECT command with an undefined class name and see the trace.

11.8. Exercise 2: Defining Unexisting Class Instances 59

Programming with TROIA, Release 0.5.beta

60 Chapter 11. Classes

CHAPTER 12

Basics of Table

As discussed in previous sections, table is most important data types of TROIA, because of the its extended features.This section aims to introduce basic concepts about tables and most used table command and functions.

12.1 Introduction

Table is a built-in data type of TROIA like string, integer or double. In addition to being a simple data type, table hastoo many features that allow programmers to implement database applications with easily.

Thera are too many structures and concepts which are based on table data type, even charts, diagrams etc. Alsodatabase queries and interactions are based on tables. Before discussing tables and its features we must focus what wemean with the word : “table”.

12.1.1 Database Table/Data Type/Table Control

TROIA Platform, uses database tables just for storing data, so when we discuss tables in this section we don’t meandatabase tables. Defining database tables and using data manipulation commands will be discussed in next sections.

In TROIA, there are two main table concepts, first one is table data type and second one is “table control” that is usedon dialogs. Table control has a user interface and some functions on its user interface such as conditional formattingetc. Table controls have also a table typed variable in server memory, in other words “table control” is user interfaceobject and table is a kind of value (like textfield’s background color & its value). So its possible to apply all featuresand operations discussed in this section, to value of a table control.

In this section we use the word table “table” to mean a variable whose type is table. Features related with table controlswill be discussed in next sections.

12.2 Defining/Filling Tables

Like other data types, data definition commands are used to define a table and it is not so much different defining aninteger variable. Here is a single object command that defines an integer and a table.

61

Programming with TROIA, Release 0.5.beta

OBJECT:TABLE TABLEVAR,INTEGER INTVAR;

Unlike primitive data types (int, double etc), table is a two dimensional data type. Therefore, only variable definitionis not so much useful for tables.In addition to defining table instance, also we must define its structure/columns tostore data. To add columns, there is a command which gets column name, column type and colcumn length and addsa column to table variable. This command is called “APPEND COLUMN”, here is its syntax and sample usage:

APPEND COLUMN {columnname}, {columntype}, {columnlength} TO {table};

/* add a 100 char length string column named COL1 to TABLEVAR */APPEND COLUMN COL1, STRING, 100 TO TABLEVAR;APPEND COLUMN COL2, INTEGER, 10 TO TABLEVAR;

/* now table is able to store data */

It is possible to add STRING, INTEGER,TEXT,DATE,DATETIME,DECIMAL,LONG, TIME and TIMES columnsusing APPEND COLUMN command and it is not allowed to add TABLE or VECTOR types as table column. Columnnames must be unique, so it is not allowed to add two columns that has same name. For more details about thecommand please see help documents.

Another option to define table is using a table control on a dialog. Every ui table has a global table variable as its datamodel and programmers can access table data over this model. Model table has same name with table control andits not too much different from a textfield and its value (as a string variable). APPEND COLUMN also works for uitables, but appending and showing new columns on user interface will be discussed in next section.

Additionally, SELECT command defines a table variable with its columns, so programmers do not need to definetable and its columns before the command. SELECT command also adds rows depending to query result. SELECTcommand will be discussed in related sections, but for now we must know that, SELECT command changes thecolumn model of an existing table variable or defines table with its column model. Here is a sample code:

OBJECT:TABLE T1;

/* change column-model and data of an existing variable */SELECT USERNAME, CREATEDBY, CREATEDAT FROM IASUSERS WHERE 1 = 2 INTO T1;

/* define a table variable with its column-model */SELECT USERNAME, CREATEDBY, CREATEDAT FROM IASUSERS WHERE 1 = 2 INTO T2;

As another option, there is a CONSTRUCT command that defines table and creates it’s column information. Thiscommand is rarely used to define tables, for more information please see it’s help document.

12.3 Adding Rows To Tables

As its obvious, rows are the data of a table variable. In TROIA there are multiple ways of adding rows to a table. Toadd a new row to a table variable programmatically, APPEND ROW command is used.This command is able to adda new row to first row, end of the table or after a specific row. Here is the syntax and example, for more detail pleasesee TROIA Help.

APPEND ROW TO {table} [ATHEAD | ATBETWEEN];

OBJECT:

(continues on next page)

62 Chapter 12. Basics of Table

Programming with TROIA, Release 0.5.beta

(continued from previous page)

TABLE T1;

SELECT USERNAME, CREATEDBY, CREATEDAT FROM IASUSERS WHERE 1 = 2 INTO T1;APPEND ROW TO T1;

Also it is possible to fill table with data which is selected from database. Another feature of SELECT command isadding new rows to table. Here is an example:

OBJECT:TABLE T1;

SELECT USERNAME, CREATEDBY, CREATEDAT FROM IASUSERS INTO T1;

Also it is possible to add rows to tables from user interface by users. To add a new row to a ui table, INSERT key isused. It will be discussed detailly in next sections.

12.4 Accessing Table Data

To access data on a table cell, “_” operator is used. This operator needs at least two information table name & columnname or an additional row number.

12.4.1 Using Row Index

Like arrays on other programming languages, row index can be specified on cell value access. In TROIA row indexesstarts from 1, here is the example:

OBJECT:TABLE T1,INTEGER ROWINDEX,STRING RESULT;

ROWINDEX = 1;RESULT = '';

SELECT USERNAME, CREATEDBY, CREATEDAT FROM IASUSERS INTO T1;

WHILE ROWINDEX < T1_ROWCOUNTBEGIN

RESULT = RESULT + T1[ROWINDEX]_USERNAME + ' created by ';RESULT = RESULT + T1[ROWINDEX]_CREATEDBY + ' at ';RESULT = RESULT + T1[ROWINDEX]_CREATEDAT + TOCHAR(10);ROWINDEX = ROWINDEX + 1;

ENDWHILE;

Accessing table cells using row indexes is not mostly used method, because in this method programmer must provicerow index at each cell access.

12.4.2 Active Row: Internal Row Cursor

To reduce development efford, table variable have an internal cursor that shows active row,so programmers need topoint row number for each cell access on same row.Here is the TROIA code that prints same information, but usingactive row instead of row index:

12.4. Accessing Table Data 63

Programming with TROIA, Release 0.5.beta

OBJECT:TABLE T1,INTEGER ROWINDEX,STRING RESULT;

ROWINDEX = 1;RESULT = '';SELECT USERNAME, CREATEDBY, CREATEDAT

FROM IASUSERSINTO T1;

WHILE ROWINDEX < T1_ROWCOUNTBEGIN

T1_ACTIVEROW = ROWINDEX;RESULT = RESULT + T1_USERNAME + ' created by ';RESULT = RESULT + T1_CREATEDBY + ' at ';RESULT = RESULT + T1_CREATEDAT + TOCHAR(10);ROWINDEX = ROWINDEX + 1;

ENDWHILE;

Active row is the most used and important concept of working with tables. Most of table commands are based onactive row, such as looping or locating.

“Active Row” is not same with “Selected Row”, it always points a single row. This curser value is set by user interfaceor different TROIA commands. We will discuss commands which effects active row in related sections. But in thissection we must know that it is possible to set active row directly, by two main method.

First one is directly setting the value with READ command’s INDEX variation, here is the basic syntax of readcommand:

/* to a given index */READ {table} WITH INDEX {activerowindex};

/* to an index related with current */READ {table} WITH FIRST | LAST | NEXT | PREV;

Another method is setting active row value with ACTIVEROW flag of table.

12.5 Table Flags

There are some special fields that returns specific information about tables like row count, active row etc. Names ofthese fields are reserved and can not be used as column names. And can be accessed by _ operator like table columns.

12.5.1 Flags about Table

Here are flags that returns data about table’s itself (independent from active row). Some of this flags will be discussed(w.b.d.) detailly, in related sections.

64 Chapter 12. Basics of Table

Programming with TROIA, Release 0.5.beta

Flag Type R-Only DescriptionACTIVEROW INTEGER NO Returns active row index between 1-row countROWCOUNT INTEGER YES Returns number of rows in tableDBTABLENAME STRING YES Db table whose data is set to table (w.b.d.)HASSELECTEDROW INTEGER YES Returns whether given table has a selected rowACTIVECOL INTEGER YES Active column index of ui tableACTIVECOLNAME STRING YES Active column name of ui table (w.b.d.)ARROWSTATE INTEGER YES For the ArrowClick Event of ui table (w.b.d.)

12.5.2 Flags about UI Table Rows

Additionally, table has row releated flags, each row is able to store different values for each flag. This flags alsoaccessed by with and without row index. If row index is not specified system returns active row’s flag value. Althoughthis flags are related/meaningful for ui tables, they are also available for any table variable. But it is not recommendedto use this flags for other purposes except their main purpose.

Flag Type DescriptionSELECTED INTEGER is set to 1 when user selects row on ui, otherwise 0HIDE INTEGER if it is set to 1, row is not visible on ui tableBKCOLOR INTEGER to change row color on uiROWTOOLTIP STRING tooltip text which gets visible when user mouse stops on rowFYI STRING another alias for ROWTOOLTIPFILTERED INTEGER is set to 1 when row is invisible by a ui filterSUMMARYROW INTEGER must be set to 1, for subtotal/summary rows to avoid miscalculationsCHECKED INTEGER only set and read by TROIA applications

There are some other ui table flags, they will be discussed in related sections.

12.5.3 Persistency Flags

TROIA tables also support object/relational persistency, so programmers don’t need to store extra information to selectappropriate data manimulation statement for storing data on database. Persistency state which indicates row’s statecompared to releated record on database, is stored on persistency flags. They are set automatically when a cell valuechanged or when data is read from database by interpreter. Here is a short and simple list of persistency flags, eachflag and its state transitions will be discussed detailly on database section.

Flag DescriptionDELETED Returns whether row is deleted by user, programmerINSERTED Returns whether row is a new row.READ Returns whether row read from database.UPDATED Returns whether row is updated after db read.

12.6 Looping on Tables

In TROIA, to do something for each row of a table, there is no need to define an index and loop with a while statementand increase index at each iteration. Other option is LOOP command which is very similer to for-each statements onsome other programming languages. Also it supports to add some conditions so programmers don’t need to add an ifstatement to loop block. Here is the simplest syntax:

12.6. Looping on Tables 65

Programming with TROIA, Release 0.5.beta

LOOP AT table [WHERE {condition}]BEGIN

blockENDLOOP;

As it is obvious LOOP command, increases active row and executes condition new active row and if condition isreturns true runs its inner block, so we must know that active row is not same at before the loop and after the loop.Here is the same example that uses LOOP command instead of WHILE.

OBJECT:TABLE T1,STRING RESULT;

RESULT = '';SELECT USERNAME, CREATEDBY, CREATEDAT

FROM IASUSERSINTO T1;

LOOP AT T1BEGIN

RESULT = RESULT + T1_USERNAME + ' created by ';RESULT = RESULT + T1_CREATEDBY + ' at ';RESULT = RESULT + T1_CREATEDAT + TOCHAR(10);

ENDLOOP;

And another example that uses where condition. In this example, it prints users only created by ‘BTAN’.

OBJECT:TABLE T1,STRING RESULT;

RESULT = '';SELECT USERNAME, CREATEDBY, CREATEDAT

FROM IASUSERSINTO T1;

LOOP AT T1 WHERE T1_CREATEDBY == 'admin'BEGIN

RESULT = RESULT + T1_USERNAME + ' created by ';RESULT = RESULT + T1_CREATEDBY + ' at ';RESULT = RESULT + T1_CREATEDAT + TOCHAR(10);

ENDLOOP;

Both with and without WHERE condition this method scans whole table. If where condition provided LOOP commandexecutes condition expression for each row.

12.6.1 Looping Faster: CRITERIA COLUMNS Variation

Another option without a where condition expression is using CRITERIA COLUMNS variation of LOOP Command.In this variation system does not execute condition expression on TROIA interpereter layer, but in java layer. Thisvariation works faster than scanning whole table on TROIA layer

LOOP AT {table} CRITERIA COLUMNS {columns} VALUES {values} [NOTCASESENSITIVE]BEGIN

block

(continues on next page)

66 Chapter 12. Basics of Table

Programming with TROIA, Release 0.5.beta

(continued from previous page)

ENDLOOP

/* {columns} & {values} are comma separated list. */

Here is an example, that shows looping with CRITERIA COLUMNS. This examle prints users that is created byBTAN and password validity is 2000:

OBJECT:TABLE T1,STRING RESULT,STRING STRCREATEDBY;

SELECT USERNAME, CREATEDBY, PWDVALIDITYFROM IASUSERSINTO T1;

STRCREATEDBY = 'BTAN';RESULT = '';

LOOP AT T1 CRITERIA COLUMNS CREATEDBY,PWDVALIDITY VALUES STRCREATEDBY,2000BEGIN

RESULT = RESULT + T1_USERNAME + ':';RESULT = RESULT + T1_PWDVALIDITY + TOCHAR(10);

ENDLOOP;

Please change value of STRCREATEDBY and test with both case sensitive and insensitive options, with single andmultiple parameters. Also it is possible to use table flags which are related with rows, as condition. Here is a simpleexample than uses INSERTED flag as CRITERIA COLUMNS condition:

OBJECT:TABLE T1,STRING RESULT,STRING STRCREATEDBY;

SELECT USERNAME, CREATEDBY, PWDVALIDITYFROM IASUSERSINTO T1;

STRCREATEDBY = 'BTAN';RESULT = '';

APPEND ROW TO T1;T1_USERNAME = 'NewUser';T1_CREATEDBY = 'BTAN';T1_CREATEDBY = 30;

LOOP AT T1 CRITERIA COLUMNS CREATEDBY,INSERTED VALUES STRCREATEDBY,1BEGIN

RESULT = RESULT + T1_USERNAME + ':';RESULT = RESULT + T1_PWDVALIDITY + TOCHAR(10);

ENDLOOP;

12.6. Looping on Tables 67

Programming with TROIA, Release 0.5.beta

12.6.2 Looping Faster: Loop on Hash Index

Also it is possible to create virtual indexes on a table variable to loop on different values of indexed columns. Whilecreating an index, system finds/calculates indexes of rows for each value combination of indexed rows. So if you needmultiple loops and different criteria values for same columns, calculating indexes for once may be useful for highperformance looping.

To create virtual hashes on a table BUILDHASHINDEX command is used, here is the syntax:

BUILDHASHINDEX {indexname} COLUMNS {columns} ON {table} [FORCE];

BUILDHASHINDEX command does not recreate index if there is already an index with given index name. If youwant to overwrite an existing index you must use optional FORCE parameter. Also HASHASHINDEX() functionis useful to check whether an index exists with same name. For more information about hash indexes and relatedfunctions please see help documents. Here is a simple example for looping over hash indexes.

OBJECT:TABLE T1,STRING RESULT,STRING INDEXNAME;

SELECT USERNAME, CREATEDBY,PWDVALIDITYFROM IASUSERSINTO T1;

INDEXNAME = 'myindex';RESULT = '';BUILDHASHINDEX INDEXNAME COLUMNS PWDVALIDITY,CREATEDBY ON T1;

LOOP AT T1 CRITERIA INDEXED INDEX INDEXNAME VALUES 2000, 'BTAN'BEGIN

RESULT = RESULT + T1_USERNAME + ':';RESULT = RESULT + T1_PWDVALIDITY + TOCHAR(10);

ENDLOOP;

RESULT = RESULT + '----------------' + TOCHAR(10);

LOOP AT T1 CRITERIA INDEXED INDEX INDEXNAME VALUES 60, 'kkizir'BEGIN

RESULT = RESULT + T1_USERNAME + ':';RESULT = RESULT + T1_PWDVALIDITY + TOCHAR(10);

ENDLOOP;

12.6.3 Which Looping Method is the Best?

As mentioned in previous sections, tables are the main and most used data type of TROIA programming language.Tables store bulk data because of its nature, so considering performance issues while working with tables is a must.Looping is also very important process for high performance applications, so programmers must select correct loopingoption considering their data structure, search criterias.

As an important point, programmers must use LOOP command to loop on tables. In other words using WHILEcommand is NOT recommended. Also it is very important to select correct LOOP command option considering datastructure of table, search criterias, expressions on criterias, number of loops etc.

Each looping option has different pros & cons. The main rule that programmer must consider is “using java layer asmuch as possible instead of TROIA commands”. For example, if it is possible using CRITERIA columns is faster thanWHERE condition.

68 Chapter 12. Basics of Table

Programming with TROIA, Release 0.5.beta

The second rule is “calculating same expressions once”. If expression result is not related cell of active row, calculatingcomparison values before the loop will be useful. Here is an example:

OBJECT:TABLE T1,STRING RESULT;

RESULT = '';SELECT USERNAME, PWDVALIDITY

FROM IASUSERSINTO T1;

/* calculate value for each row */LOOP AT T1 WHERE T1_PWDVALIDITY == THIS.CALCMAXVALIDITY() * 4 + 40BEGIN

RESULT = RESULT + T1_USERNAME + '-> max validity ' + TOCHAR(10);ENDLOOP;

Here is faster alternative which calculate value before looping:

OBJECT:TABLE T1,STRING RESULT,INTEGER MAXVALIDITY;

RESULT = '';SELECT USERNAME, PWDVALIDITY

FROM IASUSERSINTO T1;

MAXVALIDITY = THIS.CALCMAXVALIDITY() * 4 + 40;

LOOP AT T1 WHERE T1_PWDVALIDITY == MAXVALIDITYBEGIN

RESULT = RESULT + T1_USERNAME + '-> max validity ' + TOCHAR(10);ENDLOOP;

Here is faster alternative which moves comparison expression to java layer with CRITERIA COLUMNS:

OBJECT:TABLE T1,STRING RESULT,INTEGER MAXVALIDITY;

RESULT = '';SELECT USERNAME, PWDVALIDITY

FROM IASUSERSINTO T1;

MAXVALIDITY = THIS.CALCMAXVALIDITY() * 4 + 40;

LOOP AT T1 CRITERIA COLUMNS PWDVALIDITY VALUES MAXVALIDITYBEGIN

RESULT = RESULT + T1_USERNAME + '-> max validity ' + TOCHAR(10);ENDLOOP;

12.6. Looping on Tables 69

Programming with TROIA, Release 0.5.beta

12.7 Locating on Table

In some cases, programmers loops on table to find a specific row and do something for this row only. In TROIA,programmers do not need to loop to find a row, thanks to LOCATERECORD command. This command finds thecorrect row due to given parameters and changes the active row cursor on table. If LOCATERECORD commandcan not find correct row with given parameters it does not changes the active row and sets SYS_STATUS to 1, soprogrammer use check whether there is a row with given parameters. Here is the basic and most used variation ofLOCATERECORD command:

LOCATERECORD SEQUENTIAL COLUMNS {columns} VALUES {values}ON {table} [NOTCASESENSITIVE] [NEXT] [LAST];

An example that prints two users which is created by ‘BTAN’, please change the value and test/run with differentparameters and variations.

OBJECT:TABLE T1;

SELECT USERNAME, CREATEDBY,CHANGEDBYFROM IASUSERSINTO T1;

SET TMPTABLE TO TABLE TMPTABLE;

LOCATERECORD SEQUENTIAL COLUMNS CREATEDBY VALUES 'BTAN' ON T1;STRINGVAR3 = T1_ACTIVEROW + '-'+ T1_USERNAME;STRINGVAR3 = STRINGVAR3 + ' ('+ SYS_STATUS + ')';

LOCATERECORD SEQUENTIAL COLUMNS CREATEDBY VALUES 'BTAN' ON T1 NEXT;STRINGVAR3 = STRINGVAR3 + TOCHAR(10) +T1_ACTIVEROW + '-'+ T1_USERNAME;STRINGVAR3 = STRINGVAR3 + ' ('+ SYS_STATUS + ')';

SEQUENTIAL variation of LOCATERECORD command is very similar to CRITERIA COLUMNS variation ofLOOP command and scans table on java layer. As an alternative to scanning table, command has an BINARYSEARCHvariation which searches faster on as sorted table. BINARYSEARCH variation only works on sorted tables on givencolumns (ascending). Here is the syntax and a simple column example:

LOCATERECORD BINARYSEARCH COLUMNS {columns} VALUES {values}ON {table} [NOTCASESENSITIVE];

OBJECT:TABLE T1;

SELECT USERNAME, CREATEDBY,CHANGEDBYFROM IASUSERSORDERBY CREATEDBYINTO T1;

LOCATERECORD BINARYSEARCH COLUMNS CREATEDBY VALUES 'BTAN' ON T1;STRINGVAR3 = T1_ACTIVEROW + '-'+ T1_USERNAME;STRINGVAR3 = STRINGVAR3 + ' ('+ SYS_STATUS + ')';

Also it is possible to locate table’s active row over an hashindex. With this option, programmers can create indexonce and locate rows with different row values using this index. This variations reduces to process time compared toscanning table on each locate. Here is the syntax and example:

70 Chapter 12. Basics of Table

Programming with TROIA, Release 0.5.beta

LOCATERECORD INDEXED INDEX {indexname} VALUES {values}ON {table} [NEXT] [LAST];

OBJECT:TABLE T1;

SELECT USERNAME, CREATEDBY,CHANGEDBYFROM IASUSERSINTO T1;

BUILDHASHINDEX 'MyIndex' COLUMNS CREATEDBY ON T1;

LOCATERECORD INDEXED INDEX 'MyIndex' VALUES 'BTAN' ON T1;STRINGVAR3 = T1_ACTIVEROW + '-'+ T1_USERNAME;STRINGVAR3 = STRINGVAR3 + ' ('+ SYS_STATUS + ')';

LOCATERECORD INDEXED INDEX 'MyIndex' VALUES 'BTAN' ON T1 LAST;STRINGVAR3 = STRINGVAR3 + TOCHAR(10) + T1_ACTIVEROW + '-'+ T1_USERNAME;STRINGVAR3 = STRINGVAR3 + ' ('+ SYS_STATUS + ')';

As it is obvious, LOCATERECORD variations are similar to LOOP command’s. Each variation has different pros andcons. To create high performance applications, programmers must decide correct variation due to data structure, locatecount etc. For more details about locating on tables please see help documents of LOCATERECORD command.

12.8 Sorting Table Data

It is possible to select sorted row data from database but in some cases programmers may need sorting tables onapplication layer. To sort table variables due to given columns, SORT command is used. Its possible to sort rowsdescending and ascending order due to one or more columns. Default sorting is ascending and not case sensitive.Basic syntax is below:

SORT {tablename} [CASESENSITIVE] ON [DESC] {column1}, [DESC] {column2};

Here is a simple example that sorts users due to who defined them and definition time.

OBJECT:TABLE TMPTABLE;

SELECT USERNAME, CREATEDBY, CREATEDATFROM IASUSERSINTO TMPTABLE;

SORT TMPTABLE ON CREATEDBY, DESC CREATEDAT;

/* this command will be discussed later */SET TMPTABLE TO TABLE TMPTABLE;

Also its possible to provide sort colums dynamically, with the syntax below:

SORT {tablename} [CASESENSITIVE] ON @{columnsastext};

This syntax allows programmers to sort dynamically, without runtime interpretation (runtime interpretation will bediscussed later). Here is the same example that uses dynamic syntax:

12.8. Sorting Table Data 71

Programming with TROIA, Release 0.5.beta

OBJECT:TABLE TMPTABLE,STRING STRINGVAR3;

SELECT USERNAME, CREATEDBY, CREATEDATFROM IASUSERSINTO TMPTABLE;

STRINGVAR3 = 'CREATEDBY, DESC CREATEDAT';

SORT TMPTABLE ON @STRINGVAR3;

/* this command will be discussed later */SET TMPTABLE TO TABLE TMPTABLE;

12.8.1 Sort in Hierarchical Order

In some cases, programmers may need to sort rows in a relational manner. If table has an id column and parent idcolumn, TROIA has an advanced sorting option such tables. Here is a sample data mode that stores two countries andcities.

COUNTRY NAMEGERMANY KARLSRUHEGERMANY BERLINTURKEY IZMIRTURKEY ISTANBUL

TURKEYGERMANY

And you need data model after hierarchical sort:

COUNTRY NAMEGERMANY

GERMANY KARLSRUHEGERMANY BERLIN

TURKEYTURKEY IZMIRTURKEY ISTANBUL

To sort tables in hierarchical manner to get tree like table, SORT HIERARCHICAL variation is used. Here is thesyntax:

SORT {table} HIERARCHICAL IDCOLUMN {idcolumn} PARENTIDCOLUMN {parentidcolumn}[ROOTINDICATOR {indicatorvalue}] [MARKLEAFSASNODE];

Values on id columns must be unique. And both for id and parentid columns must be single row, if data has multiplecolums for id and parentid they must be consolidated before SORT HIERARCHICAL command. Here is sampleTROIA code that creates and sorts sample data model:

SELECT USERNAME AS COUNTRY, CREATEDBY AS NAMEFROM IASUSERSWHERE 1=2

(continues on next page)

72 Chapter 12. Basics of Table

Programming with TROIA, Release 0.5.beta

(continued from previous page)

INTO TMPTABLE;

APPEND ROW TO TMPTABLE;TMPTABLE_COUNTRY = 'TURKEY';TMPTABLE_NAME = 'IZMIR';

APPEND ROW TO TMPTABLE;TMPTABLE_NAME = 'TURKEY';

APPEND ROW TO TMPTABLE;TMPTABLE_COUNTRY = 'GERMANY';TMPTABLE_NAME = 'KARLSRUHE';

APPEND ROW TO TMPTABLE;TMPTABLE_NAME = 'GERMANY';

APPEND ROW TO TMPTABLE;TMPTABLE_COUNTRY = 'GERMANY';TMPTABLE_NAME = 'BERLIN';

APPEND ROW TO TMPTABLE;TMPTABLE_COUNTRY = 'TURKEY';TMPTABLE_NAME = 'IZMIR';

/* to sort same level items */SORT TMPTABLE ON NAME;

SORT TMPTABLE HIERARCHICAL IDCOLUMN 'NAME' PARENTIDCOLUMN 'COUNTRY';

/* this command will be discussed later */SET TMPTABLE TO TABLE TMPTABLE;

Hierarchical sorting is much more useful fo tree tables which is a tree representation of table control. Tree tables willbe discussed detailly in next sections, but for now we must know about hierarchical sorting option, because it is anadvanced sorting option for all kind of tables.

For any kind of sorting operation, there is no way to relocate all rows to their positions before sort operation. BecauseTROIA interpreter does not track variable’s value history for any type of variable.

12.9 Working on Tables

12.9.1 Removing Rows

To remove rows from a table variable, CLEAR command is used. Clear command has different variations to clear allrows or active row. CLEAR command has different variations but mostly used for table. Here is the syntax which isrelated with removing rows:

CLEAR ROW | ALL {table};

ROW variation of CLEAR command removes the active row without changing the active row cursor, so after thecommand active row is the new row on same index. If removed row is the last row of a multi row table, new activerow is the new last row. Here is the sample code that prints row number and active row before and after the CLEARROW, please test different variatins and compare the results. It there is no more rows after clear row active row is setto 0 which is an invalid active row index.

12.9. Working on Tables 73

Programming with TROIA, Release 0.5.beta

OBJECT:TABLE T1,STRING STRINGVAR3;

SELECT USERNAME, PASSWFROM IASUSERS WHERE USERNAME LIKE 'L%'INTO T1;

STRINGVAR3 = 'Before: ' + T1_ROWCOUNT + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'ActiveRow: ' + T1_ACTIVEROW + TOCHAR(10);CLEAR ROW T1;STRINGVAR3 = STRINGVAR3 + 'After: ' + T1_ROWCOUNT + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'ActiveRow: ' + T1_ACTIVEROW + TOCHAR(10);

With ALL variation, it is possible to remove all rows from table. After clearing all rows active row is set to 0.

OBJECT:TABLE T1,STRING STRINGVAR3;

SELECT USERNAME, PASSWFROM IASUSERSINTO T1;

STRINGVAR3 = 'Before: ' + T1_ROWCOUNT + TOCHAR(10);CLEAR ALL T1;STRINGVAR3 = STRINGVAR3 + 'After: ' + T1_ROWCOUNT + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'ActiveRow: ' + T1_ACTIVEROW + TOCHAR(10);

Another command; CLEARTABLE allows programmers to find rows with given parameters and remove withoutlooping. Command supports WHERE condition and CRITERIA COLUMNS variations like LOOP command. Hashindex variation is not supported CLEARTABLE command, because removing rows destroys hash information. Hereis the syntax and example of two variations.

CLEARTABLE {table} WHERE {condition};CLEARTABLE {table} CRITERIA COLUMNS {columns}

VALUES {values} [NOTCASESENSITIVE];

SELECT USERNAME, CREATEDBYFROM IASUSERSWHERE CREATEDBY LIKE 'B%'ORDERBY CREATEDBYINTO TMPTABLE;

CLEARTABLE TMPTABLE WHERE TMPTABLE_CREATEDBY == 'BTAN';/* or */CLEARTABLE TMPTABLE CRITERIA COLUMNS CREATEDBY VALUES 'BTAN';

SET TMPTABLE TO TABLE TMPTABLE;

CLEARTABLE command is also supports using row based flags on CRITERIA COLUMNS condition like LOOPCommand.

74 Chapter 12. Basics of Table

Programming with TROIA, Release 0.5.beta

12.9.2 Removing Columns

In some cases programmers may need remove all columns and data and reconstruct table using APPEND commands(Removing a column also means removing corresponding cell of each row, so removing all columns also removeswhole data). To remove all columns DESTROYTABLE command is used and after the DESTROYTABLE commandtable goes to same state with a table that is newly created by a variable definition command (OBJECT, LOCAL ..),here is the syntax of DESTROYTABLE command:

DESTROYTABLE {table};

To remove a single column from a table variable, REMOVECOLUMN is used. Here is the syntax of the command:

REMOVE COLUMN {columnname} [PERMANENT] FROM {table};

{columnname} parameter is not a variable, in other words is considered as name of the column. If you want toremove a column whose name is in a variable use @ prefix, before the variable name. As default REMOVECOLUMNcommand does not remove column, just sets removed flag to true. If removed flag of a column is set to true, systemignores cells on this column while preparing database queries.This behaviour is useful to work on extra columns whichis appended after database selects and does not exists in database. To remove a column permanently, you must usePERMANENT variation. This variation removes column and related cells on all rows in an unreturnable manner.

OBJECT:TABLE TMPTABLE;

SELECT CLIENT, USERNAME, CREATEDBY, CREATEDATFROM IASUSERSWHERE USERNAME LIKE 'B%'INTO TMPTABLE;

REMOVE COLUMN CREATEDBY FROM TMPTABLE;REMOVE COLUMN CREATEDAT PERMANENT FROM TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

In this example, CREATEAT at column is removed permanently so you will not see this column on the screen, butCREATEDBY button is still visible because its just signed as removed to avoid adding this column to db queries (willbe discussed in next sections).

12.9.3 Reading Table Structure

In some cases, programmers may need metadata about table & it’s columns. COPY STRUCTURE command is usedto read structure of a table variable. Here is the sample code that prints table structure which is defined by SELECTcommand:

OBJECT:TABLE T1;

SELECT USERNAME, PASSWFROM IASUSERSINTO T1;

DESTROYTABLE TMPTABLE;COPY STRUCTURE T1 INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

COPY STRUCTURE command, adds five column to destiation table named COLNAME (column name), COLTYPE(column type), COLLEN (column length), COLPRE (column presicion), COLNOT. COLNOT is a deprecated/unused

12.9. Working on Tables 75

Programming with TROIA, Release 0.5.beta

field.

12.9.4 Some Useful Functions

As mentioned before SELECTED flag shows whether user selected a row on user interface. To get selected rowcound, programmers must loop on table and count selected rows. To get rid of this kind of useless loops, there isan SELECTEDROWCOUNT() system function that returns selected row count of table. Another useful function isGETCOLUMNCOUNT() for reading column count of given table. Here is an example for two functions:

OBJECT:TABLE TMPTABLE,STRING STRINGVAR3;

SELECT USERNAME, PASSW, CREATEDBYFROM IASUSERSWHERE USERNAME LIKE 'B%'INTO TMPTABLE;

LOOP AT TMPTABLEBEGIN

IF TMPTABLE_ACTIVEROW % 2 == 0 THENTMPTABLE_SELECTED = 1;

ENDIF;

ENDLOOP;

STRINGVAR3 = 'Selected Row Count:' + SELECTEDROWCOUNT(TMPTABLE) + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'Column Count:' + GETCOLUMNCOUNT(TMPTABLE);

12.10 Data Transfer Between Tables

12.10.1 Copying Tables

To copy whole structure and data of a table COPY TABLE command is used. COPY TABLE command does nottransfer row flags, as default. To transfer table flags there is a WITHFLAGS variation. Here is the syntax:

COPY TABLE {sourcetable} INTO {destinationtable} [WITHFLAGS];

And an example that transfers a source table to destination table. Please run sample code on “DEVT11 - Runcode TestTransaction” and test different data variations and row flags transfer.

OBJECT:TABLE SOURCE,TABLE TMPTABLE,STRING STRINGVAR3;

/* prepare source table & flags */SELECT CLIENT,USERNAME,CREATEDBY, CREATEDAT

FROM IASUSERSWHERE USERNAME LIKE 'BTAN%'INTO SOURCE;

(continues on next page)

76 Chapter 12. Basics of Table

Programming with TROIA, Release 0.5.beta

(continued from previous page)

SOURCE_UPDATED = 1;SOURCE_READ = 1;SOURCE_DELETED = 1;SOURCE_HIDE = 1;

COPY TABLE SOURCE INTO TMPTABLE;

STRINGVAR3 = 'UPDATED:' + TMPTABLE_UPDATED + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'READ:' + TMPTABLE_READ+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'DELETED:' + TMPTABLE_DELETED+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'HIDE:' + TMPTABLE_HIDE+ TOCHAR(10);

WITHFLAGS variation also transfers CHECKED, DELETED, INSERTED, CHANGE, READ, UPDATED, ROW-TOOLTIP (FYI), SUMMARYROW flags for each row, other flags such as HIDE, SELECTED are not transferred evenon WITHFLAGS variation. Here is the sample code, please focus on transferred flag values on STRINGVAR3:

OBJECT:TABLE SOURCE,TABLE TMPTABLE,STRING STRINGVAR3;

/* prepare source table & flags */SELECT CLIENT,USERNAME,CREATEDBY, CREATEDAT

FROM IASUSERSWHERE USERNAME LIKE 'BTAN%'INTO SOURCE;

SOURCE_UPDATED = 1;SOURCE_READ = 1;SOURCE_DELETED = 1;SOURCE_HIDE = 1;SELECT CLIENT,USERNAME,CREATEDBY, PWDVALIDITY

FROM IASUSERSWHERE 1=2INTO TMPTABLE;

COPY TABLE SOURCE INTO TMPTABLE WITHFLAGS;

STRINGVAR3 = 'UPDATED:' + TMPTABLE_UPDATED + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'READ:' + TMPTABLE_READ+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'DELETED:' + TMPTABLE_DELETED+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'HIDE:' + TMPTABLE_HIDE+ TOCHAR(10);

12.10.2 Copying Cell/Row Data

Copying a row to another table is a little bit complicated than copying whole table. Because table structures must beidentical to copy a row directly, otherwise only corresponding cells can be transferred. For example, if source tablehas two columns COL1, COL2 and destination table has only one column COL1, only COL1 can be transferred todestination table. Actually, copying a row with assingment or MOVE command is possible like below:

OBJECT:TABLE SOURCE,TABLE TMPTABLE;

(continues on next page)

12.10. Data Transfer Between Tables 77

Programming with TROIA, Release 0.5.beta

(continued from previous page)

/* source table with 4 columns */SELECT CLIENT,USERNAME,CREATEDBY, CREATEDAT

FROM IASUSERSWHERE USERNAME LIKE 'BTAN%'INTO SOURCE;

/* destination table with 4 columns, 3 corresponding*/SELECT CLIENT,USERNAME,CREATEDBY, PWDVALIDITY

FROM IASUSERSWHERE 1=2INTO TMPTABLE;

APPEND ROW TO TMPTABLE;

/* move each column */TMPTABLE_CLIENT = SOURCE_CLIENT;TMPTABLE_USERNAME = SOURCE_USERNAME;TMPTABLE_CREATEDBY = SOURCE_CREATEDBY;

But if there are too many corresponding columns between source and destination table, it becomes very hard toassing each column manually. TROIA has command named MOVE-CORRESPONDING to transfer all correspondingcolumn values between active rows of source and destination table. Here is the syntax of MOVE-CORRESPONDINGcommand and a sample that transfers a single row:

MOVE-CORRESPONDING {sourcetable} TO {destinationtable} [WITHFLAGS];

OBJECT:TABLE SOURCE,TABLE TMPTABLE;

/* source table with 3 columns */SELECT CLIENT,USERNAME,CREATEDBY, CREATEDAT

FROM IASUSERSWHERE USERNAME LIKE 'BTAN%'INTO SOURCE;

/* destination table with 5 columns*/SELECT CLIENT,USERNAME,CREATEDBY, PWDVALIDITY

FROM IASUSERSWHERE 1=2INTO TMPTABLE;

APPEND ROW TO TMPTABLE;/* move all corresponding columns */MOVE-CORRESPONDING SOURCE TO TMPTABLE;

Additionally all row based flags exist both on source and destination rows so when transferring a row to destionationtable, also flag values must be considered. As default, MOVE-CORRESPONDIG command does not transfer flagvalues, if you need to transfer also row flags you must use WITHFLAGS variation like COPY TABLE command.Please run sample code below, with different flag values, and with/withoud WITHFLAGS keyword:

OBJECT:TABLE SOURCE,TABLE TMPTABLESTRING STRINGVAR3;

(continues on next page)

78 Chapter 12. Basics of Table

Programming with TROIA, Release 0.5.beta

(continued from previous page)

/* prepare source table & flags */SELECT CLIENT,USERNAME,CREATEDBY, CREATEDAT

FROM IASUSERSWHERE USERNAME LIKE 'BTAN%'INTO SOURCE;

SOURCE_UPDATED = 1;SOURCE_READ = 1;SOURCE_DELETED = 1;

SELECT CLIENT,USERNAME,CREATEDBY, PWDVALIDITYFROM IASUSERSWHERE 1=2INTO TMPTABLE;

APPEND ROW TO TMPTABLE;

/* move all corresponding columns */MOVE-CORRESPONDING SOURCE TO TMPTABLE WITHFLAGS;

STRINGVAR3 = 'UPDATED:' + TMPTABLE_UPDATED + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'READ:' + TMPTABLE_READ+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'DELETED:' + TMPTABLE_DELETED+ TOCHAR(10);

MOVE-CORRESPONDING command directly transfers all corresponding column values even default columns suchas CREATEDBY, CREATEDAT, CHANGEDBY, CHANGEDAT. But if source table is a check table on databaseconfiguration (ODBA). Default columns are not transferred. Default columns and ODBA will be discussed detailly innext sections.

Usually, MOVE-CORRESPONDING command is used in a LOOP statement and for each row in source table, a newrow inserted to destination table or rows transferred to source table due to a conditional statement. To ease such casesMERGETABLE command is used, which transfers rows of source table due to given condition. MERGETABLEcommand is a similar command to CLEARTABLE command with an additional hash index variation like LOOPstaments. Here is the syntaxes of three variation of MERGETABLE command:

MERGETABLE {source} INTO {destination} [WITHFLAGS] WHERE {condition};

MERGETABLE {source} INTO {destination} [WITHFLAGS]CRITERIA COLUMNS {cols} VALUES {vals} [NOTCASESENSITIVE];

MERGETABLE {source} INTO {destination} [WITHFLAGS]CRITERIA INDEXED {index} VALUES {vals};

MERGETABLE has also optional WITHFLAGS variation whose behaviour is same with COPY TABLE’s WITH-FLAGS variation. Here is an example that uses all three variation. Please modify and run source code to transfer rowflag values.

SELECT 1 AS ORD, USERNAME, 'sv' AS PASSW, CREATEDBYFROM IASUSERSWHERE CREATEDBY = 'BTAN'ORDERBY USERNAMEINTO SOURCE;

SELECT 1 AS ORD, USERNAME, 'dv' AS PASSW, CREATEDBYFROM IASUSERS

(continues on next page)

12.10. Data Transfer Between Tables 79

Programming with TROIA, Release 0.5.beta

(continued from previous page)

WHERE 1 = 2INTO TMPTABLE;

LOOP AT SOURCEBEGIN

IF SOURCETABLE_ACTIVEROW % 2 == 0 THENSOURCETABLE_INSERTED = 1;ENDIF;

SOURCETABLE_ORD = SOURCETABLE_ACTIVEROW;ENDLOOP;

BUILDHASHINDEX 'INDX' COLUMNS PASSW, INSERTED ON SOURCE FORCE;

MERGETABLE SOURCE INTO TMPTABLE WITHFLAGS WHERE SOURCETABLE_INSERTED == 1;APPEND ROW TO TMPTABLE; /* as separator */MERGETABLE SOURCE INTO TMPTABLE CRITERIA COLUMNS PASSW,INSERTED VALUES 'sv',1;APPEND ROW TO TMPTABLE; /* as separator */MERGETABLE SOURCE INTO TMPTABLE CRITERIA INDEXED INDEX 'INDX' VALUES 'sv',0;

SET TMPTABLE TO TABLE TMPTABLE;

12.11 Exercise 1: Compare LOOP Options

Define a table and fill table with users whose PWDVALIDITY is more than 0. Write three LOOP statements :

• with WHERE condition. (PWDVALIDITY == 100) and print usernames to textfield.

• with CRITERIA COLUMNS variation and print usernames to textfield.

• with hash index variation and print usernames to textfield.

and

• compare traces of three variations.

• compare execution times of three variations.

12.12 Exercise 2: Locating Using Hash Index

Define a table and fill table with all users in IASUSERS table.

• Print users whose creator user is missing on same user list. Please use only one SELECT statement.

12.13 Exercise 3: Sort Users Like a Tree

Modify code that you write for Exercise 2.

• Set CREATEDBY to empty string of users whose creator is missing.

• Create a tree hierarchy on user table using CREATEDBY column.

• add a child row to your username.

80 Chapter 12. Basics of Table

Programming with TROIA, Release 0.5.beta

• print all persistency flags of all rows and compare flags of updated rows and new row.

12.14 Exercise 4: Copying Rows

Create a new table variable and copy users who created at least one users to new table variable. Use the code that youwrite in previous example.

12.14. Exercise 4: Copying Rows 81

Programming with TROIA, Release 0.5.beta

82 Chapter 12. Basics of Table

CHAPTER 13

Working With Date/Datetime

This section aims to introduce date/datetime/time types, related configurations, structures and concepts to ease datehandling/manipulation

13.1 Date Data Types

In contrary to some other programming languages, TROIA has more than one data type to store and manipulate date,datetime, time variables. We know about data types from previous sessions, but to refresh our knowledge about thistypes here is the list of related data types:

DATE (Ex: 23.04.1920, default value:definition date)DATETIME (Ex: 29.10.1923 16:30:30, default value:definition time)

TIME (Ex: 21:30)TIMES (Ex: 21:30:13)

As it is obvious, main difference between DATE and DATETIME type is time part which consisted by hour, minuteand second. TIME and TIMES data types are used for storing only time information. Their main difference is secondpart. TIMES data type is relatively a new data type that is supported after 5.01.01 releases(not supported on 3.08.xreleases.)

Due to your application’s requirements you must use the most primitive data type. It is not recommended that storinga date information in a DATETIME symbol and 00:00:00 as its time part.

13.2 Type Conversion & Casting on Date Types

We know that TROIA handles type casting operations in background. This rule is also valid for date related data types,so it is possible to assign date, datetime, time, times variable any other typed variable except decimal, or assign anyvariable to any date data type.

Here is a simple code block that contains four casting operation:

83

Programming with TROIA, Release 0.5.beta

OBJECT:STRING STRINGVAR3,DATETIME DATETIMEVAR1,DATE DATEVAR1,DATETIME DATETIMEVAR2,TIME TIMEVAR1;

STRINGVAR3 = '25.11.1984 13:00:00';DATETIMEVAR1 = STRINGVAR3;

DATEVAR1 = DATETIMEVAR1;DATETIMEVAR2 = DATEVAR1;

TIMEVAR1 = DATETIMEVAR1;

In this example, first one is assigning a string to a datetime variable. This operation contains a kind of parsing operationwe will discuss parsing and formatting dates in following sections in detail. Second one is assigning datetime to date,in this operation only date part is transferred to target variable. The third one is date to datetime, in this case systemuses 00:00:00 for the time part of target symbol. The last one is from datetime to time, In this case only time part ofsource variable transferred to target symbol.

There are too many possibilities casting date related symbols, please write your own codes to understand the mainapproach. It is also useful to review “Operators and Expressions” section for more information. We will focus onrelation between long and date related data types.

In background, all date related types are stored as long, so it is also possible to make type conversion/casting opera-tions between date related types and long/integer variables. Long value of a date symbol is millisecond value startsfrom 01.01.1970 00:00:00 (actually it is a little bit more complicated because of timezone issues). Although it ispossible to assign a date related variable to a long or long variable to a date related variable is possible, TROIA hasMILLISECONDSTODATE() and DATETOMILLISECONDS() system functions to handle same operations. Here isan example about long and datetime data type, please discuss the results for better understanding:

OBJECT:STRING STRINGVAR3,DATETIME DATETIMEVAR1,DATETIME DATETIMEVAR2,DATETIME DATETIMEVAR3,LONG LONGVAR1,LONG LONGVAR2;

DATETIMEVAR1 = '25.11.1984 13:00:00';

LONGVAR1 = DATETOMILLISECONDS(DATETIMEVAR1);LONGVAR2 = DATETIMEVAR1;

DATETIMEVAR2 = MILLISECONDSTODATE(LONGVAR1);DATETIMEVAR3 = MILLISECONDSTODATE(LONGVAR1);

STRINGVAR3 = LONGVAR1 + TOCHAR(10) + LONGVAR2;

84 Chapter 13. Working With Date/Datetime

Programming with TROIA, Release 0.5.beta

13.3 Some Useful Functions and Variables

13.3.1 Getting Current Date

A date related variable’s initial value is the time that it is initialized/created, therefore it is possible to read the currentdate just creating a date or datetime variable. But getting current date with this approach creates a vulnerability aboutdate related bugs, so it is not recommended to use this option.

The safest and most correct way of getting current date is reading SYS_CURRENTDATE system variable’s value.SYS_CURRENTDATE is a datetime system variable and returns current time in each value read. Here is a samplecode about using SYS_CURRENTDATE:

OBJECT:INTEGER INTEGERVAR1,STRING STRINGVAR3;

STRINGVAR3 = '';INTEGERVAR1 = 0;STRINGVAR3 = 'Data Type:' + GETVARTYPE(SYS_CURRENTDATE) + TOCHAR(10);

WHILE INTEGERVAR1 < 3BEGIN

DELAY 1000;STRINGVAR3 = STRINGVAR3 + SYS_CURRENTDATE + TOCHAR(10);INTEGERVAR1 = INTEGERVAR1 + 1;

ENDWHILE;

Another option is using CURRENTTIMEMILLIS() system function that returns current time as long value. Althoughit is mostly used to measure the time between two operations, it can be also used for getting current date. The examplebelow combines two different usages of CURRENTTIMEMILLIS() function.

OBJECT:LONG LONGVAR1,DATETIME DATETIMEVAR1,STRING STRINGVAR3;

DATETIMEVAR1 = CURRENTTIMEMILLIS();

LONGVAR1 = CURRENTTIMEMILLIS();DELAY 1000;LONGVAR1 = CURRENTTIMEMILLIS() - LONGVAR1;

STRINGVAR3 = DATETIMEVAR1 + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'It takes: '+ LONGVAR1 + ' ms.'+TOCHAR(10);

13.3.2 Checking and Validating Date Related Types

In some cases, programmers need to know whether a variable is a date or datetime symbol. ISDATE() system functionchecks given variable and returns a boolean result. The example below shows that this function returns true (1) for onlyDATE and DATETIME data types, otherwise it returns false (0) even variable contains a string that can be convertibleto date:

OBJECT:STRING SRINGVAR1,

(continues on next page)

13.3. Some Useful Functions and Variables 85

Programming with TROIA, Release 0.5.beta

(continued from previous page)

DATE DATEVAR1,DATETIME DATETIMEVAR1,TIME TIMEVAR1,TIMES TIMESVAR1;

STRINGVAR1 = DATETIMEVAR1;STRINGVAR3 = '';

STRINGVAR3 = STRINGVAR3 + 'SRINGVAR1 :' + ISDATE(SRINGVAR1) + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'DATEVAR1 :' + ISDATE(DATEVAR1)+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'DATETIMEVAR1 :' + ISDATE(DATETIMEVAR1)+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'TIMEVAR1 :' + ISDATE(TIMEVAR1)+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'TIMESVAR1 :' + ISDATE(TIMESVAR1)+ TOCHAR(10);

To validate a string value whether it is a valid date/datetime TROIA has CHECKDATE() system function that getsa string parameter and returns boolean (integer). Similarly, CHECKTIME() is used for checking time/times validity.Here is a sample code that shows the behavior of CHECKDATE() and CHECKTIME() functions.

OBJECT:STRING SRINGVAR1,DATE DATEVAR1,DATETIME DATETIMEVAR1,TIME TIMEVAR1,TIMES TIMESVAR1;

STRINGVAR1 = DATETIMEVAR1;STRINGVAR3 = '';

STRINGVAR3 = STRINGVAR3 + 'SRINGVAR1 :' + CHECKDATE(STRINGVAR1) + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + '19.06.2018 :' + CHECKDATE('19.06.2018')+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + '35.06.2018 :' + CHECKDATE('35.06.2018')+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'DATETIMEVAR1 :' + CHECKDATE(DATETIMEVAR1)+ TOCHAR(10);

STRINGVAR3 = STRINGVAR3 + 'TIMEVAR1 :' + CHECKTIME(TIMEVAR1)+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + 'TIMESVAR1 :' + CHECKTIME(TIMESVAR1)+ TOCHAR(10);

13.3.3 Extracting Data From Date/Datetime Variables

It is possible to get date or time part of given date variable using GETDATE() and GETTIME() functions. It isalso possible to get same parts assigning a DATETIME variable to a DATE, TIME or TIMES variable. TROIAautomatically extracts correct part, please see the casting section for more information. The example below showsGETDATE() and GETTIME() function’s behavior.

OBJECT:STRING SRINGVAR1,DATETIME DATETIMEVAR1;

STRINGVAR1 = DATETIMEVAR1;STRINGVAR3 = '';

STRINGVAR3 = STRINGVAR3 + GETDATE(STRINGVAR1) + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + GETTIME(STRINGVAR1) + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + GETDATE(DATETIMEVAR1)+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + GETTIME(DATETIMEVAR1)+ TOCHAR(10);

86 Chapter 13. Working With Date/Datetime

Programming with TROIA, Release 0.5.beta

To get a single part of a date like year, day or month you must use the functions in the like the example below:

GETDAY() Returns the day value of given date.GETDAYOFWEEK() Returns day of week. is given day monday(1), tuesday (2), wednesday (3) . . .GETHOUR() Returns the hour partGETMINUTE() Returns the minute partGETMONTH() Returns the month partGETYEAR() Returns the year partGETWEEK() Returns week number of given date

OBJECT:STRING SRINGVAR1,DATE DATEVAR1,DATETIME DATETIMEVAR1;

STRINGVAR1 = DATETIMEVAR1;STRINGVAR3 = '';

STRINGVAR3 = STRINGVAR3 + GETDAYOFWEEK(STRINGVAR1) + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + GETDAYOFWEEK(DATETIMEVAR1)+ TOCHAR(10);

STRINGVAR3 = STRINGVAR3 + GETWEEK(STRINGVAR1) + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + GETWEEK(DATETIMEVAR1)+ TOCHAR(10);

13.3.4 Calculating Dates

Last day of a month is not a constant, it depends on to the month and date due to whether year is a leap year. For sucha kind of calculations TROIA has functions below to ease development effort.

GETDATEFROMWEEK() Gets week and year parameter and returns the first day of the given week as dateFIRSTDATEINMONTH() Gets month and year parameter and returns the first day of the given month as dateLASTDATEINMONTH() Gets month and year parameter and returns the last day of the given month as date

Here is a simple example that returns the fists day of this week:

OBJECT:INTEGER THISYEAR,INTEGER THISWEEK;

STRINGVAR3 = '';

THISYEAR = GETYEAR(SYS_CURRENTDATE);THISWEEK = GETWEEK(SYS_CURRENTDATE);

STRINGVAR3 = GETDATEFROMWEEK(THISWEEK,THISYEAR);

Also is possible to add or subtract days, minutes etc. to a date and calculate another date. Forthis kind operations TROIA has functions like ADDDAYS(), ADDYEARS(), ADDHOURS(), ADDMIN-UTES(),SUBDAYS(),SUBMONTHS() etc. All this calculations takes timezone, leap year issues and predefined con-figuration into the account and reduces development effort for TROIA programmers. For more details and functionsplease see TROIA Help documents.

13.3. Some Useful Functions and Variables 87

Programming with TROIA, Release 0.5.beta

13.3.5 Calculating Date Difference

To calculate difference between two dates in days or minutes, you must only subtract a date from another. Thisoperation returns difference in milliseconds and you can calculate this difference in days or even years. Also TROIAhas GETMINUTEDIFF() function that returns the difference in minutes. Here is an example that shows two differentapproach about calculating date difference.

OBJECT:DATETIME DATETIMEVAR1,DATETIME DATETIMEVAR2;

STRINGVAR3 = '';DATETIMEVAR1 = '25.11.1984 03:00:00';DATETIMEVAR2 = '25.11.1984 04:00:00';

LONGVAR1 = (DATETIMEVAR2 - DATETIMEVAR1) / (1000*60);LONGVAR2 = GETMINUTEDIFF(DATETIMEVAR1, DATETIMEVAR2);

13.4 What is NULLDATE?

In TROIA dialogs, DATETIME and DATE text fields can be leaved as empty. In this case the value of this date/datetimesymbols is set to a special value. This special value is called as NULLDATE and this value converted to string as ” .. : : ” or ” . . ” for date symbols. This approach is also same for table columns for date/datetime columns. To checkwhether given text is NULLDATE or not TROIA has a NULLDATE() function that returns a boolean (integer) result.Here is a simple example:

OBJECT:STRING STRINGVAR1,STRING STRINGVAR2,STRING STRINGVAR3,DATETIME DATETIMEVAR1;

DATETIMEVAR1 = '';STRINGVAR1 = DATETIMEVAR1;STRINGVAR2 = SYS_CURRENTDATE;

STRINGVAR3 ='';STRINGVAR3 = STRINGVAR3 + NULLDATE(STRINGVAR1) + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + NULLDATE(STRINGVAR2) + TOCHAR(10);

13.5 Min Date & Max Date Concepts

In some cases, TROIA programmers need some special dates values like upper and lower limits of TROIA dates.Assume that you have an expiration date for a document and in some documents you must use a maximum date valuefor the documents that never expire. For this cases system returns minimum and maximum dates with SYS_MINDATEand SYS_MAXDATE system variables which are datetime. Also it is possible to check whether a datetime/datesymbol is max date/min date or not using ISMAXDATE() and ISMINDATE() functions.

OBJECT:STRING STRINGVAR3;

STRINGVAR3 = ISMINDATE(SYS_MINDATE) + TOCHAR(10);

(continues on next page)

88 Chapter 13. Working With Date/Datetime

Programming with TROIA, Release 0.5.beta

(continued from previous page)

STRINGVAR3 = STRINGVAR3 + ISMINDATE(SYS_CURRENTDATE)+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + ISMAXDATE(SYS_MAXDATE)+ TOCHAR(10);STRINGVAR3 = STRINGVAR3 + ISMAXDATE(SYS_CURRENTDATE)+ TOCHAR(10);

In 3.08.x versions as default, this max date and min date values are 01.01.1975 00:00:00 and 01.01.2030 00:00:00 andthey are hardcoded. After 5.01 versions it is possible to set this maximum and minimum years in ServerSettings.ias fileof your server with MinDateYear and MaxDateYear parameters. So it is not recommended that using this hardcodedates inside TROIA code. Although this parameters are configurable, it is not recommended to change thisvalues without a planned migration over database tables.

13.6 Basic Date Formatting/Parsing

Date formatting means converting a date/datetime variable to a string using a format like DD.MM.YYYY orYYYY.MM.DD etc. And parsing is extracting date value from a string. Due to date format resulting value can bedifferent for both formatting and parsing operations.

As default, if a date/datetime variable is assigned to a string variable system uses ‘DD.MM.YYYY’/’DD.MM.YYYYHH:MM:SS’ format. Same format is valid for parsing dates without providing a date format. So all hardcode datesmust be given using this format. Please see the code below and discuss the behavior:

OBJECT:STRING STRINGVAR3,DATETIME DATETIMEVAR1,DATETIME DATETIMEVAR2;

DATETIMEVAR1 = '30.12.2018 21:41:42';DATETIMEVAR2 = '2018.12.30 21:41:42';

STRINGVAR3 = DATETIMEVAR1;

This is totally same with decimals, all programmers uses . as decimal separator inside TROIA code. It ishardcoded and independent from language or any localization configuration

13.6.1 Formatting Configurations & Related System Variables

In troia, there is no need to format date/datetime values for text field values or table cells. This fields are formattedautomatically if they has not a hardcoded special format given on IDE. For controls and table fields to use defaultformats you must use format texts below:

datetime use default datetime formatdatetimes use default datetime format that contains seconddate use default date formattime use default time formattimes use default time format that contains second

So it is possible to show a DATETIME text field with default date format using this format parameters. Additionallyit is possible to configure text fields and table columns independent from user date format configuration using a dateformat supported by java like “yy.MM.dd”.

System calculates default formats for all date related data types using the date formatting configuration on “SYST03- System Users” transaction and uses for default formatted text fields and table cells. Also, all this formats can beaccessed from TROIA using system variables listed below to format custom texts that uses default date formats.

13.6. Basic Date Formatting/Parsing 89

Programming with TROIA, Release 0.5.beta

SYS_DATETIMEFORMAT Default datetime formatSYS_DATETIMESFORMAT Default datetime format that contains secondSYS_DATEFORMAT Default date formatSYS_TIMEFORMAT Default time formatSYS_TIMESFORMAT Default time format that contains second

OBJECT:STRING STRINGVAR3;

STRINGVAR3 = '';STRINGVAR3 = STRINGVAR3 + SYS_DATETIMEFORMAT + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + SYS_DATETIMESFORMAT + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + SYS_DATEFORMAT + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + SYS_TIMEFORMAT + TOCHAR(10);STRINGVAR3 = STRINGVAR3 + SYS_TIMESFORMAT + TOCHAR(10);

This system variables are supported after 5.02.05 and following versions, so it is not possible to use this variables on3.08.x and 5.01.x versions.

13.6.2 Date Formatting & Parsing Dates with TROIA

It is possible to parse and format date related types using default formats or different hard codded formats thanks toFORMATDATE() and PARSEDATE() functions.

FORMATDATE() function gets a date and format, returns a string due to given format. Here is an examples:

OBJECT:STRING NLN,STRING STRINGVAR3;

NLN = TOCHAR(10);STRINGVAR3 = '';

STRINGVAR3 = STRINGVAR3 + FORMATDATE(SYS_CURRENTDATE, 'yyyy.MM.dd') + NLN;STRINGVAR3 = STRINGVAR3 + FORMATDATE(SYS_CURRENTDATE, SYS_DATETIMEFORMAT) + NLN;STRINGVAR3 = STRINGVAR3 + FORMATDATE(SYS_CURRENTDATE, SYS_TIMESFORMAT)+ NLN;

PARSEDATE() function gets a string variable and format, returns and datetime variable. Here is an example:

OBJECT:STRING NLN,STRING STRINGVAR3;

NLN = TOCHAR(10);STRINGVAR3 = '';

STRINGVAR3 = STRINGVAR3 + PARSEDATE('2018.06.19', 'yyyy.MM.dd') + NLN;STRINGVAR3 = STRINGVAR3 + PARSEDATE('19.06.2018 17:25', SYS_DATETIMEFORMAT) + NLN;STRINGVAR3 = STRINGVAR3 + PARSEDATE('17:25:54', SYS_TIMESFORMAT)+ NLN;

This system functions are supported after 5.02.05 and following versions, so it is not possible to use this variables on3.08.x and 5.01.x versions.

90 Chapter 13. Working With Date/Datetime

Programming with TROIA, Release 0.5.beta

13.7 Database & Date Format

Date formats can be configured for each user, but on database layer only one date/datetime format is used. This formatis configured on Database section of “SYST06 - System Parameters” transaction. System automatically formats daterelated variables and table cells for database interactions without any TROIA level effort.

To format a date/datetime variable using database date format you must use GETDBDATESTR() function. GET-DBDATESTR() function is mostly used for preparing database queries that contains hardcode date/datetime values.Please run the code below and compare the result with your database date format configuration.

OBJECT:STRING STRINGVAR3;

STRINGVAR3 = GETDBDATESTR(SYS_CURRENTDATE);

13.8 Timezone

TROIA Platform, is able to show/present datetime data in a specific timezone due to user configuration without anyprogramming effort. This configuration is based on users, so each users uses its own timezone on presentation layerlike datetime text fields, table cells or reports. User based timezone configuration is handled by “SYST03 - SystemUsers” transaction. Users that has not a specific timezone configuration users system’s default configuration which isset on System Dates section of “SYST06 - System Parameters” transaction.

Although dates are presented on users’ timezone on user interface layer, system stores dates in a standard timezone,this configuration is called as “Database Timezone” and it is configured on Database section of “SYST06 - SystemParameters” transaction. Although database transaction configurable, it is not recommended to change thisconfiguration without a planned data migration, because it stores the timezone of all dates

Timezone information is a sensitive information because of data integrity, so if system senses some conflictions aboutuser, system or client devices’s timezone creates some warning messages. This messages can be disabled usingIgnoreTimezoneWarnings parameter on server settings file, its default value is “false”, so timezone warnings are on, ifyou set it to “true” this will turn warnings off.

13.9 Work Calendar

In TROIA, it is also possible to define some business layer calendars and make some date calculations like addingdays hours considering constraints of this calendars. This kind of date calculations are called “Work Calendar”, wewill discuss Work Calendars in following sections.

13.7. Database & Date Format 91

Programming with TROIA, Release 0.5.beta

92 Chapter 13. Working With Date/Datetime

CHAPTER 14

Inheritance & Cross

Inheritance is one of the key concepts of object oriented programming. This sections aims to introduce inheritanceand relelated concepts.

14.1 What is “Inheritance”?

Simply, inheritance is an object oriented programming mechanism that allows programmers to reuse class codes. Inthis method, programmers creates parent, child relationship between two class. A child class gets its features/behaviorfrom its parent through a heritage and modifies parent’s behaviors/features or adds new features/behaviours.

14.2 Inheritance on TROIA

TROIA is an object oriented programming language and supports inheritance for all TROIA item types (class, dialog,report, component).

As it is same in other programming languages, only inheriting an item does not mean changing its structure or be-haviour, it only means creating heritage from base class. In practical if you only inherit an item, you can use base itemwith child’s name. To change behaviour/structure, you must override one at least one method of base item or add anew method to child item. If you add a method which has same name with one of the base methods this means you“override” this method and change its behaviour. In TROIA jargon, overriding is called inheriting a method (In thisbook we will use “override method” term instead of “inherit method”).

In TROIA an item can inherit only one base item. In other words, a sub class can only have a single base class. But itis allowed to inherit a child class. For example class A” can inherit class B which is child of class C.

When it comes to technical background, for a good understanding of inheritance with all aspects, you need to know thatcompiler has the most important role in inheritance process, because all inheriting operations are performed on compiletime. While compiling a child class, compiler resolves parent/child information at first and after the compilation itcreates child item’s binary file. This binary file contains child item’s own controls/methods, additionally it has a kindof link with base’s binary data.

93

Programming with TROIA, Release 0.5.beta

14.2.1 Inheriting Classes

In class inheritance it is possible to add new methods to base class or override (called as inherit method in TROIA)methods of base class. To override a class you must indicate base class name in new class form on IDE (see classessection). When you inherit a class, method’s of base class are shown on object explorer in base class tree element.Image below shows the view of an inherited class on Object Expolorer and menu item to override one of base methods.

When you override a base class method, system creates a same named method on child class and this method isexecuted instead of base method and this allows changing base method’s behavior. Using same method, overriding_VARIABLES and _CONSTRUCTOR methods is also possible. With overriding this methods, it is possible to addmember variables and this means changing the structure of base class on its child (remember the key roles of thismethods.)

14.2.2 Inheriting Dialogs/Components

Inheriting dialog and component is also supported. To inherit a dialog, component you must set its base item innew item form (please see new dialog, component form on related sections). Overriding dialog methods is similarwith overriding base class methods which is mentioned previous sections. It is also possible to override controls andcontrol events on dialogs/components. Additionally, adding new controls and control events to child dialog/componentis possible. Here is an image below that shows creating a new dialog that inherits DEVT11D001 as base dialog (it isalso same for component inheritance).

94 Chapter 14. Inheritance & Cross

Programming with TROIA, Release 0.5.beta

After creating an inherited dialog, IDE shows base dialog name in property explorer(1), base dialog controls/methodson object explorer(2) and base dialog controls on dialog design panel (3). Please see the image below:

In dialog design panel it is not possible to change any control’s positon or other properties, because this controls arebase dialog’s controls. To change a control feature you must firsly override control using “inherit” button which islocated on control’s right click menu. Overriding a dialog control creates a new control on child dialog and this newcontrol overwrites same named control on parent dialog.

It is also possible to override a dialog and control events to change base item’s behavior. To override a control/dialogevent you must click “blue arrow” on control’s or dialog’s right click menu. This operation creates an event code onchild class with same id and overwrites base event, similar to overriding dialog and class methods.

To override control events, you don’t need to override control’s itself. Control’s data and events has different identifi-cation and both are overridable items.

In IDE Object Explorer and control/dialog right click menu, there are some small icons (colorful dots) for each method.This icons have special meanings and eases understanding whether method is an overriding method or not. Here aremeanings of icons:

Method/event does not override any parent method/event.

Method/event overrides a parent method/event.Used for only control or dialog/component/report events.Event is implemented in base class but not overridden bychild item.

14.3 Using SUPER() Keyword

SUPER() keyword adds overridden method’s code to overriding method on compile time. With this method overridingmethod can inherit overridden behaviour and perform additional behaviours. In other words SUPER() is not a functioncall, it is a compile level identifier. Therefore if base method has a RETURN command, overriding methods contentis ignored by TROIA interpreter. Assume that class A inherits class B and overrides its M1 method:

/* class B, method M1 */OBJECT:

(continues on next page)

14.3. Using SUPER() Keyword 95

Programming with TROIA, Release 0.5.beta

96 Chapter 14. Inheritance & Cross

Programming with TROIA, Release 0.5.beta

(continued from previous page)

TABLE T1;SELECT * FROM IASUSER

INTO T1;RETURN;

/* class A method */SUPER();CLEAR ALL T1;

On compile time, TROIA compiler adds M1 method of base class to child M1 and compiles the resulting code as M1method of child class. Here is the compiled M1 for class A:

/* class A methodon compile time */

OBJECT:TABLE T1;

SELECT * FROM IASUSERINTO T1;

RETURN;CLEAR ALL T1;

As it is obvious on this example, programmers who use SUPER() keyword must consider overridden methodcontent due to risk of canceling overriding content. Also it is not possible to getting return value of base functionusing SUPER() keyword, because it is not a function call its just a keyword.

Although SUPER() is usually used at the begining on overriding methods, it is also possible to use this methodanywhere on overriding method. SUPER() keyword can be used in class,dialog, component and report events andcodes (support on classes starts with 5.01.07 032901 and 5.02.03 032901) . Additionally, in _CONSTRUCTOR and_VARIABLES class there is no need to write SUPER() keyword because, TROIA compiler adds base class methodcontent to overriding class as default. For other methods programmers must add SUPER() keyword to overridingmethod.

14.3. Using SUPER() Keyword 97

Programming with TROIA, Release 0.5.beta

14.4 Using SUPER Object

SUPER object is relatively a new feature of TROIA programming language and it is supported after 5.01.07 032901and 5.02.03 032901. SUPER object is supported only classes. In other words it is not supported on dialogs,reportsand components.

SUPER object allows programmers to call base class methods as a regular method and get returning values, alsoprogrammers can ignore RETURN command which is used on called base class. Usage of SUPER object is similar tobase class identifiers on other programming language (base, super). For better understanding assume class A inheritsclass B and overrides M1 method.

/* class B M1 method */PARAMETERS:

INTEGER PARAM;DUMP 'B.M1';RETURN PARAM;

/* class A M1 method */PARAMETERS:

INTEGER PARAM;

LOCAL:INTEGER R;

DUMP 'A.M1';R = SUPER.M1(PARAM);R = R + 1;RETURN R;

With this configuration if you define an A instance and call it’s M1 method with the code below:

OBJECT:INTEGER RESULT,A INSTANCE;

RESULT = INSTANCE.M1(10);

Interpreter firstly calls M1 method of class A and it calls method of class B. After B.M1 returns, system executesremaining part of A.M1 as a regular fuction call. In this example interpreter assigns 11 value to RESULT variable.Please review trace below for better understanding of SUPER keyword:

[DEVT11D001.RUNBUTTON.2 4] : OBJECT:INTEGER RESULT,CLASS[A] INSTANCE;

(A) INSTANCE.M1.0[(A) INSTANCE.M1.0 2] : PARAMETERS

PARAM[10] <= 10[10][(A) INSTANCE.M1.0 5] : LOCAL:

INTEGER R;[(A) INSTANCE.M1.0 7] : DUMP 'A.M1'

OBJECT DUMP { Name:A.M1, Type: STRING, Value: A.M1 }(A.B) INSTANCE.M1.0[(A.B) INSTANCE.M1.0 2] : PARAMETERS

PARAM[10] <= PARAM[10][(A.B) INSTANCE.M1.0 3] : DUMP 'B.M1'

OBJECT DUMP { Name:B.M1, Type: STRING, Value: B.M1 }

(continues on next page)

98 Chapter 14. Inheritance & Cross

Programming with TROIA, Release 0.5.beta

(continued from previous page)

[(A.B) INSTANCE.M1.0 4] : RETURN PARAM : PARAM[10]

[(A) INSTANCE.M1.0 8] : R = SUPER.M1(PARAM); [10][(A) INSTANCE.M1.0 9] : R = R + 1; [11][(A) INSTANCE.M1.0 10] : RETURN R : R[11][DEVT11D001.RUNBUTTON.2 6] : RESULT = INSTANCE.M1(10); [11]

14.5 What is “Cross”?

Simply, a cross is a definition that forces class/dialog loaders to use another class/dialog instead of defined item. Forexample if you define a cross from class A to class B, system loads class B instead of A anywhere class A is defined.Cross is a database record and it is read and applied on runtime, in other words it is not a part of compiling process.With crosses; there is no need to chage/modify standart application, so customer customizations need less efford andtime.

Crosses are mostly used with an inherited class that changes structure/behavior of a base class or adds new function-alities to a base class. Assume that we have CAT class which have a MOVE method. This method increases the xposition five by five. Here is the pseudocode of the structure and method of CAT class.

class CAT:MEMBER:

INTEGER X;

function MOVEX = X + 5;RETURN;

/* this code is not compilable,it is just for assumption */

and in somewhere of the standart application, an instance of CAT class is defined and its move method is called likebelow:

OBJECT:CAT RECCAT;

RECCAT.MOVE();

And assume again CATs on your company are lazy and move one by one. To solve this case you must find all CATdefinitions and change them to your child LAZYCAT class or do something like a factory pattern to decide which cattype will be created. With cross concept you don’t need to find and change all definitions. If you define a cross fromCAT to your LAZYCAT class, system laods LAZYCAT instead of CAT class in all applications. Although cross ismostly used from a base item to a child item, it is possible to define a cross between independent classes (but pleasethink on possible problems about crossing independent items).

It is possible to define crosses for dialogs, classes, reports and components. Cross definitions for classes usually called“class cross” and others are called “dialog cross”.

14.6 Cross Levels & Loading Order

It is possible to define crosses in two level: “system cross” and “user cross”. A system cross is system wide and ifyou define a system cross, this cross is valid for all users that connects to same database. User crosses are defined for

14.5. What is “Cross”? 99

Programming with TROIA, Release 0.5.beta

a user or a profile, so this kind of crosses are valid for a user or users defined in a profile.

System; firstly reads system crosses. After system crosses; user crosses are read starting with deepest profile, andfinally user’s own crosses are read. Latest cross owerwrites previous cross definitions. In other words, priority order isuser’s own crosses, user’s profile crosses, system crosses. Also it is possible to define crosses as chain here is a chaincross sample:

A -> BB -> CC -> D

Cross information is loaded while user logging in, so crosses that defined/deleted while user online are ignored untiluser login again.

To remove a cross you can define a cross from item’s itself (A -> A). But defining crosses as an infinite loop in morethan one step is considered as TROIA level error and this may cause stackowerflow error or infinite loop on login.Here is an invalid cross definition:

A -> BB -> CC -> A

14.7 How to Define Crosses

For classes, system crosses are defined in “DEVT08 - Class Dynamic Link” transaction. To define a system cross fora class required data is only names of crossing and crossed class. System cross cross definitions for classes are storedin SYSCLSREF system table. To define cross for dialogs, reports and components “DEVT09 - Dialog Dynamic Link”transaction is used and this transaction uses SYSDLGREF system table to store cross definitions.

For users and user profiles; crosses are defined in “Class Reference” and “Dialog Reference” tabs of “SYS03 - UserLogin Info” transaction. User cross definitions are stored in IASUSERCLSREF and IASUSERDLGREF tables. As itis obvious; all user crosses are related with user definition and when user is deleted, all cross definitions are deleted.

14.8 Example 1: Inheriting Class and Overriding Methods

Create an animal class as a base class. An animal;

• has a location (x,y)

• can walk, walking increases x position by step size

• has a step size (default is 0)

Create a child cat class that inherits animal. A cat;

• can walk 1 meter in one step

• can jump 1 meters

Create a child cheetah class that inherits cat class. A cheetah;

• can walk 5 times faster than a cat

• can jump 3 times higher than a cat

Write TROIA code that creates a cat and a cheetah call their MOVE and JUMP methods and compare their x and yposition.

100 Chapter 14. Inheritance & Cross

Programming with TROIA, Release 0.5.beta

OBJECT:RDCAT CAT1,RDCHEETAH CHEETAH1;

CAT1.WALK();CAT1.JUMP();

CHEETAH1.WALK();CHEETAH1.JUMP();

STRINGVAR2 = CAT1@XPOSITION + '-' + CAT1@YPOSITION;STRINGVAR3 = CHEETAH1@XPOSITION + '-' + CHEETAH1@YPOSITION;

14.9 Example 2: Understanding Cross Order

Assume a U1 user whose user profile is P1 and P1’s base profile is P0. Cross definitions are like below:

SYSTEM : A -> BSYSTEM : C -> DSYSTEM : E -> FSYSTEM : G -> HP0 : K -> LP0 : A -> NP1 : A -> XP1 : C -> CU1 : A -> YU1 : F -> Z

What is the final cross table for the user?

14.9. Example 2: Understanding Cross Order 101

Programming with TROIA, Release 0.5.beta

102 Chapter 14. Inheritance & Cross

CHAPTER 15

File Operations

File operations, is one of the basic functionalities of programming languages. In TROIA programming language, fileoperations are simplified and has extended features to help programmers. This sections aims to introduce basics offile operations and extended features.

15.1 Introduction

As mentioned before, TROIA platform has an multitier architecture. As a result of this architecture, some file opera-tions are available in server, client or both client and server. Even if some file operations are available on client side,(as all TROIA commands) file commands run on server side and returns result to client.

Client side paths has * character as a prefix to separate them from a server side path. So programmers must send filepaths starting with * (star) character, to point a client side path.

OBJECT:STRING STRPATH;

/* client side path samples */STRPATH = '*C:\USERS\BTAN\Desktop\sourcefile.txt';STRPATH = '*C:\TMP\sourcefile.txt';

/* server side paths */STRPATH = 'C:\TMP\sourcefile.txt';STRPATH = '\Files\sourcefile.txt';

Using relative paths starts from user.dir on client side, but it is not recommended to use relative paths on clientside.Relative paths is more useful for server side to implement portable applications, it starts from the folder thatapplication runs on.

GETUSERINFO() system function returns some useful information for file operations on client side such as file sep-arator, temp folder etc. Here is some useful information, returned by GETUSERINFO method. For more informationabout the method plese see TROIA Help:

103

Programming with TROIA, Release 0.5.beta

OBJECT:STRING S1,STRING STRINGVAR3;

S1 = 'Temp Folder: ' + GETUSERINFO('client.temp.folder');S1 = S1 + TOCHAR(10) + 'File Sep: ' + GETUSERINFO('file.separator');S1 = S1 + TOCHAR(10) + 'User Home: ' + GETUSERINFO('user.home');S1 = S1 + TOCHAR(10) + 'User Dir: ' + GETUSERINFO('user.dir');S1 = S1 + TOCHAR(10) + 'Java Home: ' + GETUSERINFO('java.home');S1 = S1 + TOCHAR(10) + 'File Enc: ' + GETUSERINFO('file.encoding');S1 = S1 + TOCHAR(10) + 'SetGet Folder: ' + GETUSERINFO('user.setgetfolder');

STRINGVAR3 = S1;

And here is the result of sample code, please run the code on your own client and see the difference:

Temp Folder: C:\Users\btan.IASRDDC\RESOURCES\TMP\File Sep: \User Home: C:\Users\btan.IASRDDCUser Dir: C:\603server\toWebJava Home: C:\Program Files\Java\jre7File Enc: Cp1254SetGet Folder: C:\603server\RESOURCES\SETGET\LOCAL\IAS604502\btan\

Also its possible to read some useful information about server side to use on file operations. Server side information isprovided by SYSGETSERVERINFO() method. Here is the sample code and its result for SYSGETSERVERINFO()method:

OBJECT:STRING S1,STRING STRINGVAR3;

S1 = 'File Sep: ' + SYSGETSERVERINFO('file.separator');S1 = S1 + TOCHAR(10) + 'Trace Folder: ' + SYSGETSERVERINFO('TraceFolder');

STRINGVAR3 = S1;

File Sep: \User Home: TRACES

15.2 Opening/Closing Files

To open files, OPEN FILE command is used. Command takes file path and file open mode. File open mode shows theaim of opening file, such as creating new file, appending or reading. Default open mode is FORAPPEND. Here is thesyntax to open files:

OPEN FILE {file_path} [FORNEW|FORREAD|FORAPPEND] [FILEID { fileid }];

CLOSE FILE command closes the file. As default it takes no argument because it closes file which already opened.Here is the syntax:

CLOSE FILE [FILEID { fileid }];

All basic file operations are performed on server side. But it is allowed to access client side files. System copies clientside file to server and sends to client after the operation. If file transfer is not necessary due to open mode system

104 Chapter 15. File Operations

Programming with TROIA, Release 0.5.beta

does not copy opened file. On database transactions it is not recommended to access files on client side. Due toEnableDBTransactionUnityCheck configuration system may show an warning messages when accessing file in clientside inside a database transaction. For more detail please see related sections. Here is the matrix that shows theoperation due to file open modes:

FORREAD FORAPPEND FORNEWOPENFILE

Copy file from client to serverand open

Copy file from client to serverand open

Just open file

CLOSEFILE

Just close file Close file. Copy file fromserver to client

Close file. Copy file from serverto client.

Both CLOSE FILE and OPEN FILE commands set SYS_STATUS to 1, if operation fails. Also SYS_STATUSERRORis set to error message. Here is an example that tries to read an unexisting file. Reading an unexisting file is an error,but appending to an unexisting file is not error. All file operations automatically creates required folders, so usingunexisting folders is not an error (provided that user have required permissions). Here is two examples that showssuccessful and unsuccessful attempts of opening/closing files:

OBJECT:STRING STRPATH,STRING STRINGVAR3;

STRPATH = '*C:\TMP\UnknownFile.txt';STRINGVAR3 = 'Open File: ';OPEN FILE STRPATH FORREAD;

IF SYS_STATUS == 0 THENSTRINGVAR3 = STRINGVAR3 + 'successful' + TOCHAR(10);

ELSESTRINGVAR3 = STRINGVAR3 + 'failed!' + TOCHAR(10);

ENDIF;

STRINGVAR3 = STRINGVAR3 + 'Close File: ';CLOSE FILE;

IF SYS_STATUS == 0 THENSTRINGVAR3 = STRINGVAR3 + 'successful' + TOCHAR(10);

ELSESTRINGVAR3 = STRINGVAR3 + 'failed!' + TOCHAR(10);

ENDIF;

OBJECT:STRING STRPATH,STRING STRINGVAR3;

STRPATH = '*C:\TMP\NewFile.txt';STRINGVAR3 = 'Open File: ';OPEN FILE STRPATH FORNEW;

IF SYS_STATUS == 0 THENSTRINGVAR3 = STRINGVAR3 + 'successful' + TOCHAR(10);

ELSESTRINGVAR3 = STRINGVAR3 + 'failed!' + TOCHAR(10);

ENDIF;

STRINGVAR3 = STRINGVAR3 + 'Close File: ';CLOSE FILE;

(continues on next page)

15.2. Opening/Closing Files 105

Programming with TROIA, Release 0.5.beta

(continued from previous page)

IF SYS_STATUS == 0 THENSTRINGVAR3 = STRINGVAR3 + 'successful' + TOCHAR(10);

ELSESTRINGVAR3 = STRINGVAR3 + 'failed!' + TOCHAR(10);

ENDIF;

All open files must be closed by programmer, in other words; open files after file operations end are considered TROIAprogramming errors.

15.2.1 Working With Multiple Files

FILEID is optional argument for both OPEN FILE and CLOSE FILE commands. It defines a unique name for openedfile. As default, system allow does not allow opening multiple files concurrently. Here is an invalid file operation,please try to find why this sample is an invalid logically.

/* !!! Warning: This is an invalid code */OBJECT:

STRING STRPATH1,STRING STRPATH2;

STRPATH1 = '*C:\TMP\NewFile1.txt';STRPATH2 = '*C:\TMP\NewFile2.txt';

OPEN FILE STRPATH1 FORNEW;OPEN FILE STRPATH2 FORNEW;

/* do something on files, part 1 */

CLOSE FILE;

/* do somehing on files, part 2 */

CLOSE FILE;

If you programmers want to open another file before closing first one, they must be provide FILEID for each command.FILEID is a unique id and shows which file will be affected from the operation. If FILEID is not provided, systemuses a defult file id. Correct code to open multiple files concurrently is below, in this example system is able to knowwhich file will be closed on each close attempt.

OBJECT:STRING STRPATH1,STRING STRPATH2;

STRPATH1 = '*C:\TMP\NewFile1.txt';STRPATH2 = '*C:\TMP\NewFile2.txt';

OPEN FILE STRPATH1 FORNEW FILEID F1;OPEN FILE STRPATH2 FORNEW FILEID F2;

/* do something on files, part 1 */

CLOSE FILE FILEID F2;

/* do somehing on files, part 2 */(continues on next page)

106 Chapter 15. File Operations

Programming with TROIA, Release 0.5.beta

(continued from previous page)

CLOSE FILE FILEID F1;

As it is obvious that each file access requires a FILEID parameter, to determine which file will be modified or read, soall file manipulation commands get FILEID parameter. Please focus on FILEID syntax in file related commands.

15.3 Writing Files & Reading Files

Writing and reading are the most used and important file manipulation operations. Like other programming languages,before reading or writing files, file must be opened.

15.3.1 Writing Files

To write files PUT command is used. PUT supports encoding with CODEPAGE parameter, this encoding (utf-8, utf-16 etc) is used while converting given text to bytes. If encoding is not provided system uses ISO8859_9 as defaultencoding. Each PUT command adds a new line (\n) and carriage return (\r) character to the end of given parameters.To disable these two endline characters NODENDOFLINE optional parameter is used.

PUT {valuelist} [CODEPAGE {encoding}] [NOENDOFLINE] [FILEID {fileid}];

Here is a sample code which uses different variations of PUT command. Please check file content and compare withthe code and its trace.

OBJECT:STRING STRPATH;

OBJECT:STRING STRVALUE;

STRVALUE = 'This is ';STRPATH = '*C:\TMP\SourceFile3.txt';OPEN FILE STRPATH FORNEW;PUT 'This is first line';PUT STRVALUE, 'second line';PUT STRVALUE NOENDOFLINE;PUT 'third line';PUT STRVALUE, 'fifth line' CODEPAGE 'ISO8859_9';CLOSE FILE;

PUT command also has FILEID option to write files which have an id.

OBJECT:STRING STRPATH,STRING STRPATH2;

STRPATH = '*C:\TMP\SourceFile4.txt';STRPATH2 = '*C:\TMP\SourceFile5.txt';

OPEN FILE STRPATH FORNEW FILEID 'F1';OPEN FILE STRPATH2 FORNEW FILEID 'F2';

PUT 'This is first file' FILEID 'F1';

(continues on next page)

15.3. Writing Files & Reading Files 107

Programming with TROIA, Release 0.5.beta

(continued from previous page)

PUT 'This is second file' FILEID 'F2';

CLOSE FILE FILEID 'F1';CLOSE FILE FILEID 'F2';

15.3.2 Reading Files

GET {variablelist} [CODEPAGE {encoding}] [FILEID {fileid}];

OBJECT:STRING STRPATH,STRING STRINGVAR1,STRING STRINGVAR3;

STRINGVAR3 = '';STRPATH = '*C:\TMP\SourceFile3.txt';OPEN FILE STRPATH FORREAD;

WHILE 1BEGIN

GET STRINGVAR1;

IF STRINGVAR1 == '' THENBREAK;

ENDIF;

STRINGVAR3 = STRINGVAR3 + STRINGVAR1 + '/';ENDWHILE;

CLOSE FILE;

OBJECT:STRING STRPATH,STRING STRPATH2;

STRINGVAR3 = '';STRPATH = '*C:\TMP\SourceFile4.txt';STRPATH2 = '*C:\TMP\SourceFile5.txt';

OPEN FILE STRPATH FORREAD FILEID 'F1';OPEN FILE STRPATH2 FORREAD FILEID 'F2';

WHILE 1BEGIN

GET STRINGVAR1 FILEID 'F1';

IF STRINGVAR1 == '' THENBREAK;

ENDIF;

STRINGVAR3 = STRINGVAR3 + STRINGVAR1 + '/';ENDWHILE;

STRINGVAR3 = STRINGVAR3 + TOCHAR(10);

(continues on next page)

108 Chapter 15. File Operations

Programming with TROIA, Release 0.5.beta

(continued from previous page)

WHILE 1BEGIN

GET STRINGVAR1 FILEID 'F2';

IF STRINGVAR1 == '' THENBREAK;

ENDIF;

STRINGVAR3 = STRINGVAR3 + STRINGVAR1 + '/';ENDWHILE;

CLOSE FILE FILEID 'F1';CLOSE FILE FILEID 'F2';

..getblock

GETBLOCK {variable}, {delimiter} [CODEPAGE {encoding}] [FILEID {fileid}];

OBJECT:STRING STRPATH;

STRPATH = '*C:\TMP\SourceFile3.txt';

OPEN FILE STRPATH FORREAD;GETBLOCK STRINGVAR3,' is ';STRINGVAR3 = STRINGVAR3 + TOCHAR(10);CLOSE FILE;

OBJECT:STRING STRPATH;

STRPATH = '*C:\TMP\SourceFile3.txt';

OPEN FILE STRPATH FORREAD;GETBLOCK STRINGVAR3,'';STRINGVAR3 = STRINGVAR3 + TOCHAR(10);CLOSE FILE;

15.4 Copying Files

OBJECT:STRING STRSOURCEPATH,STRING STRDESTPATH;

STRSOURCEPATH = '*C:\TMP\SourceFile3.txt';STRDESTPATH = '*C:\TMP\SourceFile3_Copy.txt';

COPYFILE STRSOURCEPATH INTO STRDESTPATH;

15.4. Copying Files 109

Programming with TROIA, Release 0.5.beta

15.5 Other File & Directory Operations

15.5.1 Listing Files in a Directory

FILELIST {directorypath} TO {targettable};

OBJECT:STRING STRPATH;

STRPATH = '*C:\TMP\';

DESTROYTABLE TMPTABLE;FILELIST STRPATH TO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

15.5.2 Checking File Existence

To check whether a file exists or not, you must use FILEEXISTS command. This is the faster way of checking fileexistence. This command is supported on the versions after 5.02.05 062001.

FILEEXISTS {filepath};

OBJECT:STRING STRINGVAR1;

STRPATH = '*C:\TMP\myfile.txt';

FILEEXISTS STRINGVAR1;IF SYS_STATUS THEN

STRINGVAR3 = 'File does not exist.';ELSE

STRINGVAR3 = 'File exists.';ENDIF;

15.5.3 Deleting Files

DELTEFILE {filepath};

OBJECT:STRING STRPATH;

STRPATH = '*C:\TMP\SourceFile3_Copy.txt';DELETEFILE STRPATH;

15.5.4 Digesting Files

DIGESTFILE {path} INTO {targetsymbol} [USING {hashingalgorithm}];

110 Chapter 15. File Operations

Programming with TROIA, Release 0.5.beta

OBJECT:STRING STRPATH;

STRPATH = '*C:\TMP\SourceFile3.txt';COPYFILE STRPATH INTO 'SourceFileOnServer.txt';DIGESTFILE 'SourceFileOnServer.txt' INTO STRINGVAR3 USING 'SHA1';DELETEFILE 'SourceFileOnServer.txt';

DESTROYTABLE TMPTABLE;FILELIST '.' TO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;SORT TMPTABLE ON NAME;

15.6 File Compression

ZIPFILE {filepath} INTO {targetzipfile};

OBJECT:STRING STRPATH,STRING STRPATH2;

STRPATH = '*C:\TMP\SourceFile4.txt';STRPATH2 = '*C:\TMP\SourceFile5.txt';

COPYFILE STRPATH INTO 'ServerSourceFile4.txt';COPYFILE STRPATH2 INTO 'ServerSourceFile5.txt';

ZIPFILE 'ServerSourceFile4.txt|ServerSourceFile5.txt' INTO 'Demo.zip';

COPYFILE 'Demo.zip' INTO '*C:\TMP\Demo.zip';DELETEFILE 'Demo.zip';

UNZIPFILE {zipfilepath} INTO {targetdirectory};

OBJECT:STRING STRPATH,STRING STRPATH2;

STRPATH = '*C:\TMP\UnzippedSourceFile4.txt';STRPATH2 = '*C:\TMP\UnzippedSourceFile5.txt';COPYFILE '*C:\TMP\Demo.zip' INTO 'Demo.zip';

UNZIPFILE 'Demo.zip' INTO '.\';

COPYFILE 'ServerSourceFile4.txt' INTO STRPATH;COPYFILE 'ServerSourceFile5.txt' INTO STRPATH2;

DELETEFILE 'Demo.zip';

15.7 Exercise 1: Writing Files

Write a piece of TROIA code that:

15.6. File Compression 111

Programming with TROIA, Release 0.5.beta

• Writes the list of files in a given folder to a file.

15.8 Exercise 2: Working With Multiple Files

Modify the code that you write for previous exercise and write a TROIA code that

• opens a file

• read blocks until the end of file.

• write each word and its length to another file.

format [word [4]]

another [7] and [3] another [7]

Please be sure that your code opens two files concurrently.

15.9 Exercise 3: Prepare Zip Content

• Prepare two files that contains digest data (SHA1) of two files.

• Create a zip file that contains 4 files.

• Copy zip file to client’s temporary folder.

• Delete all temporary files in server.

112 Chapter 15. File Operations

CHAPTER 16

Custom TROIA Components

Its possible to define custom business layer components and use instances of these components on different dialogs orother components. This sections aims to show how “custom components” are defined and used.

While developing dialog user interfaces, programmers use ui items such as buttons, text fields, labels (ui controls).But in some cases, programmers may need to reuse a set of controls on different dialogs to avoid copying and pastingexisting codes on different dialogs. A custom TROIA component is a reusable custom ui control which contains oneor more simple controls to perform a specific action. Custom components are a type of TROIA development itemssuch as dialogs or classes. Custom TROIA component is called as “component”, shorty.

For instance, for a fligh reservation application you may need two date chooser one is for departure date and secondone is returning departure date and you have to make a set of validity checks whether inserted dates are valid or correctorder etc. If you write whole required code on a dialog, you have to controls troia code when you need a similar controlset for an hotel reservation application. Using component infrastructure you define your date chooser as a componentand use it on different dialogs.

16.1 How Components Stored?

As it is obvious, components have controls, control events and methods. Therefore a component is similar to di-alog from the aspect of items that they have. Similar to dialogs component data is stored on development tableswhich are already used for storing dialogs. This tables are SYSDIALOGS, SYSDLGTEXTS, SYSDLGCODES,SYSDLGFUNCTEX, SYSCONTROLS, SYSCTLTEXTS. For more information about the roles of this table, pleasesee “Dailog Basics/How Dialogs are Stored?” section.

16.1.1 Defining Components

Similar to other troia development items, components are defined using TROIA IDE, too. To create a new component,you must click TROIA IDE-> New -> New Component on menu and fill the new component form which is verysimilar to new dialog form.

In this form you, must select a hotline (change request) and enter a valid component name. A valid component nameis unique and at least four characters length similar to dialogs.

113

Programming with TROIA, Release 0.5.beta

Inheriting and defining cross references are also supported for components and works in same way with dialogs. Pleasesee the related section to get more informatin about inheriting.

After you click “OK” button, IDE creates a new component and opens design window. In this design window you cancreate your component due to your requirements. Here is my sample component that has two date fields on it.

16.1.2 Using Components

To use a component on a dialog, you must just drag a “TROIA Component” (1) from toolbox and drop it on dialog(2). And write the component name to “Component” feature of your dragged control (3). Each component instancemust have a unique control name such as other controls.

114 Chapter 16. Custom TROIA Components

Programming with TROIA, Release 0.5.beta

After saving and calling the dialog, the final view is below. This dialog has two component instances named C1 (1)and C2 (2).

16.2 Nested Components

It is also possible to use components inside other components. This process is totally same with using a component ondialog.

16.2.1 Component Events

Components have a predefined event named INITIALIZE which is called when a component instance is created. Withthis method TROIA programmers are able to set initial state of a component. To implement INITIALIZE methodyou must right click to component on design view (1) or double click the evet on events explorer which is under theproperties explorer (2).

For example if you write the code below to initialize method. Components shows current date as DATEFROM andtomorrow as DATETO.

DATEFROM = CURRENTTIMEMILLIS();DATETO = ADDDAYS(DATEFROM, 1);

16.2.2 Components & Scope

Developers are not able to know in which dialogs component will be used while developing a component. Whatif varaible names conflicts with existing variables on dialogs? or if a dialog changes one of component’s variable?

16.2. Nested Components 115

Programming with TROIA, Release 0.5.beta

116 Chapter 16. Custom TROIA Components

Programming with TROIA, Release 0.5.beta

Actually this questions are not valid for components because components have their own scope, so even a variabledefined in compoent has same name with a dialog component they are not same variables. Therefore conflictions arenot possible. For example, SYS_STATUS in component scope is not same with SYS_STATUS in global scope, theyare totally different variables.

16.3 Accessing Variables Which Defined in Component

As a result of component’s have a different scope, it is not possible to access (read or set) variables defined in com-ponent from dialog codes. To do this you must call component’s public methods, if component have such methods.Defining getter/setter methods is the responsibility of programmer who developes component. Calling componentmethods will be discussed in next sections.

16.4 Calling Dialogs from Components

Also it is possible to call a dialog from component. Dialogs which is called from dialogs are a part of the component,so all variables defined on dialog (by code or control symbols) are located in component’s scope.

16.4.1 Calling Component Methods

Components is able to have some public methods that can be called from outside the component. To define such amethod, you must select “Add Method” from right click menu on IDE and fill method content.

Calling a component’s method is not different from calling a class method. You must call the method for the com-ponent’s instance name. Here is sample dialog code that calls SETVALUS() method of C1 which is an instance ofDEMOCOMPONENT.

C1.SETVALUES('01.01.2016 10:10:10', '01.02.2017 10:10:10');

This code runs on C1’s context and changes only FROM and TO dates of C1 instance. Other instances of DEMO-COMPONENT are not affected from this call.

16.3. Accessing Variables Which Defined in Component 117

Programming with TROIA, Release 0.5.beta

16.4.2 Component Actions

In some cases, behaviour of a component can be change due to dialog that it is used on. For example, if user entersa date which is later than TO date to FROM field our component must warn the user. But warning message can bechange due to dialog or component instance. In this cases, components can contain some abstract methods that mustbe filled for each component instance. To define such an action, action names must be defined in ACTION field onIDE Properties Explorer. For multiple actions, use semicolumn as seperator.

Basically, component actions are similar to any control event like buttons’ Click or textfields’ LoseFocus

This actions are implemented for each instance of component and part of dialogs that component is used, by rightclicking on the component instance on IDE. To fire an action FIRECOMPONENTEVENT is used. Here is the basicsyntax:

FIRECOMPONENTEVENT {eventname};

For example, we can check whether FROM date is earlier than TO date in our component. Assume that we have aCHECKVALIDITY() method on component and it is called from TextChanged events of DATETO and DATEFROMtextfields. Here is the code of CHECKVALIDITY() method of our component.

IF DATEFROM > DATETO THENFIRECOMPONENTEVENT 'INVALIDDATE';

ENDIF;

118 Chapter 16. Custom TROIA Components

CHAPTER 17

Working with FTP Servers

TROIA Platform supports file transfer operations between application server and file server. This section aims tointroduce ftp operations and related commands.

17.1 Introduction

FTP Operations are supported on builds after after 5.01.04 041203 in Secure File Transfer Protocol (also known asSFTP or SSH File Transfer Protocol), FTP (also known as File Transfer Protocol), FTPS (File Transfer Protocol SSL)protocols.

All FTP operations are performed on application server,so transferring files from/to client is not supported.

17.2 Connection to FTP Server

All file server operations must be executed inside and file server connection which is established using MAKEFTP-CONNECTION command. MAKEFTPCONNECTION command takes host, port, username and password to connectfile server. Port parameter is optional and default ports are 21 for FTP, 990 for FTPS, 22 for SFTP.

Additionally, programmers must provide the connection protocol to MAKEFTPCONNECTON command. This optionis not a symbol and must be selected on development phase. Protocol parameter is optional and default option is FTP.

Here is the syntax of the command:

MAKEFTPCONNECTION HOST {host} [PORT {port}] [USERNAME {username}][PASSW {password}][PROTOCOL {FTP|FTPS|SFTP}];

System allows creating multiple sessions to different file servers, but there is no need to create multiple sessions tosame file server. Distinctive parameter between different servers is HOST parameter of connection, so system does notallow multiple connections to same host. Scope of connection management is execution context, so every transactionor TROIA component has its own connection pool.

119

Programming with TROIA, Release 0.5.beta

TROIA programmer is responsible close all connections after operation finished. CLOSEFTPCONNECTION com-mand is used to close connection which is established by MAKEFTPCONNECTION. Here is the syntax:

CLOSEFTPCONNECTION {host};

Additionally system tries to kill remaining open connections before transaction close operation, but it is not recom-mended to leave ftp connections open after all ftp operations finished. Here is a sample code that connects an ftp serverand closes connection. Please test the code with valid/invalid host and login cridentials.

OBJECT:STRING FTPHOST,STRING FTPPASS,STRING FTPUSER;

FTPHOST = 'anyftp.com.tr';FTPUSER = 'user';FTPPASS = 'password';

MAKEFTPCONNECTION HOST FTPHOST USERNAME FTPUSER PASSW FTPPASS PROTOCOL FTP;

IF SYS_STATUS == 0 THEN/* connection is successful */

ELSE/* connection failed */

ENDIF;

CLOSEFTPCONNECTION FTPHOST;

17.2.1 Possible Errors on FTP Connections

Both MAKEFTPCONNECTION and CLOSEFTPCONNECTION commands set SYS_STATUS andSYS_STATUSERROR, if connect/disconnect process fails. Also all exceptional cases are inserted to tracefiles. Here are some possible exceptions and solutions.

• java.lang.NoClassDefFoundError: missing required libraries, please read installation/deployment section.

• com.ias.server.ftp.iasFileServerException: java.net.UnknownHostException: Application server cannotaccess given host, check your connection.

• ftp connection is already exists to . . . : System does not allow to create multiple connections to same fileserver. Please be sure that you closed your ftp connection. Additionally, multiple file transfe operations allowedon a single connections, so there is no need to create connection again.

• login or password incorrect! or . . . Auth Fail : Invalid connection credentials

• request timeout while connecting host . . . : To establish connection between application server and ftp server,max waiting period is 10 seconds. If ftp server does not send response of connection within 10 seconds, systemsets this error to SYS_STATUSERROR

17.3 Working Directory

After connection established to file server, a working directory is assigned to a client and all commands executed inthis path. Also, relative file paths are computed from this working directory.

To read, currently which directory are you working on FTPRUNCOMMAND’s CURRENTDIRECTORY variation isused. Changing working directory is possible with FTPRUNCOMMAND’s CHANGEDIRECTORY variation. This

120 Chapter 17. Working with FTP Servers

Programming with TROIA, Release 0.5.beta

command also allows some other operations on FTP server for more information please see the command help. Hereis the syntax of two variations.

FTPRUNCOMMAND CURRENTDIRECTORY TO {targetvariable} ON {host};FTPRUNCOMMAND CHANGEDIRECTORY {pathonftpserver} ON {host};

17.4 Transferring Files

As main functionalities of ftp operations uploading and downloading files must be executed in a FTP connectionwhich is established by MAKEFTPCONNECTION command. Also user information and permissions is about theconnection. Both uploading and dowloading commands gets host which shows ftp connection to perform operationon.

All upload and download paths are computed relatively from working directory. So programmers must be sure theyare in correct working directory before upload and download files.

Path which file downloaded to/uploaded from must be a valid path on application server. Paths starting with * (clientside paths) are not valid for FTP operations. If files are located on client or must be downloaded to client, programmersmust transfer file to the server using related file commands.

17.4.1 Downloading Files

To download files FTPDOWNLOAD command is used. Here is the syntax of the command:

FTPDOWNLOAD {pathonftpserver} TO {localpath} FROM {host};

If downlaoding operation fails, system sets SYS_STATUS and SYS_STATUSERROR system variables, also excep-tions are inserted to trace. Possible uploading problems are below:

• invalid local path . . . : local path is empty string or client side path (starts with *)

• invalid ftp server path: remote file path is empty string

• there is not a ftp connection to host . . . : invalid connection id, invalid host. Check your connection is open.

• permission failure: check ftp user rights, whether user have required privileges to download file.

OBJECT:STRING FTPHOST,STRING FTPPASS,STRING FTPUSER,STRING LOCALPATH,STRING FTPSERVERPATH;

FTPHOST = 'anyftp.com.tr';FTPUSER = 'user';FTPPASS = 'password';FTPSERVERPATH = 'file.xml';LOCALPATH = 'TempFiles\file.xml';

MAKEFTPCONNECTION HOST FTPHOST USERNAME FTPUSER PASSW FTPPASS PROTOCOL FTP;

IF SYS_STATUS == 0 THENFTPDOWNLOAD FTPSERVERPATH TO LOCALPATH FROM FTPHOST;

ENDIF;

(continues on next page)

17.4. Transferring Files 121

Programming with TROIA, Release 0.5.beta

(continued from previous page)

CLOSEFTPCONNECTION FTPHOST;

17.4.2 Uploading Files

To upload files FTPUPLOAD command is used. Here is the synta of the command:

FTPUPLOAD {localpath} TO {host};

If uploading operation fails, system sets SYS_STATUS and SYS_STATUSERROR system variables, also exceptionsare inserted to trace. Possible uploading problems are below:

• invalid local path . . . : local path is empty string or client side path (starts with *)

• there is not a ftp connection to host . . . : invalid connection id, invalid host. Check your connection is open.

• permission failure: check ftp user rights, whether user have required privileges to upload file.

OBJECT:STRING FTPHOST,STRING FTPPASS,STRING FTPUSER,STRING LOCALPATH,STRING FTPSERVERPATH;

FTPHOST = 'anyftp.com.tr';FTPUSER = 'user';FTPPASS = 'password';FTPSERVERPATH = 'file.xml';

MAKEFTPCONNECTION HOST FTPHOST USERNAME FTPUSER PASSW FTPPASS PROTOCOL FTP;

IF SYS_STATUS == 0 THENFTPUPLOAD LOCALPATH TO FTPHOST;

ENDIF;

CLOSEFTPCONNECTION FTPHOST;

17.5 Listing Files

FTP Infrastructure supports listing files. Operation is fired by FTPRUNCOMMAND command’s LISTFILE variationand executed as working directory. Result of this command must be assigned to a table symbol, similar to FILELISTcommand. This command also allows some other operations on FTP server for more information please see thecommand help. Here is the syntax to list files:

FTPRUNCOMMAND FILELIST TO {targettable} ON {host};

Here is an example that lists and prints file on initial directory.

OBJECT:STRING FTPHOST,STRING FTPPASS,STRING FTPUSER,

(continues on next page)

122 Chapter 17. Working with FTP Servers

Programming with TROIA, Release 0.5.beta

(continued from previous page)

TABLE FILESTABLE,STRING STRINGVAR3;

FTPHOST = 'anyftp.com.tr';FTPUSER = 'user';FTPPASS = 'password';

MAKEFTPCONNECTION HOST FTPHOST USERNAME FTPUSER PASSW FTPPASS PROTOCOL FTP;

IF SYS_STATUS == 0 THEN

FTPRUNCOMMAND FILELIST TO FILESTABLE ON FTPHOST;

LOOP AT FILESTABLEBEGIN

STRINGVAR3 = STRINGVAR3 + FILESTABLE_NAME + TOCHAR(10);ENDLOOP;

ENDIF;

CLOSEFTPCONNECTION FTPHOST;

17.6 Creating/Deleting Folders and Files

Infrastructure allows TROIA programmer to create and delete folders on working directory. These operations areexecuted on a ftp connection which is established by MAKEFTPCONNECTION command. To create and deletefolders and delete files use FTPRUNCOMMAND command. This command also allows some other operations onFTP server for more information please see the command help. Here is the syntax for directory and file operations:

FTPRUNCOMMAND DELETEDIRECTORY {pathonftpserver} ON {host};FTPRUNCOMMAND DELETEFILE {pathonftpserver} ON {host};FTPRUNCOMMAND CREATEDIRECTORY {pathonftpserver} ON {host};

Here is an example, that creates a folder on ftp server, changes directory, uploads a local file, finally deletes file anddirectory.

OBJECT:STRING FTPHOST,STRING FTPPASS,STRING FTPUSER,STRING LOCALPATH,STRING FTPSERVERPATH,STRING DIRNAME,TABLE FILESTABLE;

FTPHOST = 'anyftp.com.tr';FTPUSER = 'user';FTPPASS = 'password';DIRNAME = 'myfolder';

LOCALPATH = 'file.xml';

MAKEFTPCONNECTION HOST FTPHOST USERNAME FTPUSER PASSW FTPPASS PROTOCOL FTP;

(continues on next page)

17.6. Creating/Deleting Folders and Files 123

Programming with TROIA, Release 0.5.beta

(continued from previous page)

IF SYS_STATUS == 0 THEN

FTPRUNCOMMAND CREATEDIRECTORY DIRNAME ON FTPHOST;FTPRUNCOMMAND CHANGEDIRECTORY DIRNAME ON FTPHOST;

FTPUPLOAD LOCALPATH TO FTPHOST;FTPRUNCOMMAND DELETEFILE 'file.xml' ON FTPHOST;

FTPRUNCOMMAND DELETEDIRECTORY DIRNAME ON FTPHOST;

ENDIF;

CLOSEFTPCONNECTION FTPHOST;

124 Chapter 17. Working with FTP Servers

CHAPTER 18

Web Services

TROIA Platform supports defining web services/methods which allows 3rd party applications to access business ap-plications/database over TROIA codes. This section aims to introduce TROIA Web Service infrastructure for 3rd partyapplication developers.

18.1 Introduction

TROIA web service infrastructure allows programmers define web services/methods using TROIA language to serve3rd party applications. Simply, a troia web service is defining a class method as web service and web service infras-tructure serves this service using a standard wsdl interface.

Before the details of wsdl and web servie infrastructure, you must know that TROIA platform has two versions of webservices. Both this two web services are supported on all versions after 5.01.01. First version is called “TROIA WebService 1.0” and it is deprecated by second version which is called “TROIA Web Services 2.0”.

Although “TROIA Web Service 2.0” is similar to first version, it has too many extended features such as compression,encryption, message transfer etc. In this section we will discuss only “TROIA Web Service 2.0”, because first versionis only supported for backward compatibility and all new client projects which needs web services must use “TRIOAWeb Service 2.0” version.

18.1.1 WSDL Overview

Web services are defined by a WSDL(stands for “Web Services Description Language”) document in a machinereadible format. This document defines all methods, data structures which required for calling web service. In TROIAweb service infrastructure WSDL document content is not directly depends on web method’s interface, so it hassame interface even defined class methods has different interfaces. Here is the interface which is defined by WSDLdocument:

125

Programming with TROIA, Release 0.5.beta

Method Return Typelogin() LoginResponse To create a session on server side.logout() boolean To close sessioncallService() CaniasResponse To call a registered servicelistServices() String array To list available service list for logged user

18.1.2 Installation & Version Update

To deploy TROIA Web Services firstly you must have web server which supports serving java web solutions. ApacheTomcat is one of the most used web servers to deploy TROIA Web Services. After installing web server, you mustcopy TROIA Web Service folder to root directory of your Tomcat installation. This folder is supplied with TROIAPlatform.

Additionally you must copy canias1.jar which is a jar file containing client application and required classes for webservice installation. This jar file must have same version/build number with application server. After the installationyou must see the WSDL document on the link below:

http://{yourtomcaturl}/CaniasWebService/services/CaniasWebService?WSDL

If you upgrade/update your platform release you must also keep your canias1.jar which is used by tomcat to serveTROIA web services.

18.2 Service Definition & Permissions

To define a web service, firstly you must have a class with a method which will be called as web service. This classcan be defined by using “TROIA IDE”.

WSRT01 - Web Services Definitions WSRT02 - Web Services User Rights

..user rights

18.3 Log-in/Log-out over Web Service

18.3.1 login() Method

login () method creates a connector session on CANIAS Application Server if login credentials is correct.

Client, Language, DBServer, DBName, ApplicationServer, Username are default login parameters. Password param-eter must be MD5 hash of password string.

In addition to these parameters login method gets a boolean Encrypted flag. Encrypted flag enables encrypted connec-tion between client application and CANIAS Web Service.

Client application must be indicate whether compression will be enabled or not at callService() requests during thesession. If client application sends true as compression parameter, server activates automatic compression subsystem.

LCheck parameter is used internally; client application must pass an empty string as LCheck parameter.

VKey parameter is used internally; client application must pass an empty string as VKey parameter.

login() method returns LoginResponse complex type which has members below:

• Success (Boolean) : If login is successful, this field is set to true, otherwise false.

126 Chapter 18. Web Services

Programming with TROIA, Release 0.5.beta

• SessionId (String) : This member returns user’s session id, otherwise. If login fails it is an empty string.

• SecurityKey (String) : Application Server returns a random security key for each successful login. Client appli-cation must pass this security key parameter while calling callService () method, to indicate it’s an authenticatedapplication.

• ContactNum (String) : This member returns users ContactNum which is stored in CONTACTNUM columnof IASUSERS table.

• ErrorMessage (String) : If login fails, this field returns login error message in given language; else this field isan empty string.

• EncryptionKey (String): If client application connects an encrypted connection, application server returns anEncryptionKey which will be used at service interactions. Client application must convert EncryptionKey tobyte array using UTF8 encoding before using this key as encryption key.

18.3.2 logout() Method

logout() gets SessionId parameter as string and removes connector session which has given session id. Method returnstrue if log out operation is successful.

18.4 Listing Available Services

listServices() method of TROIA web service gets SessionId as string parameter and returns all available services asstring array. Web Services which user has not permission to call are not included in returning array.

If returning array does not include name of web service that you want to call, you must check whether your method isregistered as web service and user who is connected as web service client has permission to run registered service.

18.5 Calling Services

18.5.1 callService() method

callService() method is used for running a TROIA Class Method which is registered as a TROIA Web Service. Methodhas six input parameter. Detailed information about these input parameters are below:

• SessionId (String) : Session Id must be stored by web service client and sent at all service calls. Session Iddata is used for accessing correct connector session in application server.

• SecurityKey (String) : SecurityKey which is supplied by a successful login response must be passed to callSer-vice() method. ApplicationServer compares session’s security key and request’s security key to state whethercaller application is an authenticated application or not.

• ServiceId (String) : ServiceId, key value while accessing all service information like service class, method name and web service rights.If given ServiceId is not registered, service call fails and return value shows service call’s failure message.Understanding whether a service call failed is possible using callService() method’s complex return value.For more information please review structure of CaniasResponse complex type.

• Parameters (String) : Client applications can pass parameter to CANIAS Web Services as XML formatted String.callService() method gets parameters to pass TROIA method which is defined as web service. DefaultXML Format is like below:

18.4. Listing Available Services 127

Programming with TROIA, Release 0.5.beta

<PARAMETERS><PARAM>firstparam</PARAM><PARAM>secondparam</PARAM>...

</PARAMETERS>

<PARAM> element can define parameter encoding as plain or base64 like <PARAM encoding=”base64”>to indicate value of parameter is encoded as base64 string. If parameter encoded as base64 string, systemconverts base64 string to UTF-8 string before using parameter value. If param element contains specialchars CDATA block can be used to force parsers ignore. Default value of encoding is plain. Example:

<PARAMETERS><PARAM encoding="base64">cGFyYW0x</PARAM><PARAM>secondparam</PARAM><PARAM><![CDATA[third param contains > char]]></PARAM>...

</PARAMETERS>

Client applications are able to pass table and vectors as parameter to web service. In this case type ofparameter must be indicated using type attribute in <PARAM> element. If parameter is a primitive typesuch as string, integer, long or decimal there is no need to add type attribute. If table or vector parameteris passed to a web service system automatically parses xml and creates a table or vector symbol. (Vectorsare able to contain primitive variables such as string, integer, long, date etc.) Example:

<PARAMETERS><PARAM>firstparam</PARAM><PARAM>1</PARAM><PARAM>1.5</PARAM><PARAM type="TABLE">

<TABLE_VARIABLE_NAME><ROW>

<COL1>row1 col1 value</COL1><COL2>row1 col1 value</COL2>

</ROW><ROW>

<COL1>row2 col1 value</COL1><COL2>row2 col2 value</COL2>

</ROW></TABLE_VARIABLE_NAME>

</PARAM><PARAM type="VECTOR">

<VECTOR_VARIABLE_NAME><ITEM>

<NAME>TROIASYMBOL1</NAME><TYPE>STRING</TYPE><VALUE>value1</VALUE>

</ITEM><ITEM>

<NAME>TROIASYMBOL2</NAME><TYPE>LONG</TYPE><VALUE>3</VALUE>

</ITEM></VECTOR_VARIABLE_NAME>

</PARAM><PARAM>another parameter</PARAM>...

</PARAMETERS>

128 Chapter 18. Web Services

Programming with TROIA, Release 0.5.beta

If communication is an encrypted connection, parameters must be encrypted by client application. Formore information about web service please review “Encryption” section.

Parameters value can be compressed due to requirements of client application. For more information aboutcompression issue please review “Compression” section. If parameters string compressed in an encryptedconnection, client application must perform compression after encryption.

• Compressed (Boolean) : Indicates whether parameters are compressed or not. If parameters are compressedtrue value must be passed, otherwise false value must be passed.

• Permanent (Boolean) : For each service call, application server opens a transaction automatically and executesall TROIA codes in this transaction. After procedure finished transaction is closed. If client application sendstrue as permanency option, application server does not close transaction, and next service codes are executed atsame scope.

• ExtraVariables (String) : CANIAS Web Service is able to return value of TROIA variables in addition to default return value. So if client application sends variable names as ExtraVariables parameter, application server returns value of any variable from any scope. If client application needs value of more than one TROIA variable, variable names must be passed as comma separated string.Returning complex types like table and class instance is not supported.

• RequestId (Integer) : Request Id is simple id number of each service call. ApplicationServer returns responseof a request with same id number, so client applications can find request and response pairs. Due to clientapplication architecture, this number can be useless. If client application does not use a request and response idinformation send 0 (zero) or any other number to callService() method.

18.5.2 Return Value of callService() Method

callService() method returns CaniasResponse which is a complex data type containing response, extra variables andsome extra data about web service execution. All members of CaniasResponse complex type are listed below:

• Response (StringResponse) : This field stores the returning value of TROIA Class method which is registered as WebService.StringResponse complex type has two members. Value is requested string value. Compressed is a flagwhich shows whether value is compressed or not. If Compressed flag is set to false, Value filed storesreturn XML directly. Otherwise to get pure text, Value field must be decompressed. For more informationabout compression issue please review “Compression” section.

If communication is an encrypted connection, StringResponse must be dencrypted by client application.For more information about encryption please review “Encryption” section.

• SYSStatus (Integer) : After execution of TROIA Class method which is registered as web service, ApplicationServer returns latest value of SYSStatus symbol, so client application can use this value due to its requirements.If web service cannot access application server or there is not a web service with given name SYSStatusvalue is set to 1 and StringResponse is set to empty string.

• SYSStatusError (String) : This field stores value SYSStatusError system symbol.

• RequestId (Integer) : Web Service directly returns same value of callService() method’s RequestId parameter.

• ExtraVariables (StringResponse) : ExtraVariables member stores extra variables that are requested by client application.StringResponse complex type has two members. Value is requested string value. Compressed is a flagwhich shows whether value is compressed or not. If Compressed flag is set to false, Value filed storesreturn XML directly. Otherwise to get pure text, Value field must be decompressed. For more informationabout compression issue please review “Compression” section.

Resulting value contains symbol name, symbol type and value as XML format. Format of extra variablexml is below:

<EXTRAVARIABLES><VARIABLE>

<NAME> ... </NAME><TYPE>...</TYPE><VALUE>...</VALUE>

(continues on next page)

18.5. Calling Services 129

Programming with TROIA, Release 0.5.beta

(continued from previous page)

</VARIABLE><VARIABLE>

<NAME> ... </NAME><TYPE>...</TYPE><VALUE>...</VALUE>

</VARIABLE>...

</EXTRAVARIABLES>

• Messages (StringResponse) : All TROIA messages created while TROIA code is running are stored by appli-cation server and returned at Messages field of CaniasResponse.

StringResponse complex type has two members. Value is requested string value. Compressed is aflag which shows whether value is compressed or not. If Compressed flag is set to false, Value filedstores return XML directly. Otherwise to get pure text, Value field must be decompressed. For moreinformation about compression issue please review “Compression” section.

Messages string contains message text, module, message type and message number as XML format.Format of Messages extra variable xml is below:

<TROIAMESSAGES><MESSAGE>

<TEXT>...</TEXT><MODULE> ... </MODULE><TYPE>...</TYPE><NUMBER>...</NUMBER>

</MESSAGE><MESSAGE>

<TEXT>...</TEXT><MODULE> ... </MODULE><TYPE>...</TYPE><NUMBER>...</NUMBER>

</MESSAGE></TROIAMESSAGES>

• Compress (Boolean) : If length of return value of TROIA class method’s is greater than 4000 characters.Application server compresses its value and sets this fields value is true. Otherwise it is set to false.

If data sent from web service is compressed, client application must decompress StringResponsefield’s value. For more information about compression issue please review “Compression” section.

18.6 Encryption

As its default behavior, system does not use encrypted communication. If encrypted communication is needed due toapplications requirements, client applications must send true value as encryption information on login request.

Web Service encryption infrastructure uses AES as encryption standard (if required CipherMode:CBC, Padding-Mode:PKCS7, KeySize:128 and BlockSize:128). Required public key is supplied by application server and sentto client application on LoginResponse.EncryptionKey field. This value must be converted to byte array using UTF-8encoding to get final encryption key for client side encryption and decryption processes. Encryption process convertsstring response to byte array using UTF-8 encoding and encrypts returning byte array. After encryption process re-sulting byte array is converted to Base64 String to enabling data transfer over web service. As a result of this processin order to get pure string response of web service call, client applications must convert Base64 String to byte array,decrypt this byte array and convert this byte array to string using UTF-8 encoding.

130 Chapter 18. Web Services

Programming with TROIA, Release 0.5.beta

Additionally, for encrypted connections, client applications must send Parameters string as an encrypted string. Theway of encryption must be same as server side encryption process and resulting value must be Base64 String.

18.7 Compression

If compression enabled and length of service’s string response is greater than minimum compress size(4000 char-acters), application server converts string data to byte array with UTF-8 encoding, compress byte array and createsBase64 String. If server makes compression over pure response string, Compress field of CaniasResponse is set totrue. Thus, if Compress flag is set to true, client application must convert Base64 String to byte array, decompress andconvert decompressed byte array to string with UTF-8 encoding. Application Server’s web service infrastructure usesZip Stream (DEFAULT_STRATEGY) while compressing byte arrays.

System does not apply compression to encrypted data.

18.7. Compression 131

Programming with TROIA, Release 0.5.beta

132 Chapter 18. Web Services

CHAPTER 19

Parsing XML & JSON

Both XML and JSON are common formats to transfer data between systems in a human readable format. This sectionsaims to introduce all options to handle/parse xml & json formats.

19.1 Conversion Between XML & JSON

19.1.1 Convert XML to JSON

CONVERTXMLJSON( {input}, 'JSON');

<menu id="file" value="File"><popup>

<menuitem value="New" onclick="CreateNewDoc()" /><menuitem value="Open" onclick="OpenDoc()" /><menuitem value="Close" onclick="CloseDoc()" />

</popup></menu>

OBJECT:STRING STRJSON,STRING STRINGVAR3;

STRJSON = CONVERTXMLJSON(STRINGVAR3, 'JSON');STRINGVAR3 = STRJSON;

{"@id": "file","@value": "File","popup": [

{"@value": "New",

(continues on next page)

133

Programming with TROIA, Release 0.5.beta

(continued from previous page)

"@onclick": "CreateNewDoc()"},

{"@value": "Open","@onclick": "OpenDoc()"

},{"@value": "Close","@onclick": "CloseDoc()"

}]

}

19.1.2 Convert JSON to XML

CONVERTXMLJSON( {input}, 'XML'[, 'NOTYPEHINT' | 'JSONPREFIX'] );

{"menu": {"id": "file","value": "File","popup": {

"menuitem": [{"value": "New", "onclick": "CreateNewDoc()"},{"value": "Open", "onclick": "OpenDoc()"},{"value": "Close", "onclick": "CloseDoc()"}

]}

}}

OBJECT:STRING STRXML,STRING STRINGVAR3;

STRXML = CONVERTXMLJSON(STRINGVAR3,'XML','NOTYPEHINT');STRINGVAR3 = STRXML;

<?xml version="1.0" encoding="UTF-8"?><o>

<menu><id>file</id><popup>

<menuitem><e>

<onclick>CreateNewDoc()</onclick><value>New</value>

</e><e>

<onclick>OpenDoc()</onclick><value>Open</value>

</e><e>

<onclick>CloseDoc()</onclick><value>Close</value>

(continues on next page)

134 Chapter 19. Parsing XML & JSON

Programming with TROIA, Release 0.5.beta

(continued from previous page)

</e></menuitem>

</popup><value>File</value>

</menu></o>

19.2 Reading XML Structure

READXMLSTRUCTURE {xmlcontent} TO {targettable};

IDPIDNAMEPATHVALUELEVELISATTRIBUTE

<?xml version="1.0" ?><CustomerList>

<ListInfo><CreatedAt>10.10.2015</CreatedAt><CreatedBy>btan</CreatedBy>

</ListInfo>

<Customer Name="XYZ Financial Solutions"><City>Tokyo</City><ProductGroup>Payment Systems</ProductGroup>

</Customer>

<Customer Name="ABC Technology"><City>Madrid</City><ProductGroup>Mobile Applications</ProductGroup>

</Customer>

</CustomerList>

READXMLSTRUCTURE STRINGVAR3 TO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

19.3 Some Useful XML Functions

19.3.1 Formatting XML Documents

OBJECT:STRING STRXML,

(continues on next page)

19.2. Reading XML Structure 135

Programming with TROIA, Release 0.5.beta

(continued from previous page)

STRING STRINGVAR3;

STRXML = '<ROOT><TEAM><NAME>Team 1</NAME><SCORE>0</SCORE>';STRXML = STRXML + '</TEAM><TEAM><NAME>Team 2</NAME>';STRXML = STRXML + '<SCORE>1</SCORE></TEAM></ROOT>';

STRINGVAR3 = WRAPXML(STRXML);

<?xml version="1.0" encoding="UTF-8"?><ROOT><TEAM>

<NAME>Team 1</NAME><SCORE>0</SCORE>

</TEAM><TEAM>

<NAME>Team 2</NAME><SCORE>1</SCORE>

</TEAM></ROOT>

19.3.2 CLEARDOCUMENT() Function

OBJECT:STRING STRXML,STRING STRINGVAR3;

STRXML = '<ROOT><TEAM><NAME>Team 1</NAME><SCORE>0</SCORE>';STRXML = STRXML + '</TEAM><TEAM><NAME>Team 2</NAME>';STRXML = STRXML + '<SCORE>1</SCORE></TEAM></ROOT>';

STRINGVAR3 = CLEARDOCUMENT(STRXML,'TEAM');

19.4 Validating XML Documents

VALIDATEXML {validatorpath} {xmlpath} WITH {valtype} [TO {details}];VALIDATEXML TEXT {validatortext} {xmlastext} WITH {valtype} [TO {details}];

<?xml version="1.0" encoding="UTF-8"?><schema xmlns="http://purl.oclc.org/dsdl/schematron">

<ns uri="http://www.topologi.com/example" prefix="ex"/>

<pattern name="Check structure"><rule context="ex:Person">

<assert test="@Title">Person must have title

</assert><assert test="count(ex:Name)=1 and count(ex:Gender)=1">

Person should have Name / Gender</assert><assert test="ex:*[1] = ex:Name">

Name must appear before element Gender

(continues on next page)

136 Chapter 19. Parsing XML & JSON

Programming with TROIA, Release 0.5.beta

(continued from previous page)

</assert></rule>

</pattern><pattern name="Check co-occurrence constraints">

<rule context="ex:Person"><assert test="(@Title = 'Mr' and ex:Gender = 'Male')

or @Title != 'Mr'">If the Title is "Mr", gender must be "Male"

</assert></rule>

</pattern>

</schema>

<ex:Person Title="Mr" xmlns:ex="http://www.topologi.com/example"><ex:Name>Eddie</ex:Name><ex:Gender>Male</ex:Gender>

</ex:Person>

OBJECT:STRING STRXMLPATH,STRING STRSCHPATHSTRING STRINGVAR3;

STRXMLPATH = 'xml.xml';STRSCHPATH = 'validator.sch';

COPYFILE '*C:\TMP\xml.xml' INTO STRXMLPATH;COPYFILE '*C:\TMP\validator.sch' INTO STRSCHPATH;

VALIDATEXML STRSCHPATH STRXMLPATH WITH SCHEMATRON TO STRINGVAR3;STRINGVAR1 = SYS_STATUS + ' ' + SYS_STATUSERROR;

19.5 Parsing XML Documents

19.5.1 Defining XML Maps

CREATEXMLMAP {mapname};

CLEAR XMLMAP {mapname};

MAP ELEMENT {elementname} AS [XMLTABLE | XMLROOTTABLE] {tablename} IN {mapname};

MAP ATTRIBUTE {attributename} OF {elementname}AS XMLCOLUMN {columnname} IN {mapname};

MAP CHILD {elementname} OF {elementname} AS XMLCOLUMN {columnname} IN {mapname};

MAP PCDATA OF {elementname} AS XMLCOLUMN {columnname} IN {mapname};

MAP RELATION {elementname} TO {elementname} LINK {primarykey}WITH {foreignkey} GENERATE YES | NO IN {mapname};

19.5. Parsing XML Documents 137

Programming with TROIA, Release 0.5.beta

19.5.2 Parsing XML with XML Maps

PARSEXML {docpath} USING {mapname};

CONVERTXMLTABLE {xmltable} INTO {table} FROM {mapname};

19.5.3 Parsing without XML Map

PARSEXML TEXT {xmlastext} INTO {tablename};PARSEXML {filepath} INTO {tablename};

19.6 XML Parsing Examples

19.6.1 Example 1: Using Auto Parser

OBJECT:STRING STRINGVAR3;

STRINGVAR3 = '<?xml version="1.0" ?><CustomerList>

<Customer><Name>IAS Software</Name><Country>Turkey</Country>

</Customer><Customer>

<Name>XYZ Technology</Name><Country>Turkey</Country>

</Customer><Customer>

<Name>ABC Design</Name><Country>Turkey</Country>

</Customer></CustomerList>';

OBJECT:TABLE CUSTOMERS;

PARSEXML TEXT STRINGVAR3 INTO CUSTOMERS;

COPY TABLE CUSTOMERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

19.6.2 Example 2: Multiple Auto Parsers

OBJECT:STRING STRINGVAR3;

STRINGVAR3 = '<PCARD_CARD_GET_DETAILResponse xmlns="http://tempuri.org/"><PCARD_CARD_GET_DETAILResult>

(continues on next page)

138 Chapter 19. Parsing XML & JSON

Programming with TROIA, Release 0.5.beta

(continued from previous page)

<ConditionNo>100</ConditionNo><ConditionMessage>Invalid username or password</ConditionMessage><Success>false</Success><cardInfo /><cardCredit>

<lmt xsi:nil="true" /><dfl_amt xsi:nil="true" /><bln xsi:nil="true" /><dsc xsi:nil="true" />

</cardCredit></PCARD_CARD_GET_DETAILResult>

</PCARD_CARD_GET_DETAILResponse>';

PARSEXML TEXT STRINGVAR3 INTO TMPTABLE;PARSEXML TEXT TMPTABLE_XMLData INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

19.6.3 Example 3: Using PCData

<?xml version="1.0" ?><CustomerList>

<Customer>IAS Software</Customer><Customer>XYZ Technology</Customer><Customer>ABC Design</Customer>

</CustomerList>

OBJECT:TABLE CUSTOMERS;

CLEAR XMLMAP DEMOMAP;CREATEXMLMAP DEMOMAP;

MAP ELEMENT CustomerList AS XMLROOTTABLE CustomerList IN DEMOMAP;MAP ELEMENT Customer AS XMLTABLE Customer IN DEMOMAP;MAP PCDATA OF Customer AS XMLCOLUMN Customer IN DEMOMAP;MAP RELATION Customer TO CustomerList LINK 'asdf'

WITH DUMMY GENERATE NO IN DEMOMAP;

COPYFILE '*C:\TMP\XML\ex3.xml' INTO '.\XMLParsing\ex3.xml';PARSEXML '.\XMLParsing\ex3.xml' USING DEMOMAP;

CONVERTXMLTABLE Customer INTO TABLE CUSTOMERS FROM DEMOMAP;

COPY TABLE CUSTOMERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

19.6.4 Example 4: Reading Childs

<?xml version="1.0" ?><CustomerList>

<Sector>Technology</Sector><Customer>

(continues on next page)

19.6. XML Parsing Examples 139

Programming with TROIA, Release 0.5.beta

(continued from previous page)

<CustName>XYZ Industries</CustName><City>Tokyo</City>

</Customer><Customer>

<CustName>ABC Technology</CustName><City>Madrid</City>

</Customer><Customer>

<CustName>IAS Software</CustName><City>Istanbul</City>

</Customer></CustomerList>

OBJECT:TABLE CUSTOMERS,INTEGER ROWCOUNT;

CLEAR XMLMAP DEMOMAP;CREATEXMLMAP DEMOMAP;MAP ELEMENT CustomerList AS XMLROOTTABLE CustomerList IN DEMOMAP;MAP CHILD Sector OF CustomerList AS XMLCOLUMN Sector IN DEMOMAP;MAP ELEMENT Customer AS XMLTABLE CUSTOMER IN DEMOMAP;MAP CHILD CustName OF Customer AS XMLCOLUMN CustName IN DEMOMAP;MAP CHILD City OF Customer AS XMLCOLUMN City IN DEMOMAP;MAP RELATION Customer TO CustomerList LINK Sector

WITH Sector GENERATE YES IN DEMOMAP;

COPYFILE '*C:\TMP\XML\ex4.xml' INTO '.\XMLParsing\ex4.xml';PARSEXML '.\XMLParsing\ex4.xml' USING DEMOMAP;CONVERTXMLTABLE CUSTOMER INTO TABLE CUSTOMERS FROM DEMOMAP;

ROWCOUNT = CUSTOMERS_ROWCOUNT;COPY TABLE CUSTOMERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

19.6.5 Example 5: Childs with Extra Relation

<PCARD_CARD_GET_DETAILResponse xmlns="http://tempuri.org/"><PCARD_CARD_GET_DETAILResult>

<ConditionNo>100</ConditionNo><ConditionMessage>Invalid username or password</ConditionMessage><Success>false</Success><cardInfo /><cardCredit><lmt/><dfl_amt/><bln/><dsc/>

</cardCredit></PCARD_CARD_GET_DETAILResult>

</PCARD_CARD_GET_DETAILResponse>

OBJECT:TABLE DETAILRESULT;

(continues on next page)

140 Chapter 19. Parsing XML & JSON

Programming with TROIA, Release 0.5.beta

(continued from previous page)

CLEAR XMLMAP DEMOMAP;CREATEXMLMAP DEMOMAP;

MAP ELEMENT PCARD_CARD_GET_DETAILResponseAS XMLROOTTABLE PCARD_CARD_GET_DETAILResponse IN DEMOMAP;

MAP ELEMENT PCARD_CARD_GET_DETAILResultAS XMLTABLE PCARD_CARD_GET_DETAILResult IN DEMOMAP;

MAP CHILD ConditionNo OF PCARD_CARD_GET_DETAILResultAS XMLCOLUMN ConditionNo IN DEMOMAP;

MAP CHILD ConditionMessage OF PCARD_CARD_GET_DETAILResultAS XMLCOLUMN ConditionMesaj IN DEMOMAP;

MAP CHILD Success OF PCARD_CARD_GET_DETAILResultAS XMLCOLUMN Success IN DEMOMAP;

MAP CHILD ConditionNo OF PCARD_CARD_GET_DETAILResultAS XMLCOLUMN ConditionNo IN DEMOMAP;

MAP RELATION PCARD_CARD_GET_DETAILResult TO PCARD_CARD_GET_DETAILResponse LINKDUMMY WITH DUMMY GENERATE NO IN DEMOMAP;

COPYFILE '*C:\TMP\XML\ex5.xml' INTO '.\XMLParsing\ex5.xml';PARSEXML '.\XMLParsing\ex5.xml' USING DEMOMAP;CONVERTXMLTABLE PCARD_CARD_GET_DETAILResult

INTO TABLE DETAILRESULT FROM DEMOMAP;

COPY TABLE DETAILRESULT INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

19.6.6 Example 6: Reading Attributes

<?xml version="1.0" ?><CustomerList Sector="Technology">

<Customer><CustName>XYZ Industries</CustName><City>Tokyo</City>

</Customer><Customer>

<CustName>ABC Technology</CustName><City>Madrid</City>

</Customer><Customer>

<CustName>IAS Software</CustName><City>Istanbul</City>

</Customer></CustomerList>

OBJECT:TABLE CUSTOMERS,INTEGER ROWCOUNT;

CLEAR XMLMAP DEMOMAP;CREATEXMLMAP DEMOMAP;

MAP ELEMENT CustomerList AS XMLROOTTABLE CustomerList IN DEMOMAP;

(continues on next page)

19.6. XML Parsing Examples 141

Programming with TROIA, Release 0.5.beta

(continued from previous page)

/* map attribute for root element*/MAP ATTRIBUTE Sector OF CustomerList AS XMLCOLUMN Sector IN DEMOMAP;

MAP ELEMENT Customer AS XMLTABLE CUSTOMER IN DEMOMAP;MAP CHILD CustName OF Customer AS XMLCOLUMN CustName IN DEMOMAP;MAP CHILD City OF Customer AS XMLCOLUMN City IN DEMOMAP;

MAP RELATION Customer TO CustomerListLINK Sector WITH Sector GENERATE YES IN DEMOMAP;

COPYFILE '*C:\TMP\XML\ex6.xml' INTO '.\XMLParsing\ex6.xml';PARSEXML '.\XMLParsing\ex6.xml' USING DEMOMAP;

CONVERTXMLTABLE CUSTOMER INTO TABLE CUSTOMERS FROM DEMOMAP;

ROWCOUNT = CUSTOMERS_ROWCOUNT;COPY TABLE CUSTOMERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

19.6.7 Example 7: Attributes On Childs

<?xml version="1.0" ?><CustomerList Sector="Technology">

<Customer CustomerId="C1"><CustName>XYZ Industries</CustName><City>Tokyo</City>

</Customer><Customer CustomerId="C2">

<CustName>ABC Technology</CustName><City>Madrid</City>

</Customer><Customer CustomerId="C3">

<CustName>IAS Software</CustName><City>Istanbul</City>

</Customer></CustomerList>

OBJECT:TABLE CUSTOMERS,INTEGER ROWCOUNT;

CLEAR XMLMAP DEMOMAP;CREATEXMLMAP DEMOMAP;

MAP ELEMENT CustomerList AS XMLROOTTABLE CustomerList IN DEMOMAP;MAP ATTRIBUTE Sector OF CustomerList AS XMLCOLUMN Sector IN DEMOMAP;

MAP ELEMENT Customer AS XMLTABLE CUSTOMER IN DEMOMAP;/* attribute for child */MAP ATTRIBUTE CustomerId OF Customer AS XMLCOLUMN CustomerId IN DEMOMAP;MAP CHILD CustName OF Customer AS XMLCOLUMN CustName IN DEMOMAP;MAP CHILD City OF Customer AS XMLCOLUMN City IN DEMOMAP;

MAP RELATION Customer TO CustomerList LINK Sector

(continues on next page)

142 Chapter 19. Parsing XML & JSON

Programming with TROIA, Release 0.5.beta

(continued from previous page)

WITH Sector GENERATE YES IN DEMOMAP;

COPYFILE '*C:\TMP\XML\ex7.xml' INTO '.\XMLParsing\ex7.xml';PARSEXML '.\XMLParsing\ex7.xml' USING DEMOMAP;CONVERTXMLTABLE CUSTOMER INTO TABLE CUSTOMERS FROM DEMOMAP;

ROWCOUNT = CUSTOMERS_ROWCOUNT;

COPY TABLE CUSTOMERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

19.6.8 Example 8: Multiple Tables & Relations Childs-Attributes

<?xml version="1.0" ?><CustomerList Sector="Technology">

<Customer CustomerId="C1"><CustName>XYZ Industries</CustName><City>Tokyo</City><Order OrderId="O1">

<Year>2013</Year><GrandTotal>100.013</GrandTotal>

</Order></Customer>

<Customer CustomerId="C2"><CustName>ABC Technology</CustName><City>Madrid</City>

<Order OrderId="O2"><Year>2011</Year><GrandTotal>100.011</GrandTotal>

</Order><Order OrderId="O3">

<Year>2012</Year><GrandTotal>100.012</GrandTotal>

</Order>

</Customer>

<Customer CustomerId="C3"><CustName>IAS Software</CustName><City>Istanbul</City>

<Order OrderId="O5"><Year>2010</Year><GrandTotal>100.010</GrandTotal>

</Order><Order OrderId="O6">

<Year>2014</Year><GrandTotal>100.014</GrandTotal>

</Order>

</Customer></CustomerList>

19.6. XML Parsing Examples 143

Programming with TROIA, Release 0.5.beta

OBJECT:TABLE CUSTOMERS,TABLE ORDERS,INTEGER ROWCOUNT;

CLEAR XMLMAP DEMOMAP;CREATEXMLMAP DEMOMAP;

MAP ELEMENT CustomerList AS XMLROOTTABLE CustomerList IN DEMOMAP;MAP ATTRIBUTE Sector OF CustomerList AS XMLCOLUMN Sector IN DEMOMAP;

MAP ELEMENT Customer AS XMLTABLE CUSTOMER IN DEMOMAP;MAP ATTRIBUTE CustomerId OF Customer AS XMLCOLUMN CustomerId IN DEMOMAP;MAP CHILD CustName OF Customer AS XMLCOLUMN CustName IN DEMOMAP;MAP CHILD City OF Customer AS XMLCOLUMN City IN DEMOMAP;MAP RELATION Customer TO CustomerList LINK Sector

WITH Sector GENERATE YES IN DEMOMAP;

MAP ELEMENT Order AS XMLTABLE ORDER IN DEMOMAP;MAP ATTRIBUTE OrderId OF Order AS XMLCOLUMN OrderId IN DEMOMAP;MAP CHILD Year OF Order AS XMLCOLUMN Year IN DEMOMAP;MAP CHILD GrandTotal OF Order AS XMLCOLUMN GrandTotal IN DEMOMAP;MAP RELATION Order TO Customer LINK CustomerId

WITH CustomerId GENERATE NO IN DEMOMAP;

COPYFILE '*C:\TMP\XML\ex8.xml' INTO '.\XMLParsing\ex8.xml';PARSEXML '.\XMLParsing\ex8.xml' USING DEMOMAP;CONVERTXMLTABLE CUSTOMER INTO TABLE CUSTOMERS FROM DEMOMAP;CONVERTXMLTABLE ORDER INTO TABLE ORDERS FROM DEMOMAP;

COPY TABLE CUSTOMERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;RETURN;COPY TABLE ORDERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

19.6.9 Example 9: Multiple Relations/Extra Orders Column Without OrdersId

<?xml version="1.0" ?><CustomerList Sector="Technology">

<Customer CustomerId="C1"><CustName>XYZ Industries</CustName><City>Tokyo</City><Orders>

<Order OrderId="O1"><Year>2013</Year><GrandTotal>100.013</GrandTotal>

</Order></Orders>

</Customer>

<Customer CustomerId="C2"><CustName>ABC Technology</CustName><City>Madrid</City>

(continues on next page)

144 Chapter 19. Parsing XML & JSON

Programming with TROIA, Release 0.5.beta

(continued from previous page)

<Orders><Order OrderId="O2">

<Year>2011</Year><GrandTotal>100.011</GrandTotal>

</Order><Order OrderId="O3">

<Year>2012</Year><GrandTotal>100.012</GrandTotal>

</Order></Orders>

</Customer>

<Customer CustomerId="C3"><CustName>IAS Software</CustName><City>Istanbul</City><Orders>

<Order OrderId="O4"><Year>2010</Year><GrandTotal>100.010</GrandTotal>

</Order><Order OrderId="O5">

<Year>2014</Year><GrandTotal>100.014</GrandTotal>

</Order><Order OrderId="O6">

<Year>2015</Year><GrandTotal>100.015</GrandTotal>

</Order></Orders>

</Customer></CustomerList>

OBJECT:TABLE CUSTOMERS,TABLE ALLORDERS,TABLE CUSTOMERORDERS;

CLEAR XMLMAP DEMOMAP;CREATEXMLMAP DEMOMAP;

MAP ELEMENT CustomerList AS XMLROOTTABLE CustomerList IN DEMOMAP;MAP ATTRIBUTE Sector OF CustomerList AS XMLCOLUMN Sector IN DEMOMAP;

MAP ELEMENT Customer AS XMLTABLE CUSTOMER IN DEMOMAP;MAP ATTRIBUTE CustomerId OF Customer AS XMLCOLUMN CustomerId IN DEMOMAP;MAP CHILD CustName OF Customer AS XMLCOLUMN CustName IN DEMOMAP;MAP CHILD City OF Customer AS XMLCOLUMN City IN DEMOMAP;

MAP RELATION Customer TO CustomerList LINK SectorWITH Sector GENERATE YES IN DEMOMAP;

MAP ELEMENT Orders AS XMLTABLE CUSTOMERORDER IN DEMOMAP;MAP RELATION Orders TO Customer LINK CustomerId

WITH CustomerId GENERATE YES IN DEMOMAP;

MAP ELEMENT Order AS XMLTABLE ORDER IN DEMOMAP;

(continues on next page)

19.6. XML Parsing Examples 145

Programming with TROIA, Release 0.5.beta

(continued from previous page)

MAP ATTRIBUTE OrderId OF Order AS XMLCOLUMN OrderId IN DEMOMAP;MAP CHILD Year OF Order AS XMLCOLUMN Year IN DEMOMAP;MAP CHILD GrandTotal OF Order AS XMLCOLUMN GrandTotal IN DEMOMAP;MAP RELATION Order TO Orders LINK CustomerFK

WITH CustomerFK GENERATE YES IN DEMOMAP;

COPYFILE '*C:\TMP\XML\ex9.xml' INTO '.\XMLParsing\ex9.xml';PARSEXML '.\XMLParsing\ex9.xml' USING DEMOMAP;CONVERTXMLTABLE CUSTOMER INTO TABLE CUSTOMERS FROM DEMOMAP;CONVERTXMLTABLE CUSTOMERORDER INTO TABLE CUSTOMERORDERS FROM DEMOMAP;CONVERTXMLTABLE ORDER INTO TABLE ALLORDERS FROM DEMOMAP;

COPY TABLE CUSTOMERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

COPY TABLE ALLORDERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

COPY TABLE CUSTOMERORDERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

LOOP AT ALLORDERSBEGIN

LOCATERECORD BINARYSEARCH COLUMNS CustomerFK VALUESALLORDERS_CustomerFK ON CUSTOMERORDERS;

STRINGVAR2 = STRINGVAR2 + ' ' + CUSTOMERORDERS_CustomerId;ALLORDERS_CustomerFK = CUSTOMERORDERS_CustomerId;

ENDLOOP;

COPY TABLE ALLORDERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

COPY TABLE CUSTOMERORDERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

19.6.10 Example 10: Relation with Non-Generated Column

<?xml version="1.0" encoding="UTF-8"?><string xmlns="http://tempuri.org/">

<Orders><Order id="ORDER1"><Order_org>ORDERORG1</Order_org><Orderline id="ORDERLINE1">

<OrderLine_org>ORDERORG1</OrderLine_org></Orderline><Orderline id="ORDERLINE2">

<OrderLine_org>ORDERORG1</OrderLine_org></Orderline>

</Order></Orders>

</string>

OBJECT:

(continues on next page)

146 Chapter 19. Parsing XML & JSON

Programming with TROIA, Release 0.5.beta

(continued from previous page)

TABLE ORDERLINES,TABLE ORDERS;

CLEAR XMLMAP DEMOMAP;CREATEXMLMAP DEMOMAP;

MAP ELEMENT string AS XMLROOTTABLE string IN DEMOMAP;MAP ATTRIBUTE xmlns OF string AS XMLCOLUMN xmlns IN DEMOMAP;

MAP ELEMENT Orders AS XMLTABLE ALLORDERS IN DEMOMAP;MAP RELATION Orders TO string LINK xmlns WITH xmlns GENERATE NO IN DEMOMAP;

MAP ELEMENT Order AS XMLTABLE CUSTOMERORDER IN DEMOMAP;MAP ATTRIBUTE id OF Order AS XMLCOLUMN orderid IN DEMOMAP;MAP CHILD Order_org OF Order AS XMLCOLUMN Order_org IN DEMOMAP;MAP RELATION Order TO Orders LINK CustomerId WITH DUMMY GENERATE NO IN DEMOMAP;

MAP ELEMENT Orderline AS XMLTABLE ORDERLINE IN DEMOMAP;MAP ATTRIBUTE id OF Orderline AS XMLCOLUMN orderlineid IN DEMOMAP;MAP CHILD OrderLine_org OF Orderline AS XMLCOLUMN OrderLine_org IN DEMOMAP;MAP RELATION Orderline TO Order LINK orderid

WITH orderid GENERATE YES IN DEMOMAP;

COPYFILE '*C:\TMP\XML\ex10.xml' INTO '.\XMLParsing\ex10.xml';PARSEXML '.\XMLParsing\ex10.xml' USING DEMOMAP;

CONVERTXMLTABLE CUSTOMERORDER INTO TABLE ORDERS FROM DEMOMAP;CONVERTXMLTABLE ORDERLINE INTO TABLE ORDERLINES FROM DEMOMAP;CONVERTXMLTABLE ALLORDERS INTO TABLE ALLORDER FROM DEMOMAP;

COPY TABLE ORDERLINES INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

COPY TABLE ORDERS INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

19.7 Exercise 1: Parse using READXMLSTRUCTURE

Calculate sum of GrandTotal values of all orders listed in xml below, using READXMLSTRUCTURE command.

<?xml version="1.0" ?><CustomerList Sector="Technology">

<Customer CustomerId="C1"><CustName>XYZ Industries</CustName><City>Tokyo</City><Order OrderId="O1">

<Year>2013</Year><GrandTotal>100.013</GrandTotal>

</Order></Customer>

<Customer CustomerId="C2"><CustName>ABC Technology</CustName>

(continues on next page)

19.7. Exercise 1: Parse using READXMLSTRUCTURE 147

Programming with TROIA, Release 0.5.beta

(continued from previous page)

<City>Madrid</City>

<Order OrderId="O2"><Year>2011</Year><GrandTotal>100.011</GrandTotal>

</Order><Order OrderId="O3">

<Year>2012</Year><GrandTotal>100.012</GrandTotal>

</Order>

</Customer>

<Customer CustomerId="C3"><CustName>IAS Software</CustName><City>Istanbul</City>

<Order OrderId="O5"><Year>2010</Year><GrandTotal>100.010</GrandTotal>

</Order><Order OrderId="O6">

<Year>2014</Year><GrandTotal>100.014</GrandTotal>

</Order></Customer>

</CustomerList>

19.8 Exercise 2: Parsing Simple XML Documents

Calculate grand total value (sum of Price*Quantity for each product) for the products listed in XML document below:

<ProductList><Product>

<Name>Product 1</Name><Price>6.30</Price><Quantity>5</Quantity>

</Product><Product>

<Name>Product 2</Name><Price>2.50</Price><Quantity>3</Quantity>

</Product><Product>

<Name>Product 3</Name><Price>1.20</Price><Quantity>2</Quantity>

</Product></ProductList>

Here is the solution:

OBJECT:TABLE PRODUCTLIST,

(continues on next page)

148 Chapter 19. Parsing XML & JSON

Programming with TROIA, Release 0.5.beta

(continued from previous page)

TABLE PRODUCT,INTEGER ROWCOUNT;

CLEAR XMLMAP DEMOMAP;CREATEXMLMAP DEMOMAP;

MAP ELEMENT ProductList AS XMLROOTTABLE ProductList IN DEMOMAP;

MAP ELEMENT Product AS XMLTABLE Product IN DEMOMAP;

MAP CHILD Name OF Product AS XMLCOLUMN Name IN DEMOMAP;MAP CHILD Price OF Product AS XMLCOLUMN Price IN DEMOMAP;MAP CHILD Quantity OF Product AS XMLCOLUMN Quantity IN DEMOMAP;

MAP RELATION Product TO ProductList LINK DUMMY WITH DUMMY GENERATE NO IN DEMOMAP;

COPYFILE '*C:\TMP\XML\ex12.xml' INTO '.\XMLParsing\ex12.xml';PARSEXML '.\XMLParsing\ex12.xml' USING DEMOMAP;CONVERTXMLTABLE Product INTO TABLE PRODUCT FROM DEMOMAP;

REMOVE COLUMN DUMMY PERMANENT FROM PRODUCT;APPEND COLUMN GRANDTOTAL, DECIMAL, 10 TO PRODUCT;

COPY TABLE PRODUCT INTO TMPTABLE;

LOOP AT TMPTABLEBEGIN

DECIMALVAR1 = TMPTABLE_Price;DECIMALVAR2 = TMPTABLE_Quantity;TMPTABLE_GRANDTOTAL = DECIMALVAR1 * DECIMALVAR2;

ENDLOOP;

SET TMPTABLE TO TABLE TMPTABLE;

19.9 Exercise 3: Parsing Complex XML Documents

19.10 Exercise 4: Validation

19.9. Exercise 3: Parsing Complex XML Documents 149

Programming with TROIA, Release 0.5.beta

150 Chapter 19. Parsing XML & JSON

CHAPTER 20

HTTP Operations & Calling Web Services

HTTP (Hypertext Transfer Protocol) is a widely used application protocol for distributed, collaborative informationsystems. Also web services is another widely used solution to collaborate heterogeneous systems over the web. Thissection aims to introduce HTTP operations and calling web services in TROIA

20.1 Sending data over HTTP Post Method

SENDHTTPPOST {poststr} TO {url} [CODEPAGE {encoding}] [CONTENTTYPE {contenttype}][COOKIE {cookie}] [REFERER {referer}][HEADERS {headers}] [REQUESTMETHOD {requestmethod}];

poststring, url, encoding, contenttype, cookie,headers,requestmethod

20.1.1 Reading HTTP Response

SYS_SENDHTTPPOSTRESPONSE

SYS_HTTPPOSTCOOKIES

OBJECT:STRING STRINGVAR3,STRING STRINGVAR2,STRING STRURL,STRING FILEPATH;

FILEPATH = '*C:\TMP\response.html';STRURL = 'http://troia.readthedocs.org/en/latest/search.html';

SENDHTTPPOST '' TO STRURL;STRINGVAR2 = SYS_HTTPPOSTCOOKIES;STRINGVAR3 = SYS_HTTPPOSTRESPONSE;

(continues on next page)

151

Programming with TROIA, Release 0.5.beta

(continued from previous page)

OPEN FILE FILEPATH FORNEW;PUT STRINGVAR3, CODEPAGE 'UTF-8';CLOSE FILE;

OBJECT:STRING STRINGVAR3,STRING STRINGVAR2,STRING STRURL,STRING FILEPATH,STRING POSTPARAM;

STRURL = 'http://192.168.0.2:8080/FileUploader/index.jsp';SENDHTTPPOST '' TO STRURL;

STRINGVAR2 = SYS_HTTPPOSTCOOKIES;STRINGVAR3 = SYS_HTTPPOSTRESPONSE;

POSTPARAM = 'username=btan&password=xxxx';

STRURL = 'http://192.168.0.2:8080/FileUploader/login';SENDHTTPPOST POSTPARAM TO STRURL COOKIE STRINGVAR2;

STRINGVAR3 = SYS_HTTPPOSTRESPONSE;

FILEPATH = '*C:\TMP\response.html';OPEN FILE FILEPATH FORNEW;PUT STRINGVAR3, CODEPAGE 'UTF-8';CLOSE FILE;

20.2 Calling Web Services

CALLWEBSERVICE {wsdlurl} , {operation} TO {sym} WITH {params};

OBJECT:STRING STRWSDL,STRING RESULT,TABLE TMPTABLE,STRING STRINGVAR3;

STRWSDL = 'http://footballpool.dataaccess.eu/data/info.wso?wsdl';CALLWEBSERVICE STRWSDL, 'TopGoalScorers' TO RESULT WITH 25;

INTEGERVAR1 = STRPOS(RESULT, '<m:TopGoalScorersResult>')-1;INTEGERVAR2 = STRPOS(RESULT, '</m:TopGoalScorersResult>') - INTEGERVAR1 -1;RESULT = STRSTR(RESULT,INTEGERVAR1,INTEGERVAR2) + '</m:TopGoalScorersResult>';RESULT = REPLACE(RESULT,'m:','');STRINGVAR3 = RESULT;

PARSEXML TEXT RESULT INTO TMPTABLE;REMOVE COLUMN tTopGoalScorersCountry PERMANENT FROM TMPTABLE;REMOVE COLUMN tTopGoalScorersFlag PERMANENT FROM TMPTABLE;REMOVE COLUMN tTopGoalScorersFlagLarge PERMANENT FROM TMPTABLE;

(continues on next page)

152 Chapter 20. HTTP Operations & Calling Web Services

Programming with TROIA, Release 0.5.beta

(continued from previous page)

SET TMPTABLE TO TABLE TMPTABLE;

OBJECT:STRING STRWSDL,STRING RESULT,TABLE TMPTABLE,STRING STRINGVAR3;

STRWSDL = 'http://www.webservicex.net/globalweather.asmx?WSDL';CALLWEBSERVICE STRWSDL, 'GetCitiesByCountry' TO RESULT WITH 'Germany';STRINGVAR3 = RESULT;

PARSEXML TEXT RESULT INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

OBJECT:STRING STRWSDL,STRING RESULT,TABLE TMPTABLE,STRING STRINGVAR3;

STRWSDL = 'http://www.w3schools.com/xml/tempconvert.asmx?WSDL';CALLWEBSERVICE STRWSDL, 'CelsiusToFahrenheit' TO RESULT WITH '10';STRINGVAR3 = RESULT;

OBJECT:STRING STRINGVAR3,STRING STRURL,STRING FILEPATH,STRING STRCTYPE,TABLE TMPTABLE;

FILEPATH = '*C:\TMP\response.html';STRURL = 'http://www.w3schools.com/xml/tempconvert.asmx/CelsiusToFahrenheit';STRCTYPE = 'application/x-www-form-urlencoded';

SENDHTTPPOST 'celsius=10' TO STRURL CONTENTTYPE STRCTYPE;STRINGVAR3 = SYS_HTTPPOSTRESPONSE;

PARSEXML TEXT STRINGVAR3 INTO TMPTABLE;SET TMPTABLE TO TABLE TMPTABLE;

20.2. Calling Web Services 153

Programming with TROIA, Release 0.5.beta

154 Chapter 20. HTTP Operations & Calling Web Services

CHAPTER 21

Port Communication (Serial & TCP)

TROIA Platform supports sending/recieving data over serial ports. Also its possible to communicate over TCP portsusing TCP Protocol. This sections aims to introduce communicating over serial and TCP ports

21.1 Introduction

21.2 Opening/Closing Serial Ports

..serial port

OPENPORT {port} {portname} [ PARAMETERS [BAUDRATE {baudrate}][DATABITS {databits}][STOPBITS {stopbits}][PARITY NONE|ODD|EVEN|MARK|SPACE][FLOWCONTROL NONE|RTSCTSIN|RTSCTSOUT|XONXOFFIN|XONXOFFOUT][RTS {rts}][DTR {dtr}][ENCODING {encoding}][DEBUG TRUE|FALSE] ];

CLOSEPORT {portname};

Open/Close COM1 port on client:

OBJECT:STRING PORT,STRING PORTNAME;

PORTNAME = '*PORT';PORT = 'COM1';OPENPORT PORT PORTNAME PARAMETERS BAUDRATE '9600'

(continues on next page)

155

Programming with TROIA, Release 0.5.beta

(continued from previous page)

DATABITS '8' STOPBITS '1' PARITY NONE;

CLOSEPORT PORTNAME;

21.3 Opening/Closing TCP Ports

OPENPORT TCP {portname} PORT {portnumber} [IPADDRESS {ipaddress}];

CLOSEPORT {portname};

open a tcp port to 192.168.5.114

OBJECT:STRING PORTNAME;

PORTNAME = '*PORTNAME';OPENPORT TCP PORTNAME PORT 4848 IPADDRESS '192.168.5.114';CLOSEPORT PORTNAME;

open a tcp port on localhost

OBJECT:STRING PORTNAME;

PORTNAME = '*PORTNAME';OPENPORT TCP PORTNAME PORT 4848;

CLOSEPORT PORTNAME;

21.4 Reading Data From Port

READFROMPORT {portname} INTO {variable};

read from a serial port.

OBJECT:STRING PORT,STRING PORTNAMESTRING RESULT;

PORTNAME = '*PORT';PORT = 'COM1';OPENPORT PORT PORTNAME PARAMETERS BAUDRATE '9600'

DATABITS '8' STOPBITS '1' PARITY NONE;INTEGERVAR1 = 0;STRINGVAR3 = '';RESULT = '' ;

WHILE INTEGERVAR1 < 100BEGIN

(continues on next page)

156 Chapter 21. Port Communication (Serial & TCP)

Programming with TROIA, Release 0.5.beta

(continued from previous page)

READFROMPORT PORTNAME INTO RESULT;IF RESULT != '' THEN

STRINGVAR3 = RESULT;ENDIF;DELAY 100;INTEGERVAR1 = INTEGERVAR1 + 1;

ENDWHILE;

CLOSEPORT PORTNAME;

read data from a tcp port

OBJECT:STRING STRINGVAR3,STRING PORTNAME;

PORTNAME = '*PORTNAME';OPENPORT TCP PORTNAME PORT 4848 IPADDRESS '192.168.5.114';READFROMPORT PORTNAME TO STRINGVAR3;CLOSEPORT PORTNAME;

21.5 Writing Data To Port

SENDTOPORT {portname} {content} [{timetowait}];

write data to a tcp port

OBJECT:STRING PORTNAME;

PORTNAME = '*PORTNAME';OPENPORT TCP PORTNAME PORT 4848;SENDTOPORT PORTNAME 'Hello World!';CLOSEPORT PORTNAME;

21.5. Writing Data To Port 157

Programming with TROIA, Release 0.5.beta

158 Chapter 21. Port Communication (Serial & TCP)

CHAPTER 22

Shared Libraries & Running Other Programs

This sections aims to introduce using dll/so files as library to call methods in dll/so and invoking other programs toperform a specific action or open specific file formats.

22.1 Introduction to Shared Libraries

22.2 Using Shared Libraries in TROIA

iasNativeCall.dll / iasNativeCall.so

22.2.1 LOADNATIVE Command

LOADNATIVE {libname} , {signature} TO {targetsymbol} WITH {parameters};

OBJECT:STRING STRINGVAR1,STRING STRINGVAR2;

STRINGVAR1 = 'int abs(int)';LOADNATIVE '!msvcrt.dll',STRINGVAR1 TO STRINGVAR2 WITH '-4';

OBJECT:STRING STRINGVAR1,STRING STRINGVAR2;

STRINGVAR1 = 'int abs(int)';LOADNATIVE 'msvcrt.dll',STRINGVAR1 TO STRINGVAR2 WITH '-4';

159

Programming with TROIA, Release 0.5.beta

22.3 Opening Files with Default App

Users selects different default applications for specific file extensions, so it is not possible to indicate a correct ap-plication while writing TROIA code that opens a file in client side. For example; to show a .htm file, runningchrome/internet expolorer is not a correct approach for a cross-platform application. The default browser (or anotherkind of application) depends on operating system of the client and user’s choice.

To reduce creating a cross-platform solution, TROIA has a RUNFILE command that fires default application for givenfile extension. Using this command TROIA programmers totally ignore which application or program is default forgiven file, all operations are performed in interpreter layer.

RUNFILE {filepathonclient};

RUNFILE command works only for client side paths, in other words it is not possible to fire default application inapplication server. Here is an example that creates a .htm file and runs it with default browser.

OBJECT:STRING STRPATH;

STRPATH = '*C:\TMP\runfile.htm';

OPEN FILE STRPATH FORNEW;PUT '<b>RUNFILE Command</b>';CLOSE FILE;

RUNFILE STRPATH;

Same example, for a server side path.

OBJECT:STRING STRPATH;

STRPATH = '.\runfile.htm';

OPEN FILE STRPATH FORNEW;PUT '<b>RUNFILE Command</b>';CLOSE FILE;

RUNFILE STRPATH;DELETEFILE STRPATH;

22.4 Invoking Other Programs

RUNPROGRAM {executable} [params] [WITH WAIT [INTO {targetsymbol}]];

22.4.1 RUNPROGRAM Command

OBJECT:STRING STRINGVAR3,STRING COMMAND;

COMMAND = '*ipconfig -all';RUNPROGRAM COMMAND WITH WAIT INTO STRINGVAR3;

160 Chapter 22. Shared Libraries & Running Other Programs

Programming with TROIA, Release 0.5.beta

OBJECT:STRING STRINGVAR3,STRING COMMAND;

COMMAND = '*java -jar C:\TMP\OutPrinter.jar p1 p2 p3 p4';RUNPROGRAM COMMAND WITH WAIT INTO STRINGVAR3;

public static void main(String[] args) {

System.out.println("Out Printer");if (args.length > 0) {

for (int i = 0; i < args.length; i++) {System.out.println(" Arg " + (i + 1) + ": " + args[i]);

}} else {

System.out.println(" No Input Parameter.");}

}

22.5 Exercise 1: Checking domain availability

OBJECT:STRING STRINGVAR3,STRING COMMAND,STRING TMPRESULT;

STRINGVAR1 = 'g';INTEGERVAR1 = 0;STRINGVAR3 = '';

WHILE INTEGERVAR1 < 20BEGIN

INTEGERVAR1 = INTEGERVAR1 + 1;STRINGVAR1 = STRINGVAR1 + 'g';STRINGVAR2 = 'www.'+STRINGVAR1+'le.com';COMMAND = '*C:\TMP\whois.exe ' + STRINGVAR2;SYNCHRONIZE;RUNPROGRAM COMMAND WITH WAIT INTO TMPRESULT;

IF STRPOS(TMPRESULT, 'No whois information found') > 0 THENSTRINGVAR3 = STRINGVAR3 + STRINGVAR2 + ' : available.';

ELSESTRINGVAR3 = STRINGVAR3 + STRINGVAR2 + ' : not available.';

ENDIF;

STRINGVAR3 = STRINGVAR3 + TOCHAR(10);ENDWHILE;

22.5. Exercise 1: Checking domain availability 161

Programming with TROIA, Release 0.5.beta

162 Chapter 22. Shared Libraries & Running Other Programs

CHAPTER 23

Client Plugin Development

TROIA Platform offers an api to integrating third party applications with TROIA client. This sections aims to introduceclient plugin api to developers who wants to develop applications integrated with client application of TROIA Platform.

23.1 Introduction

Plugins are third party applications or libraries that are able to communicate with client application over plugin ser-vice. It is possible to develop a wide range of plugins from simple logging applications to enterprise level businessintelligence tools using java programming language.

23.1.1 Enabling Plugin

To enable plugin check Menu -> Settings -> Plugin -> Enable Plugins checkbox.

23.1.2 Installation Details

If plugin service is enabled, client deploys and starts Plugin Service automatically. Plugin Service is installed to {user-homefolder}RESOURCESPluginServicefolder. PluginService is also updated by Canias Client. Plugin Infrastructureis supported on 5.02.01 100801 and following versions.

23.1.3 Components of Plugin Infrastructure

Plugin Service: A standalone service that creates a communication infrastructure between client and plugins. Thisservice is installed and run automatically if there is an open Canias client that allows plugin service (Canias-> Settings-> Plugin->Enable Plugins)

caniasplugin.jar: a java library for developing all types of client plugins. This jar is supplied by IAS.

163

Programming with TROIA, Release 0.5.beta

23.2 Types of Plugins

There are two types of client plugin. First one is executable plugin. Executable plugins are standalone and runnableapplications that connect to Canias. This kind of applications must connect to plugin service using caniasplugin api.For example; business intelligence tools, drawing or cad tools.

Second type of plugins is non-executable plugin. This plugins are not runnable applications. They are installed toplugin service as library file. Plugin service fires (calls) their methods when a related action occurs. In this type ofplugins there is no need an extra running application. For example: logging applications, etc.

23.3 How to Develop a Plugin

To connect a standalone application to TROIA Platform or develop a plugin “caniasplugin.jar” must be used as library.This api contains all required infrastructure communicate with client application. Using this api it is possible to sendactions to Canias clients or listen actions from Canias Client. Two sample plugins(executable, non-executable) aresupplied with this document.

23.3.1 Key Classes

To develop a plugin, programmers must only inherit iasAbstractPlugin class which is supplied in caniasplugin.jar.

iasAbstractPlugin has abstract methods that must be overridden by your plugin. When and PLUGINACTION com-mand run on an TROIA application, doAction(iasPluginAction p) method is fired. To send events to Canias Clientfrom a plugin use postEvent(iasPluginEvent e, String target) method.

iasPluginAction class contains all required information such as action class, action type, action value, session id,transaction id, username and transaction. Event source is also contained by iasPluginAction. Using event sourcevalue, it is possible to send events to Canias Client which sends previous action. To fire an action on Canias Client,plugins must send an iasPluginEvent using postEvent() method of iasAbstractPlugin. Event type and event value mustbe supplied by plugin.

Details about all required classes are in Javadoc files which are supplied with this document and caniaspluging.jar.Also, sample plugins include usage examples of this classes.

23.3.2 Deploying a Plugin

To deploy second type of plugin (non-executable) plugin jar must be copied into. . . RESOURCESPluginServicepluginsfolder. For non-executable plugins jar file must have same name with the classthat inherits iasAbstractPlugin. For example; if com.samplecompany.sammpleplugin.java inherits iasAbstractPluginjar’s name must be com.samplecompany.sammpleplugin.jar (See sample plugins Non-Executable)

Executable plugins are standalone applications, so there is no need to any special deployment action.

23.4 Sources of a Simple Generic Plugin

These example contains source codes of a simple plugin (has only three class) that prints each action to a textfield.Here is the first and most important class that inherits iasAbstracPlugin class which is provided in caniasplugin.jarlibrary:

164 Chapter 23. Client Plugin Development

Programming with TROIA, Release 0.5.beta

package com.ias.client.plugin.test;

import java.rmi.RemoteException;

import com.ias.client.plugin.iasAbstractPlugin;import com.ias.client.plugin.iasPluginAction;import com.ias.client.plugin.iasPluginValidationParameters;

@SuppressWarnings("serial")/*** plugin passes all action parameters to frame to print on a text

* field

*/public class SamplePlugin extends iasAbstractPlugin {

public SamplePluginFrame Frame;private String m_strUniqueInstanceKey;

protected SamplePlugin(SamplePluginFrame pFrame,String pUIK) throws RemoteException {

super();

Frame = pFrame;m_strUniqueInstanceKey = pUIK;

}

/*** called when a PLUGINACTION command runs on application

* server.

** this demo plugin converts iasPluginAction to a string

*/@Overridepublic boolean doAction(iasPluginAction pAction) {

StringBuilder sb = new StringBuilder();

sb.append("Class:").append(pAction.getActionClass());

sb.append("\nType: ").append(pAction.getActionType());

sb.append("\nValue: ").append(pAction.getActionValue());

sb.append("\nSource: ").append(pAction.getSource());

sb.append("\nSessionId: ").append(pAction.getSessionId());

sb.append("\nTransactionId: ").append(pAction.getTransactionId());

sb.append("\nUsername: ").append(pAction.getUsername());

sb.append("\nTransaction: ").append(pAction.getTransaction());

(continues on next page)

23.4. Sources of a Simple Generic Plugin 165

Programming with TROIA, Release 0.5.beta

(continued from previous page)

sb.append("\n");

Frame.handleAction(sb.toString(),pAction.getSource());

return true;}

/*** called when PLUGINVALIDATE command runs on appliaction

* server. PLUGINVALIDATE command sends all validation

* parameters to all plugins which contains data

* (language,database etc) about session.

** After this parameters is checked by plugin, if given params

* is valid for plugin must send true.

** If multiple plugins are available, a pop up message appears

* on client to allow user select target plugin for given

* action.

*/@Overrideprotected boolean validatePlugin(

iasPluginValidationParameters params) {// return true/false after validation paramters// checkedreturn true;

}

/*** plugin service sends only related actions to this plugin

*/@Overridepublic String[] getRelatedIncomingActionClasses() {

return new String[] { "BITOOL" };}

@Overridepublic String getAppName() {

return "BITOOL - Business Analytics";}

@Overrideprotected void disconnecting() {

Frame = null;}

@Overridepublic String getAppInstanceKey() {

return m_strUniqueInstanceKey;}

}

Second class is a simple user interface that contains a textfield to print received action and push actions to clientapplication. Third class is only an entry point (main method) for the sample plugin. You can download full and up todate source code of demo application from http://www.github.com/bahtiyartan/troia-platform-client-plugin-demo.

166 Chapter 23. Client Plugin Development

Programming with TROIA, Release 0.5.beta

23.5 Sending Message to a Plugin

23.5.1 PLUGINACTION Command

For sending an action to plugins from TROIA Layer, PLUGINACTION command is used, here is the syntax:

PLUGINACTION ACTIONCLASS {actionclass} ACTIONTYPE {actiontype}[ACTIONVALUE {value}] [TARGET {pluginid}]

Action class shows plugin functionality. Plugin Service sends this action to related plugins using action class param-eter. In other words it is used for selecting which plugin must consume this action. Second parameter, action type isused to determine which action will be performed on selected plugin. Action value is optional and it’s value is passedto plugin as string. (pure string, xml, json, etc.)

Its also possible to send an action to a target plugin directly without plugin selection process. Target parameter isused to indicate target plugin for action. To get pluginId of a executable/non-executable plugin, PLUGINVALIDATEcommand is used.

23.5.2 PLUGINVALIDATE Command

PLUGINVALIDATE [ACTIONCLASS {actionclass}] [VALIDATIONSTRING {valstr}]TO PLUGINCAPTION {plugincaption} PLUGINID {pluginid};

For given action class, sends validation string to executable/non-executable plugins to check valid plugins for givenparameters. If there is only one plugin, its caption and id are set to target parameters. If there are multiple plugins, apop up appears to help user to select appropriate plugin for given action.

Action class is used to get related plugins for given action class. It is optional, if it is not given in validate commandvalidation string is sent to all executable/non-executable plugins. Validate string is a business layer validation string.This parameters is send to related plugins to check business layer data, to check whether plugin is valid for givenaction type.

Plugin caption is a target string symbol to get name for selected plugin caption and pluginid is a target string symbolto get selected plugin id. This value can be used as target PLUGINACTION command

23.5.3 Plugin Class

To access a plugin easily, PLUGINACCESS which is a wrapper class is included in standard code database. Basicmethods of this class are below:

VOID DOACTIONWP(STRING PACTIONCLASS, STRING PACTIONTYPE, STRING PACTIONVALUE) :This method sends given action parameters to PluginService. If class has a target plugin information this action is sentto target plugin automatically. This method uses PLUGINACTION command.

VOID SETDEFAULTACTIONCLASS(STRING PACTIONCLASS) : Sets default action class, and uses this actionclass for all actions.

VOID DOACTION(STRING PACTIONTYPE, STRING PACTIONVALUE) : This method sends given action pa-rameters to PluginService. Uses default action class which is set by SETDEFAULTACTIONCLASS() method. If classhas a target plugin information this action is sent to target plugin automatically. This method uses PLUGINACTIONcommand.

STRING SELECTTARGET(STRING PACTIONCLASS, STRING PVALSTRING) : Checks appropriate pluginsusing given parameters. If there are multiple applications which is valid for given parameters, shows selection dialog

23.5. Sending Message to a Plugin 167

Programming with TROIA, Release 0.5.beta

on client side. If there is only one plugin it sets target plugin information for this PLUGINACCESS instance. Returnstarget plugin’s id.

VOID CLEARTARGET() : Clears target plugin id and caption.

STRING GETTARGET() : Returns target plugin id. If there is not a target plugin returns empty string. To select atarget you must call SELECTTARGET() method.

STRING GETTARGETCAPTION() : Returns target plugin caption.

VOID CLEARTARGET() : Clear target plugin id and caption for this instance.

Here is an example which sends a single message to a plugin:

OBJECT:PLUGINACCESS PACCESS1;

PACCESS1.DOACTIONWP('BITOOL','OPENANALYSIS','params');

Another example that sends multiple actions to a selected plugin:

OBJECT:PLUGINACCESS PACCESS1;

PACCESS1.SETDEFAULTACTIONCLASS('BITOOL');

PACCESS1.DOACTION('OPENANALYSIS1','params');PACCESS1.DOACTION('OPENANALYSIS2','params');PACCESS1.DOACTION('OPENANALYSIS3','params');

Another example that shows selecting a target plugin to send next messages directly :

OBJECT:PLUGINACCESS PACCESS1;

PACCESS1.SELECTPLUGIN('BITOOL');

PACCESS1.SETDEFAULTACTIONCLASS('BITOOL');PACCESS1.DOACTION('OPENANALYSIS1','params');PACCESS1.DOACTION('OPENANALYSIS2','params');

168 Chapter 23. Client Plugin Development