This chapter provides a tutorial based on sample1, a basic tracking system, and covers these topics:
Analyzing the sample1 PDL file
Using tvgen and tvinstall to generate sample1
Expanding the sample1 application
The sample1 tracking system is a useful tool that teaches you how to build your own tracking system. The user interface for sample1 is shown in Figure 4-1.
The PDL file sample1.pdl is located in /usr/Tracker/samples and is listed in Figure 4-2.
Like all PDL files, sample1 has sections for field declarations, transition declarations, and view declarations. sample1 is a simple application, so there are no auxiliary views.
Let's analyze the sample1 PDL file, piece by piece. For details on the meaning of each term and its use, refer to Chapter 2, “Using the Process Description Language (PDL).”
The field declaration follows:
fields {
submitter: short-text;
submit_date: date;
owner: short-text
priority: one-of LOW, MEDIUM, HIGH;
project: one-of PROJECT_1, PROJECT_2, PROJECT_3...;
description: long-text;
close_date: date;
}
|
The sample1 PDL file has seven field declarations:
| submitter | is a short-text field; it lets users enter any text with no restrictions except size (one line only). | |
| submit_date | is a date type fields; Tracker ensures that the entry is in a proper date format. | |
| close_date | is a date type field. | |
| owner | is a short-text field like submitter. | |
| priority | is one-of field, limiting the user to the three selections: LOW, MEDIUM, and HIGH. | |
| project | is also a one-of field, but the ellipsis at the end makes it an open rather than closed enumeration. Thus, users can select one of the three selections or enter their own. | |
| description | is a long-text field, thus permitting multiple lines of text. |
The transition declarations follow the field declarations in PDL files. Each transition declaration requires a state change declaration, which can be simply the transition operator in a declaration (=>), indicating no state change with any current state valid. Rules and actions are optional.
The transition declarations for sample1 follow:
transitions {
SUBMIT(=>AWAITING_RESPONSE) {
rules {
description.isSet;
}
actions {
submit_date.setValue('now');
submitter.setValue($USER.value);
}
}
RESOLVE(AWAITING_RESPONSE=>CLOSED) {
rules {
description.changed;
}
}
REJECT(AWAITING_RESPONSE=>CLOSED) {
rules {
description.changed;
}
}
EDIT(=>) {
}
}
|
sample1 has four transitions: SUBMIT, RESOLVE, REJECT, and EDIT.
SUBMIT takes a request from a nonexistent state to AWAITING_RESPONSE. Its only rule is that there must be an entry in the description field. This is accomplished through the isSet method:
description.isSet; |
SUBMIT has two actions:
The declaration
submit_date.setValue('now');
|
has the effect of setting the submit_date field to the value of `now', which is replaced by the current date and time.
The action declaration
submitter.setValue($USER.value); |
forces the submitter field to the current user.
RESOLVE and REJECT have similar declarations. They both take a request from AWAITING_RESPONSE to CLOSED. Both incorporate one rule; the description must change. Its purpose is to cause the user to provide an explanation when resolving or rejecting the request.
The EDIT transition is open-ended in nature. The state does not change and EDIT can be applied to requests in any state. It has no rules or actions. You can declare no rules or actions with empty braces with or without the key words. In the example we simply use empty braces after the state declaration.
The view declaration for sample1 is as follows:
views {
Sample1(){
control-bar() {
transitions;
};
qresults() {
index $ENTITY_ID ' ', $STATE ' ', owner,
` submitted by `, submitter;
};
display() {
row{'Report #:' $ENTITY_ID, 'Status:' $STATE,
'Owner:' owner, 'Submitter:' submitter};
row{'Date:' submit_date,'Project:' project,
'Priority:' priority, 'Closed:' close_date};
row{'Description:' ' '};
row{description};
}
}
}
|
The example has one view called Sample1 that has declarations for a standard control bar, query results area, and request form area.
The control bar is specified to use all four transitions, since the transitions key word is used with no transition names specified.
The query results area sets up an index of the request number (equal to the $ENTITY_ID variable), the state ($STATE), owner, and submitter. In the GUI, the area is divided into four columns, each with a title indicating the type of data it displays. The data in text columns is left-justified and vertically aligned. Data in numeric columns is right-justified.
The first two rows have four fields, plus a label for each one. The first two fields, Report # and Status, are predefined. The next six fields use field declarations from the beginning of the PDL file. The string 'Description:' is used as a label, padded with trailing white space (` `), as described in the section on tuples (see “Defining a Request Form Area” in Chapter 2).
Before you can run sample1, use tvgen to compile it and then use tvinstall to create the links from the public directories to the application directories. Here are the steps for generating sample:
Become super-user.
Create a test directory and copy the PDL file sample1.pdl from the /usr/Tracker/samples directory to your test directory.
From any directory, type:
tvgen <yourTestDirPath>/db <yourTestDirPath>/sample1.pdl |
where the expression <yourTestDirPath>is the absolute path to your test directory. (If sample1.pdl is in your database directory, you can use a relative path.)
Running tvgen creates a script called sample1 in /yourTestDirPath/db/tools/bin, a number of database files in /yourTestDirPath/db, help files in <yourTestDirPath>/db/tools/help, and an app-defaults file called Sample1 in <yourTestDirPath>/db/tools/lib/X11.
Then type:
tvinstall <yourTestDirPath> /db/tools |
As before, <yourTestDirPath> must be an absolute path. Running tvinstall has the following effects:
All directories and executable files in
<yourTestDirPath>/db/tools/bin are linked into /usr/local/bin.
All directories and files in <yourTestDirPath>/lib are linked into /usr/local/lib.
All files in <yourTestDirPath>/db/tools/lib/X11/app-defaults are linked into /usr/lib/X11/app-defaults.
All files in <yourTestDirPath>/db/tools/lib/images are linked into
/usr/lib/images.
The files in<yourTestDirPath>/db/tools/help are linked into
/usr/lib/onlineHelp.
The on-line help database is rescanned and any currently running help server is killed.
To run sample1, at the shell prompt, type:
/usr/local/bin/sample1 |
You can add /usr/local/bin to your path so that in future you need only type sample1 to run the application.
![]() | Note: The end users must rcp or NFS-mount the tools directory (...db/tools) onto their own systems. They then install the default Tracker subsystems on their systems and run tvinstall to set up the required links from the tools directory to their systems. |
The sample1 example assumes a simple tracking process in which the owner closes his or her own requests. This section introduces the concept of an approval authority, which adds a level of complexity to the application by adding another transition state, APPROVE.
The two existing intermediate states are AWAITING_RESPONSE and CLOSED. When a third intermediate state, AWAITING_APPROVAL, is added, the other transitions may also have to be rerouted.
To incorporate an approver, follow these steps:
declare a field named Approver
add the Approver field to the main view
add an intermediate state called AWAITING_APPROVAL and change the affected transitions accordingly
add a new transition named APPROVE
These steps are detailed in the following sections. You can edit your sample1 PDL file accordingly.
To add a field declaration, you:
specify an internal field name
select a type for it
edit the field declarations section of the PDL file.
A complete list of field types is provided in Table 2-1 in Chapter 2. In this example, we add a field named approver of type short-text, (see Figure 4-3).
Once you have defined a field, you need to add it to the user interface, by editing the view declarations portion of the PDL file.
In this example, we add a tuple that comprises the approver field and the “Approver” label. There are currently eight short fields in two groups of four, plus the larger description field.
To keep things symmetrical, change the view to three rows of three fields each, adding the approver field last (see Figure 4-4).
Adding a new state is tricky because it actually changes the process. All transitions that enter or leave that state have to be changed accordingly. NEED MORE EXPLANATION
Figure 4-5 shows the state transitions of a request as sample1 was originally designed.
To implement the notion of an approval authority, you need to add an intermediate state called AWAITING_APPROVAL after the owner is through with the request, and prior to its being closed. This is shown in Figure 4-6.
As a result, you need to change the RESOLVE and REJECT transitions so that instead of going from AWAITING_RESPONSE to CLOSED, they go to AWAITING_APPROVAL. The transition declarations are shown in Figure 4-7.
You now need to create a new transition called APPROVE that takes a request from the AWAITING_APPROVAL state to CLOSED. To set a condition requiring the approver to add an explanation to the description for closing the request, add the rule:
description.changed; |
You can also add an action:
close_date.setValue('now');
|
This sets the closed date to the date on which the APPROVE transition is performed. Figure 4-8 shows the transitions section after you have added the new rule and action.