Source-derived document; reported behaviour, inference and evidence gaps are identified in the text.
4. Journeys and State Machines
In this document
Diagram coverage
| Diagram / view | Status | Scope or next work |
|---|---|---|
| Journey / activity flow | Linked | 7 bounded views; 92 elements; 86 relationships. |
| Lifecycle state machine | Linked | 7 bounded views; 3 elements; 3 relationships. |
| Interaction sequence | Not yet generated | Capture message ordering and call/return relationships for each relevant interaction. |
Journey model and evidence boundaries
The supplied evidence describes two related but distinct execution paths: the Java application launched through D4_Main.main, and the original Informix-4GL programs under demo/source. They share business vocabulary and database names, but the evidence does not prove that every 4GL path has an equivalent Java implementation. The Java path is therefore described separately from the legacy 4GL order-maintenance path rather than merged into one assumed state machine. Detailed field definitions and representations belong in C06, while validation and business-rule conditions belong in C05.
The Java journey begins when D4_Main.main creates the application through AppFactory.create("D4_Main", args) and starts the module. D4_Main.run() obtains the stores7 database, initializes shared state through D4_Globals, loads states and stock references, and presents commands for Customer, Orders, Stock, Reports, and Exit. The application also exposes a bang command that passes user input to _app.execute(true, Str.valueOf(cmd)); this is a command-execution path rather than a business-object lifecycle and is not treated as a successful business transition merely because it is accepted by the menu. E0001 E0007 E0011
Customer maintenance journey
A customer begins in an unselected or not-yet-created condition. From the Customer menu, the user can start one-customer or repeated customer entry, find existing customers, update the selected customer, or request deletion. In the Java implementation, input_cust() gathers the customer number, names, company, address, city, state, ZIP code, and phone. If entry is interrupted through the supported input action, the operation ends without inserting a customer; the surrounding add flow reports the abort, clears the form, and resets the working customer number. E0007 E0009
On normal completion, input_cust() inserts the customer row and obtains the generated identifier through the database serial result. The working customer consequently changes from an unsaved input record to a selected customer with a database-assigned customer_num. The evidence does not establish a complete customer-creation failure contract: the 4GL source performs the insert and then reads SQLCA.SQLERRD[2] without a visible explicit status check, while the Java implementation and its framework error semantics are only partly evidenced. Whether an insert failure can be reported as successful therefore remains a specific unresolved question. E0007 E0008 E0009
Finding a customer constructs selection criteria and queries customer, with the Java path ordering results by lname. The browse journey exposes Next, Previous, First, Last, Select, and Quit actions. Navigation changes the currently displayed candidate, but it does not itself modify the database. Select establishes the current customer for subsequent update, deletion, or order entry; Quit leaves the browse without selecting a new record. Query-by-example supports literals, ranges, lists, relational operators, and wildcards in the documented behavior, although the parser and its safety guarantees are not fully available. E0007 E0009 E0012
Updating requires a selected customer. The Java path edits the customer fields and issues an update for the selected customer_num; interruption restores the stored row and reports that the update was aborted. Deletion also requires a selected customer and confirmation. If related orders are counted, deletion is refused. The Java query shown for this check counts all rows in orders for the customer, while the user-facing message refers to “active orders.” The evidence does not resolve whether all orders are intentionally treated as active or whether the query is broader than the business rule. A declined confirmation is not a deletion transition. E0002 E0007
Order-entry journey
Order entry starts by selecting an existing customer through query_customer(2). If no customer is returned, the Java flow opens customer entry and may create a customer before continuing; if the customer number remains null, the order journey ends without creating an order. This creates a dependency between the customer selection state and the order-entry state: the order header cannot proceed until a customer is available. E0007
The user then supplies order-header data, including order date, purchase-order number, and shipping instructions. Line entry collects stock number, manufacturer code, and quantity for up to ten items. A stock lookup can populate the description and unit price; an invalid lookup clears those derived fields. Once quantity and unit price are valid, item_total() calculates total_price as quantity multiplied by unit price. The order remains an in-memory working order while these header and line-item values are collected. The form definitions separately identify item number, stock number, manufacturer code, description, quantity, price, total, and a form-only running total. E0007 E0009 E0013
Completion moves the working order into database insertion. add_order() begins a transaction, inserts the order header with a temporary order number, retrieves the generated order number, inserts the item rows, and commits only if the required operations succeed. If the order insertion or item insertion reports failure, the code attempts rollback and displays an error; no committed order is established by that failed path. An exception after transaction start is less certain: the visible broad exception handler delegates to _eh.handleException(_e) and does not itself show a rollback call. Whether the framework performs recovery is unresolved. E0002 E0007 E0012
After a successful commit, the order enters a persisted state and invoice generation is requested. The invoice joins order, item, stock, and manufacturer information and directs output according to print_option: file, printer, or screen. The interactive order total applies a 1.1 multiplier, while invoice logic separately reports 6.5 percent sales tax and 3.5 percent shipping. These figures suggest an intended ten-percent relationship, but the evidence does not establish whether the displayed total and invoice amount are rounded identically or whether the multiplier has another meaning. E0002 E0012
The Java get_order() journey retrieves orders for a selected customer, displays their items, and allows the user to select one. This is a viewing and selection transition, not an update. In the Java D4_Orders.java evidence, update_order() and delete_order() are menu-level stubs that display “This option has not been implemented.” Consequently, a user’s request for either operation is rejected or terminated at the menu; it does not transition the order to an updated or deleted state. E0002 E0011 E0012
Legacy order-maintenance journey
The separate demo/source/ordmenu.4gl.main path describes a fuller order journey. Its menu offers Add, Query, Modify, Delete, and Exit. Add collects a customer, order and ship dates, and item lines, then inserts the order and items. Query browses a customer’s orders and permits one to become the selected order. Modify is permitted only when the chosen flag indicates a selected order; it can change dates and replace the order’s items. Delete likewise requires a selected order and confirmation, then deletes the order and its items. These behaviors belong to this 4GL program and should not be attributed to Java D4_Orders without direct implementation evidence. E0009
The legacy menu1.4gl.main path provides another customer/order browser with privilege-dependent menu options. It uses cur to distinguish the customer and order views and exist to indicate whether a current row is available. Query, Detail, Switch, and Exit are available to nonprivileged users; additional maintenance options are exposed to privileged users. However, det_ord() calls view_ord() and then unconditionally sets exist to 1, even when view_ord() has found no order and reset it to zero. The likely result is that later Detail, Update, or Delete actions can proceed using stale or uninitialized order data, although the exact runtime consequence depends on 4GL semantics. E0009 E0010
The same legacy path has a misleading deletion journey: del_cust() and del_ord() conditionally issue the delete only after a positive confirmation, but then unconditionally clear the form and display “Record deleted.” A negative response therefore leaves the database row in place while presenting a success message. In addition, del_ord() in ordmenu.4gl.main deletes the parent order before its item rows; whether that succeeds depends on constraints not supplied in the evidence. E0010
Reporting journey
The Reports menu supports implemented mailing-label and accounts-receivable journeys. Mailing labels use customer query-by-example criteria, order the selected customers by ZIP code, and emit customer identity and address information. Accounts receivable selects orders whose paid_date is null and groups output by customer and order. Both paths can target a file, printer, or screen, with file paths defaulting to labels.out or ar.out when no filename is supplied. E0007
Backlog and stock-list report requests do not enter a report-generation state in the Java implementation: print_backlog() and print_stock() display the unimplemented-option error. The help text independently marks those options as not implemented. Report interruption is also qualified: the 4GL report routines reset int_flag before the post-loop abort test, so an interrupted report may not be recognized as aborted. The precise behavior depends on the runtime event and control-flow semantics. E0002 E0007 E0008
Reference-data and stock journeys
States and stock are loaded as reference data before the Java main menu is entered. get_states() retains up to 50 state records, and get_stocks() retains up to 30 stock records; excess rows are not retained in the working arrays. State selection can open state_list, and stock selection can populate an order line, but these are lookup transitions rather than stock-maintenance transitions. E0002 E0007 E0009
The Java stock menu exposes add, find, update, and delete commands, but each handler reports that the option has not been implemented. Thus a stock request ends at an explicit rejected-operation state, with no evidenced stock row creation, modification, or deletion. The source data and forms show stock numbers, manufacturer codes, descriptions, units, and prices, but those definitions describe available reference data rather than proving a complete stock lifecycle. E0002 E0007 E0010
The principal unresolved journey questions are whether Java customer behavior is fully implemented in the unavailable or inconsistently supplied D4_Cust evidence, whether framework exceptions always roll back order insertion, and whether the Java and legacy 4GL journeys are intended to share one operational database lifecycle. E0002 E0012 E0010
Expandable topic detail
Journey / activity flow
Browse diagrams and evidence gaps.
Lifecycle state machine
Browse diagrams and evidence gaps.
Harten documentation of the Informix 4GL and Java source repository, from the retained 17 October 2026 export. The exact upstream revision analysed is not established. Source findings do not establish runtime behaviour or equivalence between the implementations.
Evidence identifiers are retained for traceability. The underlying analysis records are not included in this public edition; credential values are redacted. About this case study.