# Business Logic — KKW01021SF01DBean.typeModelData() [100 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `eo.web.webview.KKW01021SF.KKW01021SF01DBean` |
| Layer | Utility / Data-Binding (Web WebView package implementing X33V framework interfaces) |
| Module | `KKW01021SF` (Package: `eo.web.webview.KKW01021SF`) |

## 1. Role

### KKW01021SF01DBean.typeModelData()

This method serves as a **data type resolver** within the X33V web framework's data-binding layer. It is part of the `X33VDataTypeBeanInterface` contract, enabling the framework to dynamically determine the Java type of each field on a WebView screen during model initialization and data binding. The method implements a routing/dispatch pattern: based on a `key` (the business field name) and `subkey` (the field's property, such as `"value"` or `"state"`), it returns the corresponding `Class<?>` type that the framework uses to instantiate or validate form-bound data.

The method handles seven distinct business fields: "SYSID" (system ID), "サービス契約番号" (Service Contract Number), "異動区分" (Movement Classification), "異動理由コード" (Movement Reason Code — a compound indexed field with list semantics), "異動理由メモ" (Movement Reason Memo), "申請番号" (Application Number), and "申請詳細番号" (Application Detail Number). Most fields consistently return `String.class` for both `"value"` and `"state"` subkeys. The "異動理由コード" field is the most complex: it supports an asterisk (`"*"`) subkey to return `Integer.class` (for list count), resolves numeric string indices to access individual list items, and delegates to `X33VDataTypeStringBean.typeModelData()` for per-item type resolution. This enables the framework to correctly render and validate multi-value list fields for movement reasons.

## 2. Processing Pattern (Detailed Business Logic)

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

    START --> CHECK_NULL["key == null || subkey == null"]
    CHECK_NULL -->|true| NULL_RETURN["return null"]
    CHECK_NULL -->|false| FIND_SLASH["separaterPoint = key.indexOf('/')"]

    FIND_SLASH --> BR1["key equals SYSID"]
    BR1 -->|true| BR1_SUB["Check subkey"]
    BR1_SUB --> BR1_V["subkey equalsIgnoreCase value"]
    BR1_V -->|true| BR1_V_RET["return String.class"]
    BR1_SUB --> BR1_S["subkey equalsIgnoreCase state"]
    BR1_S -->|true| BR1_S_RET["return String.class"]
    BR1 -->|false| BR2["key equals サービス契約番号"]
    BR2 -->|true| BR2_SUB["Check subkey"]
    BR2_SUB --> BR2_V["subkey equalsIgnoreCase value"]
    BR2_V -->|true| BR2_V_RET["return String.class"]
    BR2_SUB --> BR2_S["subkey equalsIgnoreCase state"]
    BR2_S -->|true| BR2_S_RET["return String.class"]
    BR2 -->|false| BR3["key equals 異動区分"]
    BR3 -->|true| BR3_SUB["Check subkey"]
    BR3_SUB --> BR3_V["subkey equalsIgnoreCase value"]
    BR3_V -->|true| BR3_V_RET["return String.class"]
    BR3_SUB --> BR3_S["subkey equalsIgnoreCase state"]
    BR3_S -->|true| BR3_S_RET["return String.class"]
    BR3 -->|false| BR4["key equals 異動理由コード"]
    BR4 -->|true| BR4_SUB["Process ido_rsn_cd branch"]
    BR4_SUB --> BR4_SLICE["key = key.substring(separaterPoint + 1)"]
    BR4_SLICE --> BR4_ASTERISK["key equals '*'"]
    BR4_ASTERISK -->|true| BR4_A_RET["return Integer.class"]
    BR4_ASTERISK -->|false| BR4_PARSE["Integer.valueOf(key)"]
    BR4_PARSE --> BR4_CATCH["NumberFormatException caught?"]
    BR4_CATCH -->|true| BR4_CATCH_RET["return null"]
    BR4_CATCH -->|false| BR4_NULL["tmpIndexInt == null"]
    BR4_NULL -->|true| BR4_NULL_RET["return null"]
    BR4_NULL -->|false| BR4_BOUNDS["tmpIndex < 0 or >= list.size()"]
    BR4_BOUNDS -->|true| BR4_B_RET["return null"]
    BR4_BOUNDS -->|false| BR4_DELEGATE["X33VDataTypeStringBean.typeModelData(subkey)"]
    BR4_DELEGATE --> BR4_D_RET["return delegated result"]
    BR4 -->|false| BR5["key equals 異動理由メモ"]
    BR5 -->|true| BR5_SUB["Check subkey"]
    BR5_SUB --> BR5_V["subkey equalsIgnoreCase value"]
    BR5_V -->|true| BR5_V_RET["return String.class"]
    BR5_SUB --> BR5_S["subkey equalsIgnoreCase state"]
    BR5_S -->|true| BR5_S_RET["return String.class"]
    BR5 -->|false| BR6["key equals 申請番号"]
    BR6 -->|true| BR6_SUB["Check subkey"]
    BR6_SUB --> BR6_V["subkey equalsIgnoreCase value"]
    BR6_V -->|true| BR6_V_RET["return String.class"]
    BR6_SUB --> BR6_S["subkey equalsIgnoreCase state"]
    BR6_S -->|true| BR6_S_RET["return String.class"]
    BR6 -->|false| BR7["key equals 申請詳細番号"]
    BR7 -->|true| BR7_SUB["Check subkey"]
    BR7_SUB --> BR7_V["subkey equalsIgnoreCase value"]
    BR7_V -->|true| BR7_V_RET["return String.class"]
    BR7_SUB --> BR7_S["subkey equalsIgnoreCase state"]
    BR7_S -->|true| BR7_S_RET["return String.class"]
    BR7 -->|false| FALLBACK["return null"]
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| 1 | `key` | `String` | The business field identifier (項目名) used to select which data type resolver branch applies. Can be a simple field name (e.g., `"SYSID"`, `"サービス契約番号"`) or a compound identifier using the format `"<fieldName>/<index>"` (e.g., `"異動理由コード/0"`, `"異動理由コード/*"`). The presence and position of the `/` separator determines how compound keys are parsed. |
| 2 | `subkey` | `String` | The property selector within the identified field. For simple fields, it is `"value"` (to resolve the data value type) or `"state"` (to resolve the status/state metadata type). For the compound "異動理由コード" field, it is forwarded to the individual `X33VDataTypeStringBean` instance for per-item resolution. Case-insensitive comparison (`equalsIgnoreCase`) is used. |

**Instance fields / external state read:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `ido_rsn_cd_list` | `X33VDataTypeList` | A list of movement reason code data beans (`X33VDataTypeStringBean`), holding the multi-value entries for the "異動理由コード" field. Accessed via `size()` and `get()` to validate and resolve indexed items. |

## 4. CRUD Operations / Called Services

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

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| - | `X33VDataTypeStringBean.typeModelData` | X33VDataTypeStringBean | - | Delegates type resolution for an individual movement reason code list item. The element at `ido_rsn_cd_list.get(tmpIndex)` is cast to `X33VDataTypeStringBean` and its `typeModelData(subkey)` is called. |
| - | `KKW01021SF01DBean.typeModelData` | KKW01021SF01DBean | - | Self-referencing (recursive pattern) — the method resolves types for fields that themselves contain nested type model data. |

**CRUD Classification:** This method performs no Create, Read, Update, or Delete operations against entities or databases. It is a pure type-resolution utility — a stateless routing mechanism that maps field identifiers to Java types. It reads the `ido_rsn_cd_list` instance field (an in-memory collection) for list-bound resolution, but this is not a database operation.

## 5. Dependency Trace

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Class: `KKW01021SF01DBean` | `KKW01021SF01DBean.typeModelData` (self-reference for indexed list items) | `X33VDataTypeStringBean.typeModelData [R] in-memory list` |

**Notes:** The pre-computed call graph shows this method is called by the `KKW01021SF01DBean` class itself (self-reference from the indexed "異動理由コード" branch). As an X33V framework method implementing `X33VDataTypeBeanInterface`, this method is typically invoked by the X33V framework's internal model-loading mechanism — not by explicit callers in application code. The framework calls `typeModelData()` during screen initialization to determine how to instantiate and bind each field's data type.

## 6. Per-Branch Detail Blocks

### Block 1 — IF (null guard) (L505)

Guard clause: returns `null` if either parameter is null. This is the entry point's safety check.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if(key == null || subkey == null)` |
| 2 | RETURN | `return null;` // key,subkeyがnullの場合、nullを返す — Return null if key or subkey is null |

---

### Block 2 — SET (slash separator detection) (L510)

Locate the `/` separator position in `key` for potential compound key parsing (used by the "異動理由コード" branch).

| # | Type | Code |
|---|------|------|
| 1 | SET | `int separaterPoint = key.indexOf("/");` // Find position of the "/" separator in key |

---

### Block 3 — IF-ELSE-IF (SYSID field) (L513)

Handle the "SYSID" (項目ID: sysid) field — data type is `String`.

| # | Type | Code |
|---|------|------|
| 1 | IF | `if(key.equals("SYSID"))` [SYSID = "SYSID"] |
| 2 | IF-ELSE-IF | `if(subkey.equalsIgnoreCase("value"))` |
| 3 | RETURN | `return String.class;` // Data type for value property |
| 4 | ELSE-IF | `else if(subkey.equalsIgnoreCase("state"))` [subkeyが"state"の場合、ステータスを返す — When subkey is "state", return the status] |
| 5 | RETURN | `return String.class;` // Data type for state property |
| 6 | ELSE | (falls through to next `else if` branch) |

---

### Block 4 — IF-ELSE-IF (サービス契約番号 field) (L523)

Handle the "サービス契約番号" (項目ID: svc_kei_no) field — data type is `String`.

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `else if(key.equals("サービス契約番号"))` [サービス契約番号 = "Service Contract Number"] |
| 2 | IF | `if(subkey.equalsIgnoreCase("value"))` |
| 3 | RETURN | `return String.class;` // Data type for value property |
| 4 | ELSE-IF | `else if(subkey.equalsIgnoreCase("state"))` [subkeyが"state"の場合、ステータスを返す — When subkey is "state", return the status] |
| 5 | RETURN | `return String.class;` // Data type for state property |
| 6 | ELSE | (falls through to next `else if` branch) |

---

### Block 5 — IF-ELSE-IF (異動区分 field) (L533)

Handle the "異動区分" (項目ID: ido_div) field — data type is `String`.

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `else if(key.equals("異動区分"))` [異動区分 = "Movement Classification"] |
| 2 | IF | `if(subkey.equalsIgnoreCase("value"))` |
| 3 | RETURN | `return String.class;` // Data type for value property |
| 4 | ELSE-IF | `else if(subkey.equalsIgnoreCase("state"))` [subkeyが"state"の場合、ステータスを返す — When subkey is "state", return the status] |
| 5 | RETURN | `return String.class;` // Data type for state property |
| 6 | ELSE | (falls through to next `else if` branch) |

---

### Block 6 — IF-ELSE-IF (異動理由コード field — compound indexed) (L543)

Handle the "異動理由コード" (項目ID: ido_rsn_cd) field. This is a String-type list field with compound key syntax (`"異動理由コード/0"`, `"異動理由コード/*"`, etc.). Supports three modes: asterisk index (returns list count as `Integer`), numeric index (returns per-item type via delegation), and invalid index (returns `null`).

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `else if(key.equals("異動理由コード"))` [異動理由コード = "Movement Reason Code" — String type, list field] |
| 2 | SET | `key = key.substring(separaterPoint + 1);` // keyの次の要素を取得 — Extract the element after the first "/" from the key (e.g., from "異動理由コード/0" get "0") |
| 3 | IF | `if(key.equals("*"))` [* = wildcard, list count mode] |
| 4 | RETURN | `return Integer.class;` // インドックス値の代わりに"*"が指定されていたら、リストの要素数を返す — If "*" is specified as the index value, return the list element count type |
| 5 | ELSE | // 次のはリスト中のインデックスを見る — Next, look at the index within the list |
| 6 | SET | `Integer tmpIndexInt = null;` |
| 7 | TRY | `tmpIndexInt = Integer.valueOf(key);` |
| 8 | CATCH | `catch(NumberFormatException e)` // インドックス値が数値文字列でない場合は、ここでnullを返す — If the index value is not a numeric string, return null here |
| 9 | RETURN | `return null;` |
| 10 | IF | `if(tmpIndexInt == null)` |
| 11 | RETURN | `return null;` |
| 12 | SET | `int tmpIndex = tmpIndexInt.intValue();` |
| 13 | IF | `if(tmpIndex < 0 || tmpIndex >= ido_rsn_cd_list.size())` // インドックス値がリスト個数-1を超えると、ここでnullを返す — If the index value exceeds list count - 1, return null here |
| 14 | RETURN | `return null;` |
| 15 | RETURN | `return ((X33VDataTypeStringBean)ido_rsn_cd_list.get(tmpIndex)).typeModelData(subkey);` // Delegate to the list item's typeModelData for per-item resolution |
| 16 | ELSE | (falls through to next `else if` branch) |

---

### Block 7 — IF-ELSE-IF (異動理由メモ field) (L578)

Handle the "異動理由メモ" (項目ID: ido_rsn_memo) field — data type is `String`.

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `else if(key.equals("異動理由メモ"))` [異動理由メモ = "Movement Reason Memo"] |
| 2 | IF | `if(subkey.equalsIgnoreCase("value"))` |
| 3 | RETURN | `return String.class;` // Data type for value property |
| 4 | ELSE-IF | `else if(subkey.equalsIgnoreCase("state"))` [subkeyが"state"の場合、ステータスを返す — When subkey is "state", return the status] |
| 5 | RETURN | `return String.class;` // Data type for state property |
| 6 | ELSE | (falls through to next `else if` branch) |

---

### Block 8 — IF-ELSE-IF (申請番号 field) (L588)

Handle the "申請番号" (項目ID: mskm_no) field — data type is `String`.

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `else if(key.equals("申請番号"))` [申請番号 = "Application Number"] |
| 2 | IF | `if(subkey.equalsIgnoreCase("value"))` |
| 3 | RETURN | `return String.class;` // Data type for value property |
| 4 | ELSE-IF | `else if(subkey.equalsIgnoreCase("state"))` [subkeyが"state"の場合、ステータスを返す — When subkey is "state", return the status] |
| 5 | RETURN | `return String.class;` // Data type for state property |
| 6 | ELSE | (falls through to next `else if` branch) |

---

### Block 9 — IF-ELSE-IF (申請詳細番号 field) (L598)

Handle the "申請詳細番号" (項目ID: mskm_dtl_no) field — data type is `String`.

| # | Type | Code |
|---|------|------|
| 1 | ELSE-IF | `else if(key.equals("申請詳細番号"))` [申請詳細番号 = "Application Detail Number"] |
| 2 | IF | `if(subkey.equalsIgnoreCase("value"))` |
| 3 | RETURN | `return String.class;` // Data type for value property |
| 4 | ELSE-IF | `else if(subkey.equalsIgnoreCase("state"))` [subkeyが"state"の場合、ステータスを返す — When subkey is "state", return the status] |
| 5 | RETURN | `return String.class;` // Data type for state property |
| 6 | ELSE | (falls through to fallback) |

---

### Block 10 — ELSE (fallback) (L603)

No matching property exists. Return `null`.

| # | Type | Code |
|---|------|------|
| 1 | ELSE | // 条件に一致するプロパティが存在しない場合は、nullを返す — If no property matches the condition, return null |
| 2 | RETURN | `return null;` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `sysid` | Field | System ID — internal system identifier for the record |
| `sysid_value` | Field | System ID data value |
| `sysid_state` | Field | System ID status/state metadata |
| `svc_kei_no` | Field | Service Contract Number — the service contract line item identifier (サービス契約番号) |
| `svc_kei_no_value` | Field | Service Contract Number data value |
| `svc_kei_no_state` | Field | Service Contract Number status/state metadata |
| `ido_div` | Field | Movement Classification — classifies the type of movement/change (異動区分). Data type: String |
| `ido_rsn_cd` | Field | Movement Reason Code — the reason code for a service movement/change (異動理由コード). Data type: String list (`X33VDataTypeList` of `X33VDataTypeStringBean`) |
| `ido_rsn_cd_list` | Field | List of Movement Reason Code beans — the in-memory collection holding all movement reason code entries for this bean |
| `ido_rsn_cd_list_err` | Field | Movement Reason Code detail error items — error flags for each movement reason code entry |
| `ido_rsn_memo` | Field | Movement Reason Memo — free-text memo explaining the movement reason (異動理由メモ). Data type: String |
| `mskm_no` | Field | Application Number — the application/request number (申請番号). Data type: String |
| `mskm_dtl_no` | Field | Application Detail Number — the detail line number within an application (申請詳細番号). Data type: String |
| X33V | Framework | Fujitsu Futurity X33V web framework — the UI framework providing the data-binding bean interfaces (`X33VDataTypeBeanInterface`, `X33VListedBeanInterface`, `X33VDataTypeList`, `X33VDataTypeStringBean`) |
| `typeModelData` | Method | X33V framework contract method — resolves the Java `Class<?>` type for a given field name and subkey, enabling dynamic data binding |
| `value` | Subkey | Property selector — requests the data value type (e.g., the type of the field's actual data) |
| `state` | Subkey | Property selector — requests the state/status metadata type (e.g., whether the field has errors or is in a specific UI state) |
| "SYSID" | Key constant | System ID field identifier — a String-type field |
| "サービス契約番号" | Key constant | Service Contract Number field identifier — a String-type field |
| "異動区分" | Key constant | Movement Classification field identifier — a String-type field |
| "異動理由コード" | Key constant | Movement Reason Code field identifier — a String-type list field supporting indexed access via `/N` suffix |
| "異動理由メモ" | Key constant | Movement Reason Memo field identifier — a String-type field |
| "申請番号" | Key constant | Application Number field identifier — a String-type field |
| "申請詳細番号" | Key constant | Application Detail Number field identifier — a String-type field |
| `X33VDataTypeList` | Class | X33V framework list bean — a list container holding typed data beans (`X33VDataTypeStringBean`) |
| `X33VDataTypeStringBean` | Class | X33V framework string data bean — represents a single typed string value with `value`, `state`, and `update` properties |
| `X33VDataTypeBeanInterface` | Interface | X33V framework contract — defines the `typeModelData` method that this class implements |
