# Business Logic — KKW01601SF01DBean.typeModelData() [160 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.web.webview.KKA15301SF.KKW01601SF01DBean` |
| Layer | Utility / Web Bean (View-layer data type resolver) |
| Module | `KKA15301SF` (Package: `eo.web.webview.KKA15301SF`) |

## 1. Role

### KKW01601SF01DBean.typeModelData()

This method serves as the **data type metadata router** for the KKA15301SF screen's web bean. It determines the Java type of any given field within the screen's data model based on a hierarchical key structure — resolving the type for simple scalar fields (like code-type code, code-type name, selection index, and initial setup code) as well as for indexed list fields (code-type code value list, code-type name list, and credit exchange code list).

The method implements a **dispatch/routing design pattern**: it receives a dot-separated key string (e.g., "初期設定コード/0") and a subkey (e.g., "value", "enable", "state"), then dispatches to the appropriate branch based on the field category. For scalar fields, it returns a `Class<?>` representing the data type (`String.class`, `Boolean.class`, or `Integer.class`). For list fields, it extracts the list index from the key, validates bounds, retrieves the corresponding bean from the list, and delegates the subkey resolution to that bean's own `typeModelData()` method.

It plays a **shared utility role** within the screen's data-binding framework — likely called by the X33 web framework to determine field metadata for dynamic form rendering, validation, and data access. The method handles 7 distinct field categories, including 4 simple string-type fields and 3 array-type (list) fields, each supporting subkeys "value", "enable", and "state".

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["typeModelData key, subkey"])
    COND_NULL["key == null or subkey == null"]
    RET_NULL(["return null"])
    FIND_SEP["int separaterPoint = key.indexOf('/')"]

    COND_K1["key equals コードタイプコード"]
    SUB1["subkey.equalsIgnoreCase('value')"]
    RET_S1["return String.class"]
    SUB2["subkey.equalsIgnoreCase('enable')"]
    RET_B1["return Boolean.class"]
    SUB3["subkey.equalsIgnoreCase('state')"]
    RET_S2["return String.class (status)"]

    COND_K2["key equals コードタイプ名称"]
    SUB4["subkey.equalsIgnoreCase('value')"]
    RET_S3["return String.class"]
    SUB5["subkey.equalsIgnoreCase('enable')"]
    RET_B2["return Boolean.class"]
    SUB6["subkey.equalsIgnoreCase('state')"]
    RET_S4["return String.class (status)"]

    COND_K3["key equals 選択インデックス"]
    SUB7["subkey.equalsIgnoreCase('value')"]
    RET_S5["return String.class"]
    SUB8["subkey.equalsIgnoreCase('enable')"]
    RET_B3["return Boolean.class"]
    SUB9["subkey.equalsIgnoreCase('state')"]
    RET_S6["return String.class (status)"]

    COND_K4["key equals 初期設定コード"]
    PARSE_IDX1["key = key.substring(separaterPoint+1)"]
    CHECK_ASTERISK1["key equals '*'"]
    RET_COUNT1["return Integer.class (list count)"]
    PARSE_INT1["Integer tmpIndexInt = Integer.valueOf(key)"]
    CATCH_NFE1["NumberFormatException → return null"]
    CHECK_BOUNDS1["tmpIndex < 0 or >= default_cd_list.size()"]
    RET_NULL1["return null"]
    CALL_DM1["((X33VDataTypeStringBean)default_cd_list.get(tmpIndex)).typeModelData(subkey)"]

    COND_K5["key equals コードタイプコード値リスト"]
    PARSE_IDX2["key = key.substring(separaterPoint+1)"]
    CHECK_ASTERISK2["key equals '*'"]
    RET_COUNT2["return Integer.class (list count)"]
    PARSE_INT2["Integer tmpIndexInt = Integer.valueOf(key)"]
    CATCH_NFE2["NumberFormatException → return null"]
    CHECK_BOUNDS2["tmpIndex < 0 or >= cd_div_cd_list_list.size()"]
    RET_NULL2["return null"]
    CALL_DM2["((X33VDataTypeStringBean)cd_div_cd_list_list.get(tmpIndex)).typeModelData(subkey)"]

    COND_K6["key equals コードタイプ名称リスト"]
    PARSE_IDX3["key = key.substring(separaterPoint+1)"]
    CHECK_ASTERISK3["key equals '*'"]
    RET_COUNT3["return Integer.class (list count)"]
    PARSE_INT3["Integer tmpIndexInt = Integer.valueOf(key)"]
    CATCH_NFE3["NumberFormatException → return null"]
    CHECK_BOUNDS3["tmpIndex < 0 or >= cd_div_nm_list_list.size()"]
    RET_NULL3["return null"]
    CALL_DM3["((X33VDataTypeStringBean)cd_div_nm_list_list.get(tmpIndex)).typeModelData(subkey)"]

    COND_K7["key equals クレジット交換コード"]
    PARSE_IDX4["key = key.substring(separaterPoint+1)"]
    CHECK_ASTERISK4["key equals '*'"]
    RET_COUNT4["return Integer.class (list count)"]
    PARSE_INT4["Integer tmpIndexInt = Integer.valueOf(key)"]
    CATCH_NFE4["NumberFormatException → return null"]
    CHECK_BOUNDS4["tmpIndex < 0 or >= credit_kokan_cd_list.size()"]
    RET_NULL4["return null"]
    CALL_DM4["((X33VDataTypeStringBean)credit_kokan_cd_list.get(tmpIndex)).typeModelData(subkey)"]

    RET_DEFAULT["return null (no match)"]
    END_FLOW(["END"])

    START --> COND_NULL
    COND_NULL -- true --> RET_NULL --> END_FLOW
    COND_NULL -- false --> FIND_SEP

    FIND_SEP --> COND_K1
    COND_K1 -- true --> SUB1
    SUB1 -- true --> RET_S1 --> END_FLOW
    SUB1 -- false --> SUB2
    SUB2 -- true --> RET_B1 --> END_FLOW
    SUB2 -- false --> SUB3
    SUB3 -- true --> RET_S2 --> END_FLOW
    SUB3 -- false --> COND_K2

    COND_K2 -- true --> SUB4
    SUB4 -- true --> RET_S3 --> END_FLOW
    SUB4 -- false --> SUB5
    SUB5 -- true --> RET_B2 --> END_FLOW
    SUB5 -- false --> SUB6
    SUB6 -- true --> RET_S4 --> END_FLOW
    SUB6 -- false --> COND_K3

    COND_K3 -- true --> SUB7
    SUB7 -- true --> RET_S5 --> END_FLOW
    SUB7 -- false --> SUB8
    SUB8 -- true --> RET_B3 --> END_FLOW
    SUB8 -- false --> SUB9
    SUB9 -- true --> RET_S6 --> END_FLOW
    SUB9 -- false --> COND_K4

    COND_K4 -- true --> PARSE_IDX1
    PARSE_IDX1 --> CHECK_ASTERISK1
    CHECK_ASTERISK1 -- true --> RET_COUNT1 --> END_FLOW
    CHECK_ASTERISK1 -- false --> PARSE_INT1
    PARSE_INT1 --> CATCH_NFE1
    CATCH_NFE1 --> RET_NULL1 --> END_FLOW
    RET_NULL1 --> CHECK_BOUNDS1
    CHECK_BOUNDS1 -- out of bounds --> RET_NULL1
    CHECK_BOUNDS1 -- valid index --> CALL_DM1 --> END_FLOW

    COND_K5 -- true --> PARSE_IDX2
    PARSE_IDX2 --> CHECK_ASTERISK2
    CHECK_ASTERISK2 -- true --> RET_COUNT2 --> END_FLOW
    CHECK_ASTERISK2 -- false --> PARSE_INT2
    PARSE_INT2 --> CATCH_NFE2
    CATCH_NFE2 --> RET_NULL2 --> END_FLOW
    RET_NULL2 --> CHECK_BOUNDS2
    CHECK_BOUNDS2 -- out of bounds --> RET_NULL2
    CHECK_BOUNDS2 -- valid index --> CALL_DM2 --> END_FLOW

    COND_K6 -- true --> PARSE_IDX3
    PARSE_IDX3 --> CHECK_ASTERISK3
    CHECK_ASTERISK3 -- true --> RET_COUNT3 --> END_FLOW
    CHECK_ASTERISK3 -- false --> PARSE_INT3
    PARSE_INT3 --> CATCH_NFE3
    CATCH_NFE3 --> RET_NULL3 --> END_FLOW
    RET_NULL3 --> CHECK_BOUNDS3
    CHECK_BOUNDS3 -- out of bounds --> RET_NULL3
    CHECK_BOUNDS3 -- valid index --> CALL_DM3 --> END_FLOW

    COND_K7 -- true --> PARSE_IDX4
    PARSE_IDX4 --> CHECK_ASTERISK4
    CHECK_ASTERISK4 -- true --> RET_COUNT4 --> END_FLOW
    CHECK_ASTERISK4 -- false --> PARSE_INT4
    PARSE_INT4 --> CATCH_NFE4
    CATCH_NFE4 --> RET_NULL4 --> END_FLOW
    RET_NULL4 --> CHECK_BOUNDS4
    CHECK_BOUNDS4 -- out of bounds --> RET_NULL4
    CHECK_BOUNDS4 -- valid index --> CALL_DM4 --> END_FLOW

    COND_K7 -- false --> RET_DEFAULT --> END_FLOW
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `key` | `String` | The hierarchical field identifier that specifies both the data category and (for list fields) the list index. Format varies by category: simple keys use the field name directly (e.g., "コードタイプコード"), while list fields use "fieldName/index" syntax (e.g., "初期設定コード/0"). Determines which data type branch to dispatch to. |
| 2 | `subkey` | `String` | The property descriptor within the matched field. Expected values include "value" (the actual data value type), "enable" (the editable state type), and "state" (the display status type). The subkey determines which `Class<?>` is returned for scalar fields. |

**Instance fields read by this method:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `default_cd_list` | `X33VDataTypeList` | List of initial setup code items — contains beans for configurable default code entries |
| `cd_div_cd_list_list` | `X33VDataTypeList` | List of code-type code value items — contains beans for a list of code-type code entries |
| `cd_div_nm_list_list` | `X33VDataTypeList` | List of code-type name items — contains beans for a list of code-type name entries |
| `credit_kokan_cd_list` | `X33VDataTypeList` | List of credit exchange code items — contains beans for a list of credit exchange code entries |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| - | `KKW01601SF01DBean.typeModelData` | KKW01601SF01DBean | - | Calls `typeModelData` in `KKW01601SF01DBean` |

This method is a **pure metadata resolver** — it performs no database operations, no SC/CBS calls, and no create/read/update/delete actions. It operates entirely on in-memory list data (instance fields holding `X33VDataTypeStringBean` objects) and returns `Class<?>` type descriptors. The only method calls it performs are:

| Method | Type | Description |
|--------|------|-------------|
| `X33VDataTypeStringBean.typeModelData(String)` | Self-delegation | Delegates subkey type resolution to the retrieved list element's own `typeModelData()` method (lines 738, 765, 792, 819). The element is cast to `X33VDataTypeStringBean` before the call. |

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | — | — | No external callers found. Method is self-referential (delegates to X33VDataTypeStringBean). |

Note: This method is called internally within the X33 web framework's data-binding mechanism. The pre-extracted caller list shows the method only appears as a self-reference (it delegates to `typeModelData()` on list element beans).

## 6. Per-Branch Detail Blocks

**Block 1** — IF (null guard) (L625)

> Validates that both input parameters are non-null. If either is null, returns null immediately.

| # | Type | Code |
|---|------|------|
| 1 | SET | `int separaterPoint = key.indexOf("/")` // Extract first slash position for list key parsing |
| 2 | RETURN | `return null` // key or subkey is null — no type information available |

**Block 2** — IF/ELSE-IF/ELSE (コードタイプコード — Code-Type Code) (L630)

> The "コードタイプコード" (code-type code) field is a simple string-type field identified by item ID `cd_div_cd`. It resolves the type based on the subkey.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (subkey.equalsIgnoreCase("value"))` // subkey is "value" → data value |
| 2 | RETURN | `return String.class` // The code value is stored as a string |
| 3 | ELSE-IF | `else if (subkey.equalsIgnoreCase("enable"))` // subkey is "enable" → editability flag |
| 4 | RETURN | `return Boolean.class` // The enable flag is a boolean |
| 5 | ELSE-IF | `else if (subkey.equalsIgnoreCase("state"))` // subkey is "state" → status (ステータス) |
| 6 | RETURN | `return String.class` // The status is stored as a string |

**Block 3** — ELSE-IF (コードタイプ名称 — Code-Type Name) (L643)

> The "コードタイプ名称" (code-type name) field is a simple string-type field identified by item ID `cd_div_nm`. Same subkey resolution as Block 2.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (subkey.equalsIgnoreCase("value"))` // subkey is "value" → data value |
| 2 | RETURN | `return String.class` // The code name is stored as a string |
| 3 | ELSE-IF | `else if (subkey.equalsIgnoreCase("enable"))` // subkey is "enable" → editability flag |
| 4 | RETURN | `return Boolean.class` // The enable flag is a boolean |
| 5 | ELSE-IF | `else if (subkey.equalsIgnoreCase("state"))` // subkey is "state" → status (ステータス) |
| 6 | RETURN | `return String.class` // The status is stored as a string |

**Block 4** — ELSE-IF (選択インデックス — Selection Index) (L656)

> The "選択インデックス" (selection index) field is a simple string-type field identified by item ID `select_index`. Same subkey resolution as Block 2 and Block 3.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if (subkey.equalsIgnoreCase("value"))` // subkey is "value" → data value |
| 2 | RETURN | `return String.class` // The selection index value is a string |
| 3 | ELSE-IF | `else if (subkey.equalsIgnoreCase("enable"))` // subkey is "enable" → editability flag |
| 4 | RETURN | `return Boolean.class` // The enable flag is a boolean |
| 5 | ELSE-IF | `else if (subkey.equalsIgnoreCase("state"))` // subkey is "state" → status (ステータス) |
| 6 | RETURN | `return String.class` // The status is stored as a string |

**Block 5** — ELSE-IF (初期設定コード — Initial Setup Code, list type) (L669)

> The "初期設定コード" (initial setup code) is a list field identified by item ID `default_cd`. The key must contain a "/" separator; the part after "/" is parsed as either a wildcard "*" (returning the list count type) or a numeric index (returning the element's type via delegation).

| # | Type | Code |
|---|------|------|
| 1 | SET | `key = key.substring(separaterPoint + 1)` // Extract part after "/" from key (e.g., "0" from "初期設定コード/0") |
| 2 | IF | `if (key.equals("*"))` // Wildcard: request list count type |
| 3 | RETURN | `return Integer.class` // The list count is an integer |
| 4 | ELSE | // Parse key as numeric index |
| 5 | SET | `Integer tmpIndexInt = null` |
| 6 | SET | `tmpIndexInt = Integer.valueOf(key)` // Parse index from string |
| 7 | CATCH | `catch (NumberFormatException e)` // Index is not a valid numeric string |
| 8 | RETURN | `return null` // Return null for non-numeric index |
| 9 | IF | `if (tmpIndexInt == null)` // Guard against null after parsing |
| 10 | RETURN | `return null` |
| 11 | SET | `int tmpIndex = tmpIndexInt.intValue()` |
| 12 | IF | `if (tmpIndex < 0 || tmpIndex >= default_cd_list.size())` // Index out of bounds |
| 13 | RETURN | `return null` // Return null for out-of-bounds index |
| 14 | CALL | `((X33VDataTypeStringBean)default_cd_list.get(tmpIndex)).typeModelData(subkey)` // Delegate to the list element's typeModelData() |

**Block 6** — ELSE-IF (コードタイプコード値リスト — Code-Type Code Value List, list type) (L701)

> The "コードタイプコード値リスト" (code-type code value list) is a list field identified by item ID `cd_div_cd_list`. Same parsing logic as Block 5, operating on `cd_div_cd_list_list`.

| # | Type | Code |
|---|------|------|
| 1 | SET | `key = key.substring(separaterPoint + 1)` // Extract part after "/" (e.g., "0" from "コードタイプコード値リスト/0") |
| 2 | IF | `if (key.equals("*"))` // Wildcard: request list count type |
| 3 | RETURN | `return Integer.class` // The list count is an integer |
| 4 | ELSE | // Parse key as numeric index |
| 5 | SET | `Integer tmpIndexInt = null` |
| 6 | SET | `tmpIndexInt = Integer.valueOf(key)` // Parse index from string |
| 7 | CATCH | `catch (NumberFormatException e)` // Index is not a valid numeric string |
| 8 | RETURN | `return null` // Return null for non-numeric index |
| 9 | IF | `if (tmpIndexInt == null)` // Guard against null after parsing |
| 10 | RETURN | `return null` |
| 11 | SET | `int tmpIndex = tmpIndexInt.intValue()` |
| 12 | IF | `if (tmpIndex < 0 || tmpIndex >= cd_div_cd_list_list.size())` // Index out of bounds |
| 13 | RETURN | `return null` // Return null for out-of-bounds index |
| 14 | CALL | `((X33VDataTypeStringBean)cd_div_cd_list_list.get(tmpIndex)).typeModelData(subkey)` // Delegate to list element |

**Block 7** — ELSE-IF (コードタイプ名称リスト — Code-Type Name List, list type) (L728)

> The "コードタイプ名称リスト" (code-type name list) is a list field identified by item ID `cd_div_nm_list`. Same parsing logic, operating on `cd_div_nm_list_list`.

| # | Type | Code |
|---|------|------|
| 1 | SET | `key = key.substring(separaterPoint + 1)` // Extract part after "/" (e.g., "0" from "コードタイプ名称リスト/0") |
| 2 | IF | `if (key.equals("*"))` // Wildcard: request list count type |
| 3 | RETURN | `return Integer.class` // The list count is an integer |
| 4 | ELSE | // Parse key as numeric index |
| 5 | SET | `Integer tmpIndexInt = null` |
| 6 | SET | `tmpIndexInt = Integer.valueOf(key)` // Parse index from string |
| 7 | CATCH | `catch (NumberFormatException e)` // Index is not a valid numeric string |
| 8 | RETURN | `return null` // Return null for non-numeric index |
| 9 | IF | `if (tmpIndexInt == null)` // Guard against null after parsing |
| 10 | RETURN | `return null` |
| 11 | SET | `int tmpIndex = tmpIndexInt.intValue()` |
| 12 | IF | `if (tmpIndex < 0 || tmpIndex >= cd_div_nm_list_list.size())` // Index out of bounds |
| 13 | RETURN | `return null` // Return null for out-of-bounds index |
| 14 | CALL | `((X33VDataTypeStringBean)cd_div_nm_list_list.get(tmpIndex)).typeModelData(subkey)` // Delegate to list element |

**Block 8** — ELSE-IF (クレジット交換コード — Credit Exchange Code, list type) (L755)

> The "クレジット交換コード" (credit exchange code) is a list field identified by item ID `credit_kokan_cd`. Same parsing logic, operating on `credit_kokan_cd_list`.

| # | Type | Code |
|---|------|------|
| 1 | SET | `key = key.substring(separaterPoint + 1)` // Extract part after "/" (e.g., "0" from "クレジット交換コード/0") |
| 2 | IF | `if (key.equals("*"))` // Wildcard: request list count type |
| 3 | RETURN | `return Integer.class` // The list count is an integer |
| 4 | ELSE | // Parse key as numeric index |
| 5 | SET | `Integer tmpIndexInt = null` |
| 6 | SET | `tmpIndexInt = Integer.valueOf(key)` // Parse index from string |
| 7 | CATCH | `catch (NumberFormatException e)` // Index is not a valid numeric string |
| 8 | RETURN | `return null` // Return null for non-numeric index |
| 9 | IF | `if (tmpIndexInt == null)` // Guard against null after parsing |
| 10 | RETURN | `return null` |
| 11 | SET | `int tmpIndex = tmpIndexInt.intValue()` |
| 12 | IF | `if (tmpIndex < 0 || tmpIndex >= credit_kokan_cd_list.size())` // Index out of bounds |
| 13 | RETURN | `return null` // Return null for out-of-bounds index |
| 14 | CALL | `((X33VDataTypeStringBean)credit_kokan_cd_list.get(tmpIndex)).typeModelData(subkey)` // Delegate to list element |

**Block 9** — ELSE (no match) (L782)

> No field category matched the provided key. Return null to indicate no type metadata exists for this key.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return null` // No matching property found — return null |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `key` | Parameter | Hierarchical field identifier — specifies the data category (e.g., code-type, initial setup, credit exchange) and optionally a list index in "category/index" format |
| `subkey` | Parameter | Property descriptor within a field — one of "value" (data content), "enable" (editable flag), or "state" (display status) |
| コードタイプコード | Field | Code-Type Code — the classification code for a code type (item ID: `cd_div_cd`) |
| コードタイプ名称 | Field | Code-Type Name — the display name of a code type (item ID: `cd_div_nm`) |
| 選択インデックス | Field | Selection Index — the currently selected index in a selection component (item ID: `select_index`) |
| 初期設定コード | Field | Initial Setup Code — configurable default code entries (item ID: `default_cd`), stored as a list |
| コードタイプコード値リスト | Field | Code-Type Code Value List — a list of code-type code value entries (item ID: `cd_div_cd_list`) |
| コードタイプ名称リスト | Field | Code-Type Name List — a list of code-type name entries (item ID: `cd_div_nm_list`) |
| クレジット交換コード | Field | Credit Exchange Code — credit exchange code entries (item ID: `credit_kokan_cd`), stored as a list |
| `X33VDataTypeStringBean` | Class | X33 Framework bean — a generic data type bean representing a string data field, providing `typeModelData()`, `loadModelData()`, and `storeModelData()` methods for data binding |
| `X33VDataTypeList` | Class | X33 Framework list — a list container holding `X33VDataTypeStringBean` items, used for array-type fields |
| status (ステータス) | Property | Display status of a form field — managed as a String type |
| enable (有効フラグ) | Property | Editable flag — indicates whether a form field is enabled for user input, managed as a Boolean type |
| value (値) | Property | The actual data value of a field — managed as a String type |
