# Business Logic — KKW01037SFBean.typeModelData() [180 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.web.webview.KKW01037SF.KKW01037SFBean` |
| Layer | Service (SF = Service Form bean, part of the web view tier) |
| Module | `KKW01037SF` (Package: `eo.web.webview.KKW01037SF`) |

## 1. Role

### KKW01037SFBean.typeModelData()

This method serves as a **runtime type-introspection router** for the KKW01037SF (Referral Information Inquiry) screen. Given a dot-separated key string and an optional subkey, it determines and returns the Java `Class<?>` that represents the data type of a specific field within the screen's model. It implements a **dispatch/routing pattern**: the method parses the key to extract the top-level element name, then branches into type-specific handlers — each of which returns the appropriate `String.class`, `Boolean.class`, or `Integer.class` based on the subkey requested.

The method handles three categories of fields: (1) **Simple type fields** such as System IDs, customer IDs, referral party names, phone numbers, and popup mode — each returning a primitive wrapper class for a scalar value; (2) **Data-type view (list) fields** such as the Service Contract List and Customer Contract Handover List — where the key encodes a list index plus a nested field path, and the method delegates to the individual list item's own `typeModelData` implementation via the `X33VDataTypeBeanInterface`; and (3) **Common info view fields** — detected by a `"//"` prefix in the key, which are fully delegated to `super.typeCommonInfoData(key)`.

Its role in the larger system is that of a **shared metadata accessor** used by the X33V framework to build data-type metadata lists (e.g., `X33VDataTypeList`) for dynamic view binding, validation, and serialization. It is called by the screen's data-loading infrastructure to determine field types at runtime without hard-coding field introspection logic.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["typeModelData key subkey"])

    START --> C1{key equals null?}
    C1 -->|true| R_NULL["return null"]
    C1 -->|false| CHECK_SUBKEY{subkey equals null?}

    CHECK_SUBKEY -->|true| SET_SUBKEY["subkey = empty string"]
    SET_SUBKEY --> CHECK_COMMON_INFO

    CHECK_SUBKEY -->|false| CHECK_COMMON_INFO2["separaterPoint = key indexOf doubleSlash"]

    CHECK_COMMON_INFO2 --> CI{separaterPoint equals 0?}
    CI -->|true| DELEGATE_COMMON["super.typeCommonInfoData key"]
    CI -->|false| FIND_SLASH["separaterPoint = key indexOf slash"]

    FIND_SLASH --> FIRST_ELEM{separaterPoint greater than 0?}
    FIRST_ELEM -->|true| EXTRACT["keyElement = key substring 0 to separaterPoint"]
    FIRST_ELEM -->|false| SET_ELEM["keyElement = key"]

    EXTRACT --> SIMPLE_CHECK["Check simple type fields"]
    SET_ELEM --> SIMPLE_CHECK

    SIMPLE_CHECK --> ST{keyElement equals 継続システムID?}
    ST -->|true| SUBCHECK_S1{subkey equals value or state?}
    SUBCHECK_S1 -->|true| RET_STRING_S1["return String.class"]
    SUBCHECK_S1 -->|false| SIMPLE2

    SIMPLE2 --> ST2{keyElement equals 継続お客様ID?}
    ST2 -->|true| SUBCHECK_S2["return String.class value or state"]
    ST2 -->|false| SIMPLE3

    SIMPLE3 --> ST3{keyElement equals 被紹介者契約者名?}
    ST3 -->|true| SUBCHECK_S3{subkey equals value or enable or state?}
    SUBCHECK_S3 -->|true| RET_STRING_S3["return String.class or Boolean.class"]
    SUBCHECK_S3 -->|false| SIMPLE4

    SIMPLE4 --> ST4{keyElement equals 被紹介者電話番号?}
    ST4 -->|true| SUBCHECK_S4["return String.class or Boolean.class"]
    ST4 -->|false| SIMPLE5

    SIMPLE5 --> ST5{keyElement equals 被紹介者システムID?}
    ST5 -->|true| SUBCHECK_S5["return String.class or Boolean.class"]
    ST5 -->|false| SIMPLE6

    SIMPLE6 --> ST6{keyElement equals ポップアップモード?}
    ST6 -->|true| SUBCHECK_S6["return String.class value or state"]
    ST6 -->|false| LIST_CHECK

    LIST_CHECK --> LC{keyElement equals サービス契約一覧リスト?}
    LC -->|true| LIST1_PARSE["Parse keyRemain extract index bounds check svc_kei_list_list"]
    LIST1_PARSE --> DELEGATE_LIST1["typeModelData on list item"]

    LC -->|false| LC2{keyElement equals 顧客契約引継リスト?}
    LC2 -->|true| LIST2_PARSE["Parse keyRemain extract index bounds check cust_kei_hktgi_list_list"]
    LIST2_PARSE --> DELEGATE_LIST2["typeModelData on list item"]

    LC2 -->|false| FINAL_NULL["return null"]

    R_NULL --> END(["End"])
    DELEGATE_COMMON --> END
    SUBCHECK_S1 --> END
    SUBCHECK_S2 --> END
    RET_STRING_S1 --> END
    SUBCHECK_S3 --> END
    SUBCHECK_S4 --> END
    SUBCHECK_S5 --> END
    SUBCHECK_S6 --> END
    DELEGATE_LIST1 --> END
    DELEGATE_LIST2 --> END
    FINAL_NULL --> END
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `key` | `String` | The field identifier in a hierarchical dot-separated path format. It specifies which field's type to resolve. Supported formats: (a) a plain field name like "被紹介者契約者名"; (b) a path like "サービス契約一覧リスト/0/fieldName" to target a specific list item's sub-field; (c) a common info view indicator like "//<viewName>" where a `//` prefix signals delegation to the parent's common info handler. |
| 2 | `subkey` | `String` | An optional sub-field qualifier (e.g., "value", "state", "enable") that narrows the type lookup within a composite field. For example, the field "被紹介者契約者名" has three sub-keys: "value" (the name string), "enable" (a Boolean enabling/disabling the field), and "state" (a String status). When `null`, it is normalized to an empty string. |

**Instance fields read by this method:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `svc_kei_list_list` | `X33VDataTypeList` | Service contract detail list — a list of `KKW01037SF02DBean` items, each representing a service contract line item with its own type model. |
| `cust_kei_hktgi_list_list` | `X33VDataTypeList` | Customer contract handover list — a list of `KKW01037SF02DBean` items, each representing a customer contract being transferred. |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| - | `super.typeCommonInfoData` | X33VViewBaseBean | - | Delegates to parent class for common info view type resolution (X33V framework method) |
| - | `KKW01037SFBean.typeModelData` | KKW01037SFBean | - | Recursively calls `typeModelData` on list item beans (`X33VDataTypeBeanInterface`) for nested field type resolution in data-type view lists |
| - | `X33VDataTypeList.get` | X33VDataTypeList | - | Retrieves a list item at a given index from `svc_kei_list_list` or `cust_kei_hktgi_list_list` |

**Note:** This method performs **no database operations**. It is a pure type-routing utility that resolves data types from in-memory structures. All `substring`, `indexOf`, `Integer.valueOf`, and `equalsIgnoreCase` calls are standard Java string/integer operations on local variables and parameters.

## 5. Dependency Trace

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

No screen/batch entry points found within 8 hops. Direct callers found: 1 methods.
Terminal operations from this method: `typeModelData` [-], `typeModelData` [-], `substring` [-], `substring` [-], `substring` [-], `substring` [-], `substring` [-], `substring` [-], `substring` [-], `substring` [-], `substring` [-], `substring` [-], `substring` [-], `substring` [-], `typeModelData` [-], `typeModelData` [-], `substring` [-], `substring` [-], `substring` [-], `substring` [-]

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | KKW01037SFBean (self) | `KKW01037SFBean.typeModelData` (recursive delegation to list items) | `typeModelData` [R] In-memory type model metadata |

**Notes:**
- This method is called by itself recursively when resolving types for nested list item fields (e.g., `"サービス契約一覧リスト/0/fieldName"` delegates to the list item's `typeModelData`).
- The method is also invoked by the parent class's `typeCommonInfoData` for common info view paths (a separate call chain from `super`).
- The screen `KKSV0004` (Referral Information Inquiry) is associated with the KKW01037SF module but does not directly call `typeModelData` — it uses the X33V framework's data binding infrastructure which invokes this method internally.

## 6. Per-Branch Detail Blocks

### Block 1 — IF `(key == null)` (L880)

> If the key is null, return null immediately. This is a null-guard that prevents NPE on subsequent string operations.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return null;` // key is null, cannot resolve type |

### Block 2 — ELSE-IF `(subkey == null)` (L887)

> If the subkey is null, normalize it to an empty string so subsequent `equalsIgnoreCase` comparisons work consistently.

| # | Type | Code |
|---|------|------|
| 1 | SET | `subkey = new String("");` // normalize null subkey to empty string |

### Block 3 — IF `(separaterPoint == 0)` — Common Info View Delegation (L894)

> Check if the key starts with `"//"` which indicates a common info view. If so, delegate the entire type resolution to the parent class.

| # | Type | Code |
|---|------|------|
| 1 | SET | `String keyElement;` // local variable for key element extraction |
| 2 | SET | `int separaterPoint = key.indexOf("//");` // check if key is a common info view indicator |
| 3 | CALL | `return super.typeCommonInfoData(key);` // delegate to parent for common info view type resolution |

### Block 4 — Find first slash, extract keyElement (L901-L909)

> For non-common-info keys, find the first `"/"` separator to extract the top-level element name.

| # | Type | Code |
|---|------|------|
| 1 | SET | `separaterPoint = key.indexOf("/");` // search for separator "/" to split key |
| 2 | IF | `separaterPoint > 0` — Key contains a path separator |
| 3 | SET | `keyElement = key.substring(0, separaterPoint);` // extract element before first slash |

### Block 4.1 — ELSE (no slash found) (L907-L909)

| # | Type | Code |
|---|------|------|
| 1 | SET | `keyElement = key;` // entire key is the element name (no path) |

### Block 5 — Simple Type Field: 継続システムID (Continuation System ID) (L914-L925)

> Resolves the data type for the continuation system ID field. Has two sub-keys: "value" and "state", both return `String.class`.

| # | Type | Code |
|---|------|------|
| 1 | IF | `keyElement.equals("継続システムID")` — 継続システムID (continuation system ID, field ID: hktg_sysid) |
| 2 | IF (nested) | `subkey.equalsIgnoreCase("value")` — the actual value |
| 3 | RETURN | `return String.class;` |
| 4 | ELSE-IF (nested) | `subkey.equalsIgnoreCase("state")` — subkey is "state" -> returns status (状態) |
| 5 | RETURN | `return String.class;` |

### Block 6 — Simple Type Field: 継続お客様ID (Continuation Customer ID) (L928-L939)

> Resolves the data type for the continuation customer ID field. Has two sub-keys: "value" and "state", both return `String.class`.

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `keyElement.equals("継続お客様ID")` — 継続お客様ID (continuation customer ID, field ID: hktg_svc_kei_no) |
| 2 | IF (nested) | `subkey.equalsIgnoreCase("value")` — the actual value |
| 3 | RETURN | `return String.class;` |
| 4 | ELSE-IF (nested) | `subkey.equalsIgnoreCase("state")` — subkey is "state" -> returns status |
| 5 | RETURN | `return String.class;` |

### Block 7 — Simple Type Field: 被紹介者契約者名 (Referred Party Contract Name) (L942-L957)

> Resolves the data type for the referred party's contract name. Has three sub-keys: "value" (`String`), "enable" (`Boolean`), and "state" (`String`).

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `keyElement.equals("被紹介者契約者名")` — 被紹介者契約者名 (referred party contract name, field ID: hi_cust_nm) |
| 2 | IF (nested) | `subkey.equalsIgnoreCase("value")` |
| 3 | RETURN | `return String.class;` |
| 4 | ELSE-IF (nested) | `subkey.equalsIgnoreCase("enable")` — enable/disable flag |
| 5 | RETURN | `return Boolean.class;` |
| 6 | ELSE-IF (nested) | `subkey.equalsIgnoreCase("state")` — returns status |
| 7 | RETURN | `return String.class;` |

### Block 8 — Simple Type Field: 被紹介者電話番号 (Referred Party Phone Number) (L960-L975)

> Resolves the data type for the referred party's phone number. Has three sub-keys: "value" (`String`), "enable" (`Boolean`), and "state" (`String`).

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `keyElement.equals("被紹介者電話番号")` — 被紹介者電話番号 (referred party phone number, field ID: hi_telno) |
| 2 | IF (nested) | `subkey.equalsIgnoreCase("value")` |
| 3 | RETURN | `return String.class;` |
| 4 | ELSE-IF (nested) | `subkey.equalsIgnoreCase("enable")` |
| 5 | RETURN | `return Boolean.class;` |
| 6 | ELSE-IF (nested) | `subkey.equalsIgnoreCase("state")` — returns status |
| 7 | RETURN | `return String.class;` |

### Block 9 — Simple Type Field: 被紹介者システムID (Referred Party System ID) (L978-L993)

> Resolves the data type for the referred party's system ID. Has three sub-keys: "value" (`String`), "enable" (`Boolean`), and "state" (`String`).

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `keyElement.equals("被紹介者システムID")` — 被紹介者システムID (referred party system ID, field ID: hi_sysid) |
| 2 | IF (nested) | `subkey.equalsIgnoreCase("value")` |
| 3 | RETURN | `return String.class;` |
| 4 | ELSE-IF (nested) | `subkey.equalsIgnoreCase("enable")` |
| 5 | RETURN | `return Boolean.class;` |
| 6 | ELSE-IF (nested) | `subkey.equalsIgnoreCase("state")` — returns status |
| 7 | RETURN | `return String.class;` |

### Block 10 — Data-Type View List: サービス契約一覧リスト (Service Contract List) (L998-L1023)

> Resolves types for nested fields within the service contract list. The key format is `"サービス契約一覧リスト/<index>/<fieldName>"`. Supports wildcard index `"*"` to return `Integer.class` for list size queries.

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `keyElement.equals("サービス契約一覧リスト")` — サービス契約一覧リスト (service contract list, field ID: svc_kei_list) |
| 2 | SET | `String keyRemain = key.substring(separaterPoint + 1);` // extract everything after first "/" |
| 3 | IF | `keyRemain.equals("*")` — wildcard index requests list element count type |
| 4 | RETURN | `return Integer.class;` // list element count |
| 5 | SET | `separaterPoint = keyRemain.indexOf("/");` // find next separator |
| 6 | IF | `separaterPoint <= 0` — separator not found or invalid |
| 7 | RETURN | `return null;` // invalid key path |
| 8 | SET | `keyElement = keyRemain.substring(0, separaterPoint);` // extract index string |
| 9 | TRY | Parse index as integer |
| 10 | SET | `tmpIndexInt = Integer.valueOf(keyElement);` |
| 11 | CATCH | `NumberFormatException e` — index is not a numeric string |
| 12 | RETURN | `return null;` // invalid index |
| 13 | IF | `tmpIndexInt == null` |
| 14 | RETURN | `return null;` |
| 15 | SET | `int tmpIndex = tmpIndexInt.intValue();` |
| 16 | IF | `tmpIndex < 0 \|\| tmpIndex >= svc_kei_list_list.size()` — out-of-bounds index check |
| 17 | RETURN | `return null;` // index exceeds list count - 1 |
| 18 | SET | `keyElement = keyRemain.substring(separaterPoint + 1);` // extract nested field name |
| 19 | CALL | `((X33VDataTypeBeanInterface)svc_kei_list_list.get(tmpIndex)).typeModelData(keyElement, subkey);` // delegate to list item bean for nested type resolution |

### Block 11 — Data-Type View List: 顧客契約引継リスト (Customer Contract Handover List) (L1028-L1053)

> Resolves types for nested fields within the customer contract handover list. The key format is `"顧客契約引継リスト/<index>/<fieldName>"`. Follows the same pattern as Block 10 but operates on `cust_kei_hktgi_list_list`.

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `keyElement.equals("顧客契約引継リスト")` — 顧客契約引継リスト (customer contract handover list, field ID: cust_kei_hktgi_list) |
| 2 | SET | `String keyRemain = key.substring(separaterPoint + 1);` // extract everything after first "/" |
| 3 | IF | `keyRemain.equals("*")` — wildcard index requests list element count type |
| 4 | RETURN | `return Integer.class;` // list element count |
| 5 | SET | `separaterPoint = keyRemain.indexOf("/");` // find next separator |
| 6 | IF | `separaterPoint <= 0` — separator not found or invalid |
| 7 | RETURN | `return null;` // invalid key path |
| 8 | SET | `keyElement = keyRemain.substring(0, separaterPoint);` // extract index string |
| 9 | TRY | Parse index as integer |
| 10 | SET | `tmpIndexInt = Integer.valueOf(keyElement);` |
| 11 | CATCH | `NumberFormatException e` — index is not a numeric string |
| 12 | RETURN | `return null;` // invalid index |
| 13 | IF | `tmpIndexInt == null` |
| 14 | RETURN | `return null;` |
| 15 | SET | `int tmpIndex = tmpIndexInt.intValue();` |
| 16 | IF | `tmpIndex < 0 \|\| tmpIndex >= cust_kei_hktgi_list_list.size()` — out-of-bounds index check |
| 17 | RETURN | `return null;` // index exceeds list count - 1 |
| 18 | SET | `keyElement = keyRemain.substring(separaterPoint + 1);` // extract nested field name |
| 19 | CALL | `((X33VDataTypeBeanInterface)cust_kei_hktgi_list_list.get(tmpIndex)).typeModelData(keyElement, subkey);` // delegate to list item bean for nested type resolution |

### Block 12 — Simple Type Field: ポップアップモード (Popup Mode) (L1056-L1066)

> Resolves the data type for the popup mode field. Has two sub-keys: "value" and "state", both return `String.class`.

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `keyElement.equals("ポップアップモード")` — ポップアップモード (popup mode, field ID: popup_mode) |
| 2 | IF (nested) | `subkey.equalsIgnoreCase("value")` |
| 3 | RETURN | `return String.class;` |
| 4 | ELSE-IF (nested) | `subkey.equalsIgnoreCase("state")` — returns status |
| 5 | RETURN | `return String.class;` |

### Block 13 — Default (Fall-through) (L1069)

> If none of the known key elements matched, return null.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return null;` // unrecognized keyElement |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `hktg_sysid` | Field | Continuation System ID — internal system identifier that persists across customer contract renewals |
| `hktg_sysid_value` | Field | The actual value of the continuation system ID (String) |
| `hktg_sysid_state` | Field | UI state flag for the continuation system ID field (String) |
| `hktg_svc_kei_no` | Field | Continuation Customer ID — internal customer identifier that persists across contract renewals |
| `hktg_svc_kei_no_value` | Field | The actual value of the continuation customer ID (String) |
| `hi_cust_nm` | Field | Referred Party Contract Name — name of the contract party introduced via referral (被紹介者契約者名) |
| `hi_cust_nm_value` | Field | The contract party's name value (String) |
| `hi_cust_nm_enabled` | Field | Whether the referred party name field is enabled for editing (Boolean) |
| `hi_telno` | Field | Referred Party Phone Number — phone number of the referred party (被紹介者電話番号) |
| `hi_telno_value` | Field | The phone number value (String) |
| `hi_telno_enabled` | Field | Whether the referred party phone number field is enabled (Boolean, default true) |
| `hi_sysid` | Field | Referred Party System ID — system ID for the referred party (被紹介者システムID) |
| `svc_kei_list` | Field | Service Contract List — a list of service contract detail line items (サービス契約一覧リスト), each typed as `KKW01037SF02DBean` |
| `svc_kei_list_list` | Field | In-memory `X33VDataTypeList` holding the service contract list beans |
| `cust_kei_hktgi_list` | Field | Customer Contract Handover List — list of customer contracts being transferred (顧客契約引継リスト), each typed as `KKW01037SF02DBean` |
| `cust_kei_hktgi_list_list` | Field | In-memory `X33VDataTypeList` holding the customer contract handover list beans |
| `popup_mode` | Field | Popup Mode — controls which popup dialog mode is active (ポップアップモード) |
| 継続システムID | Japanese | Continuation System ID — system identifier that persists when a customer's contract is renewed/continued |
| 継続お客様ID | Japanese | Continuation Customer ID — customer identifier that persists across contract renewals |
| 被紹介者契約者名 | Japanese | Referred Party Contract Name — name of the contract party who was introduced via a referral |
| 被紹介者電話番号 | Japanese | Referred Party Phone Number — phone number of the referred party |
| 被紹介者システムID | Japanese | Referred Party System ID — system ID assigned to the referred party |
| サービス契約一覧リスト | Japanese | Service Contract List — composite field holding multiple service contract detail items |
| 顧客契約引継リスト | Japanese | Customer Contract Handover List — composite field holding contracts being handed over (e.g., upon renewal or transfer) |
| ポップアップモード | Japanese | Popup Mode — controls popup dialog behavior on the screen |
| 紹介情報照会 | Japanese | Referral Information Inquiry — the screen purpose (KKW01037), displays information about customer referrals |
| X33VDataTypeList | Type | X33V framework list container that holds `X33VDataTypeBeanInterface` items with type metadata |
| X33VDataTypeBeanInterface | Type | Interface implemented by list item beans that provides `typeModelData` for nested field type resolution |
| X33VViewBaseBean | Type | Parent class of KKW01037SFBean; provides `typeCommonInfoData` for common info view delegation |
