# Business Logic — JKKTvSvcKeiCourceChgCC.setNullToMsg() [27 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `com.fujitsu.futurity.bp.custom.common.JKKTvSvcKeiCourceChgCC` |
| Layer | CC/Common Component (Package: `com.fujitsu.futurity.bp.custom.common`) |
| Module | `common` (Package: `com.fujitsu.futurity.bp.custom.common`) |

## 1. Role

### JKKTvSvcKeiCourceChgCC.setNullToMsg()

This method implements a **CAAN message field cleanup and normalization** routine used within the telecom service contract change processing domain. Specifically, it scans a `CAANMsg` object (a message payload used in Fujitsu's CAAN middleware) for keys that carry an `_err` suffix — indicating that these keys correspond to error or validation data fields. For each such key, it strips the suffix, verifies whether the corresponding base data field is present and non-empty in the message, and nulls out the base field if it is missing or blank. This ensures that downstream processing never encounters stale error keys paired with empty or absent base data, which could trigger spurious validation errors or null pointer exceptions.

The method implements a **recursive traversal pattern**: when a base data field holds a `CAANMsg[]` (an array of sub-messages, representing nested structures like line-item details or child records), the method recursively invokes itself on each sub-message. This allows it to clean up error metadata at arbitrary nesting depths within the message tree.

As a **shared utility method** encapsulated in the `JKKTvSvcKeiCourceChgCC` common component class, this method is not tied to a single screen or use case. It is called from multiple entry points within the same class (e.g., `editInMsg` and the overloaded `setNullToMsg`) and likely across multiple service components that handle telecom service type changes — such as FTTH (Fiber To The Home), mail service changes, and other broadband contract modifications. Its role in the larger system is to **enforce message consistency** before data is forwarded to downstream CBS (CBS = Central Business System) components or persisted to entity tables.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["setNullToMsg(CAANMsg msg)"])
    A["Get schema key set iterator"] --> B{"More keys?"}
    B -->|yes| C["Get next key"]
    C --> D{"key ends with '_err'?"}
    D -->|no| B
    D -->|yes| E["tmpKey = key.substring(0, key.length() - 4)"]
    E --> F{"msg.containsKeyOfMsgData(tmpKey) AND not empty?"}
    F -->|no| G["msg.setNull(tmpKey)"]
    G --> B
    F -->|yes| H["Object obj = msg.getObject(tmpKey)"]
    H --> I{"obj instanceof CAANMsg[]?"}
    I -->|yes| J["For each submsg in (CAANMsg[]):
  setNullToMsg(submsg)"]
    J --> B
    I -->|no| B
    B -->|no| END(["Return / End"])
```

This flowchart captures the complete processing logic:

1. **Iterator creation** — The method extracts an iterator over all keys defined in the message schema (`msg.getSchema().getSchemaKeySet()`).
2. **Key filtering** — Each key is tested with `endsWith("_err")` to identify error/suffix fields. Keys that do not match this pattern are skipped.
3. **Key transformation** — For `_err` keys, the suffix (4 characters) is stripped using `substring(0, length - 4)` to derive the base data field key.
4. **Null condition check** — If the base field is either **absent** from the message data or **empty** (equals empty string `""`), the base field is set to null via `msg.setNull(tmpKey)`, and the loop continues to the next key.
5. **Array sub-message recursion** — If the base field exists and is non-empty, its value is retrieved. If the value is an instance of `CAANMsg[]`, the method recursively processes each sub-message in the array, enabling deep cleanup of nested structures.

**Key business rules:**
- Only keys ending with `_err` trigger any processing; all other schema keys are silently ignored.
- The substring suffix is hardcoded as `"err"` (4 characters: `'e'`, `'r'`, `'r'`, `'\0'`... actually `length - 4` removes exactly 4 characters).
- The method processes keys in schema-order (determined by the iteration order of `getSchemaKeySet()`), not alphabetically.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `msg` | `CAANMsg` | A CAAN middleware message payload carrying service contract change data. Contains a schema-defined key set (including both data fields and their associated error metadata fields suffixed with `_err`). The method traverses this message to clean up error metadata and optionally recurses into nested sub-messages representing child records or line-item details. |

## 4. CRUD Operations / Called Services

### Pre-computed evidence from code analysis graph:

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| - | `CAANMsg.getSchema` | CAANMsg | - | Reads the message schema metadata to retrieve the key set |
| - | `CAANMsg.containsKeyOfMsgData` | CAANMsg | - | Checks if a data field exists in the message payload |
| - | `CAANMsg.getObject` | CAANMsg | - | Reads the value of a data field from the message payload |
| - | `CAANMsg.setNull` | CAANMsg | - | Sets a field in the message payload to null |
| - | `JKKTvSvcKeiCourceChgCC.setNullToMsg` | JKKTvSvcKeiCourceChgCC | - | Self-recursive call for nested CAANMsg array elements |

**Notes on classification:**
- This method performs **no direct database operations** (no C/R/U/D against entities or tables). It is a pure in-memory message transformation utility.
- All operations are **in-place mutations** on the `CAANMsg` object passed as a parameter.
- The `setNullToMsg` recursive CALL is classified as `-` (not a standard CRUD) because it is a message cleanup operation within the same CC component.
- The pre-computed evidence shows calls to `setNull` and `getObject` in various CC classes — these are classified as `-` because they operate on message payloads, not on database entities.

## 5. Dependency Trace

### Pre-computed evidence from code analysis graph:

No screen/batch entry points found within 8 hops. Direct callers found: 3 methods.
Terminal operations from this method: `setNullToMsg` [-], `getObject` [R], `getObject` [R], `setNull` [-], `setNull` [-], `setNull` [-], `setNull` [-], `setNull` [-], `getObject` [R], `getObject` [R], `substring` [-], `substring` [-], `substring` [-], `substring` [-]

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | CBS: `JKKTvSvcKeiCourceChgCC.editInMsg` | `editInMsg` -> `setNullToMsg(msg)` | `setNullToMsg [-]`, `setNull [-]` |
| 2 | CBS: `JKKTvSvcKeiCourceChgCC.setNullToMsg` (overloaded) | `setNullToMsg` (self) -> `setNullToMsg(submsg)` | `setNullToMsg [-]`, `setNull [-]` |

**Caller Analysis:**
- **`editInMsg`** — The primary caller. This method is part of the service contract change processing flow and calls `setNullToMsg` to clean up error metadata from input messages before further processing.
- **`setNullToMsg` (recursive self-call)** — Invoked when a message field contains a `CAANMsg[]` array, enabling recursive traversal of nested structures.

**No screen or batch entry points** were found within 8 hops in the call graph. This indicates that `setNullToMsg` is called by intermediate CBS/CB methods rather than directly by a UI screen or batch job, confirming its role as an internal message-cleaning utility.

## 6. Per-Branch Detail Blocks

**Block 1** — [WHILE LOOP] `(caanMsgKeys.hasNext())` (L487)

> Iterates over all keys in the message schema. This is the top-level loop that drives the entire method.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `Iterator<String> caanMsgKeys = msg.getSchema().getSchemaKeySet().iterator();` // Get iterator over all schema-defined keys |
| 2 | SET | `String key = caanMsgKeys.next();` // Retrieve the next key from the iterator |
| 3 | IF | `if (key.endsWith("_err"))` [suffix = `"err"`, 4 chars] (L489) — See Block 1.1 and Block 1.2 below |

**Block 1.1** — [nested IF] `(key ends with "_err")` — YES branch (L489)

> This block handles keys that are error metadata fields. It derives the base data key, checks if the base data is present, and either nulls it out or recurses into nested structures.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `String tmpKey = key.substring(0, key.length() - 4);` // Strip the "_err" suffix (4 characters) to derive the base data field key. [-> suffix = `"err"`] |
| 2 | IF | `if (!msg.containsKeyOfMsgData(tmpKey) || "".equals(msg.getObject(tmpKey)))` (L492) — See Block 1.1.1 and Block 1.1.2 below |
| 3 | CAST | `Object obj = msg.getObject(tmpKey);` // Cast retrieved object |
| 4 | IF | `if (obj instanceof CAANMsg[])` (L497) — See Block 1.1.3 and Block 1.1.4 below |

**Block 1.1.1** — [nested IF] `(key not in data OR data is empty)` — YES branch (L492)

> The base data field is either absent from the message or contains an empty string. In either case, the error metadata key has no corresponding data to reference, so the base field is nulled to prevent stale data from persisting.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `msg.setNull(tmpKey);` // Set the base data field to null |
| 2 | EXEC | `continue;` // Skip to the next schema key |

**Block 1.1.2** — [nested IF] `(key not in data OR data is empty)` — NO branch (L492)

> The base data field exists and is non-empty. The method proceeds to check if the value is a nested message array for recursive cleanup.

| # | Type | Code |
|---|------|------|
| 1 | SET | `Object obj = msg.getObject(tmpKey);` // Retrieve the actual data value |
| 2 | IF | `obj instanceof CAANMsg[]` (L497) — See Block 1.1.3 and Block 1.1.4 below |

**Block 1.1.3** — [nested IF] `(obj is CAANMsg array)` — YES branch (L497)

> The base data field contains an array of nested CAAN sub-messages (e.g., line-item details, child records). The method recursively cleans up error metadata in each sub-message.

| # | Type | Code |
|---|------|------|
| 1 | FOR | `for (CAANMsg submsg : (CAANMsg[]) obj)` // Iterate over each nested sub-message |
| 2 | CALL | `setNullToMsg(submsg);` // Recursively clean error metadata in the sub-message |

**Block 1.1.4** — [nested IF] `(obj is CAANMsg array)` — NO branch (L497)

> The base data field exists, is non-empty, but is NOT a `CAANMsg[]`. This is a simple scalar field — no further processing is needed. The loop proceeds to the next schema key.

| # | Type | Code |
|---|------|------|
| 1 | (no-op) | // The field is a scalar value; no recursion or nulling required |

**Block 1.2** — [nested IF] `(key ends with "_err")` — NO branch (L489)

> The current key does NOT end with `_err`. It is a regular schema key (not an error metadata field). No processing is performed; the loop continues to the next key.

| # | Type | Code |
|---|------|------|
| 1 | (no-op) | // Skip non-error keys and continue iteration |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `CAANMsg` | Class | CAAN middleware message — a Fujitsu CAAN framework message container used to carry structured data between service components. Contains a schema-defined key set and supports nested message arrays (`CAANMsg[]`). |
| `_err` suffix | Naming convention | Error metadata suffix appended to schema keys in CAAN messages. Keys ending with `_err` identify validation or error data fields that correspond to a base data field (the key with `_err` stripped). |
| `msg.getSchema().getSchemaKeySet()` | API | Returns the set of all keys defined in the CAAN message schema — the keys that this method iterates over to find error metadata fields. |
| `substring(0, length - 4)` | Operation | String operation that strips the last 4 characters from a key name (removing the `_err` suffix) to derive the base data field key. |
| `setNull` | Operation | CAAN message method that sets a field's value to null, effectively clearing it from the message payload. |
| `CAANMsg[]` | Type | Array of CAAN messages — represents nested or multi-valued message structures, typically used for line-item details or child records in telecom service data. |
| CC | Acronym | Common Component — a shared utility class in the Fujitsu Futurity framework used for cross-module helper methods. |
| JKKTvSvcKeiCourceChgCC | Class | Service Type Source Change Common Component — the enclosing class for telecom service type change processing utilities (e.g., FTTH, mail service contract modifications). |
| schema | Domain concept | The predefined structure of a CAAN message — a blueprint defining all valid keys and their types within a message payload. |
