Skill for understanding, editing, analyzing, and migrating TIBCO Objectstar (Object Service Broker) code used in mainframe OTP and batch applications...
.OSB / MetaStore / screen rulesGET, FORALL, ON GETFAIL, DISPLAY, REPLACE, etc.Objectstar rules are declarative procedures with four sections:
Used in both interactive OTP (3270 screens) and batch (job stream) contexts.
Objectstar has no IF/THEN/ELSE. All conditional logic uses condition quadrants ā a Y/N matrix that determines which actions execute.
RULE_NAME(param1, param2);
LOCAL var1, var2; -- Untyped local variables
---------------------------------------------------------------------------
condition1; | Y N N -- Condition rows
condition2; | Y N
------------------------------------------------------------+---------------
action1; | 1 -- Action rows (numbered)
action2; | 1
action3; | 1
---------------------------------------------------------------------------
ON GETFAIL: -- Exception handlers
handler_action;
CALC_DISCOUNT(CUST_TYPE, ORDER_AMT);
LOCAL DISCOUNT;
---------------------------------------------------------------------------
CUST_TYPE = 'PREMIUM'; | Y N N -- Column 1: Premium
ORDER_AMT > 1000; | Y N -- Column 2: Large order
------------------------------------------------------------+---------------
DISCOUNT = 0.20; | 1 -- 20% for premium
DISCOUNT = 0.10; | 1 -- 10% for large orders
DISCOUNT = 0.05; | 1 -- 5% default
Equivalent pseudo-code:
if (CUST_TYPE == 'PREMIUM') { DISCOUNT = 0.20; }
else if (ORDER_AMT > 1000) { DISCOUNT = 0.10; }
else { DISCOUNT = 0.05; }
Objectstar tables can be parameterized ā creating logically separate data partitions using the same table definition.
TABLE(param1) -- Single parameter
TABLE(param1, param2) -- Multiple parameters
REGIONAL_REPORT(REGION_CODE);
LOCAL TOTAL;
---------------------------------------------------------------------------
TOTAL = 0;
FORALL SALES(REGION_CODE) WHERE YEAR = 2024
ORDERED DESCENDING AMOUNT
UNTIL GETFAIL:
TOTAL = TOTAL + SALES.AMOUNT;
END;
CALL MSGLOG('Total for ' || REGION_CODE || ': ' || TOTAL);
Calling with different parameters accesses different data:
CALL REGIONAL_REPORT('WEST'); -- Accesses SALES('WEST')
CALL REGIONAL_REPORT('EAST'); -- Accesses SALES('EAST')
| Pattern | Example |
|---|---|
| Regional partitioning | SALES(REGION), INVENTORY(WAREHOUSE) |
| Temporal partitioning | TRANSACTIONS(YEAR), LOGS(MONTH) |
| Multi-tenant | CUSTOMERS(TENANT_ID) |
| Configuration | CONFIG(ENVIRONMENT) |
Parameterized tables have no direct SQL equivalent. Migration options:
Option 1: Composite Key
@Entity
public class Sales {
@EmbeddedId
private SalesId id; // Contains region + primary key
}
// Query with region filter
salesRepository.findByIdRegionAndYear("WEST", 2024);
Option 2: Filtered Repository
public interface SalesRepository {
@Query("SELECT s FROM Sales s WHERE s.region = :region AND s.year = :year")
List<Sales> findByRegionAndYear(String region, int year);
}
Option 3: Separate Tables (for strict isolation)
SALES_WEST, SALES_EAST with union viewsSee objectstar-syntax.md for language keywords and examples.
ā
Always trap expected exceptions (GETFAIL, INSERTFAIL) locally
ā
Use primary key WHERE clauses for GET and REPLACE to ensure intent list consistency
ā
Use EXECUTE for sub-transactions that should commit independently
ā
Commit periodically in batch jobs to avoid COMMITLIMIT errors
ā
Use screen tables for passing data in OTP rules and session tables in batch
ā
Favor BROWSE mode when writing read-only rules
ā Using ON ERROR as a general flow control ā leads to masked bugs
ā FORALL with nested loops over large tables ā performance killer
ā No COMMIT in long batch loops ā causes memory and lock issues
ā Hardcoding dataset names and magic values ā hinders migration
ā Reliance on implicit global state instead of parameter passing
See objectstar-pitfalls.md for deeper explanations.
Exception loop idiom:
CALL FORALLA('TABLE', ...);
UNTIL ENDFILE:
CALL FORALLB('TABLE');
END;
CALL FORALLE('TABLE');
Screen data validation rule:
GET CUSTOMER WHERE ID = SCR.ID;
ON GETFAIL:
CALL SCREENMSG('SCR', 'Customer not found');
SIGNAL ERROR;
Batch processing with commit window (using condition quadrant):
BATCH_PROCESS;
LOCAL COUNT;
---------------------------------------------------------------------------
COUNT = 0;
FORALL INVOICES UNTIL GETFAIL:
CALL PROCESS_INVOICE;
COUNT = COUNT + 1;
COUNT >= 1000; | Y N
----------------------------------------+-----
COMMIT; | 1
COUNT = 0; | 2
END;
COMMIT; -- Final commit for remaining
Copy these checklists to track progress on complex tasks.
## Objectstar Analysis Progress
### 1. Structure Identification
- [ ] Locate rule declaration and arguments
- [ ] Identify LOCAL variables
- [ ] Map condition quadrant columns
- [ ] List action sequence numbers
### 2. Data Flow Analysis
- [ ] Trace LOCAL variable scope (visible in descendant rules)
- [ ] Document table access patterns (GET/REPLACE/INSERT/DELETE)
- [ ] Identify parameterized table usage
### 3. Control Flow Analysis
- [ ] Map condition quadrant to branching logic
- [ ] Document FORALL patterns and termination conditions
- [ ] Note TRANSFERCALL usage (no return)
- [ ] List all CALL/EXECUTE dependencies
### 4. Exception Analysis
- [ ] List all ON handlers
- [ ] Check handler specificity (table-specific before generic)
- [ ] Identify SIGNAL statements
- [ ] Verify ON ERROR has proper handling
### 5. Documentation
- [ ] Summarize rule purpose
- [ ] Document business logic
- [ ] Note migration concerns
## Objectstar Migration Progress
### Phase 1: Inventory
- [ ] Extract MetaStor (tables, rules, screens)
- [ ] Classify rules: OTP vs batch vs utility
- [ ] Document parameterized tables
- [ ] Map CALL/EXECUTE/TRANSFERCALL dependencies
### Phase 2: Schema Migration
- [ ] Map TDS tables to relational schema
- [ ] Convert parameterized tables to composite keys
- [ ] Define foreign key relationships
- [ ] Create JPA entities
### Phase 3: Logic Migration (per rule)
- [ ] Convert condition quadrants to decision logic
- [ ] Map LOCAL variables to typed Java fields
- [ ] Handle scope chain with context objects
- [ ] Convert FORALL to repository queries + streams
### Phase 4: Exception Handling
- [ ] Map Objectstar exceptions to Java exceptions
- [ ] Convert ON handlers to try-catch blocks
- [ ] Implement transaction boundaries (@Transactional)
### Phase 5: UI Migration (if OTP)
- [ ] Convert screens to web forms
- [ ] Map screen tables to DTOs
- [ ] Implement validation rules
### Phase 6: Validation
- [ ] Create test cases from existing behavior
- [ ] Run ā Compare ā Fix ā Repeat
- [ ] Verify transaction semantics preserved
1. Identify anti-pattern (see pitfalls.md)
2. Apply refactoring
3. Verify rule compiles/runs
4. Test affected functionality
5. If issues ā revert and retry
6. Document changes