# KKW00127SF02DBean

## Purpose

`KKW00127SF02DBean` is a data-binding bean used within the K-Opticom web framework (X33 framework) to manage form data for a **service contract agreement details** screen. It acts as a view-layer data object (VDBean), holding individual form fields and nested repeatable list structures that correspond to fields rendered in a JSP. Its primary role is to provide a unified, introspectable data carrier between the JSP view (`KKW001270PJP.jsp`) and the application logic, supporting both single-value fields and dynamic list (repeat) items.

## Design

This class follows the **Data-Binding Bean** pattern used throughout the X33 framework. It implements three interfaces:

- **`X33VDataTypeBeanInterface`** — enables dynamic, string-based property access via `loadModelData`, `storeModelData`, and `typeModelData`, where fields are addressed by a display-name key and a subkey (typically `"value"` or `"state"`). This decouples the JSP from Java field names.
- **`X33VListedBeanInterface`** — provides list management methods (`addListDataInstance`, `removeElementFromListData`, `clearListDataInstance`) for dynamically growing and shrinking repeat-item list collections.
- **`Serializable`** — allows the bean to be serialized, for example for session storage or pass-through to other layers.

Architecturally, this bean is a **data object** (sometimes called a "view bean") — it contains no business logic, only data storage, accessor methods, and the introspection methods that the framework uses to bind UI components to model data.

### Field Categories

The bean's 30+ fields fall into two structural groups:

#### Single-value fields (value / state / update pattern)

Each of these fields follows a consistent three-part naming convention:

| Field ID (internal) | Display Name (key) | `_value` Purpose | `_state` Purpose | `_update` Purpose |
|---|---|---|---|---|
| `svc_kei_stat` | サービス契約ステータス | The current status value | The editable/disabled state flag | Change-flag for dirty tracking |
| `mskm_dtl_no` | 申込明細番号 | Application detail number | State flag | Change-flag |
| `prc_grp_cd` | 料金グループコード | Pricing group code | State flag | Change-flag |
| `svc_sta_kibo_ymd` | サービス開始希望日 | Desired service start date (YM D) | State flag | Change-flag |
| `payway_keizoku_flg` | 支払方法引継フラグ | Payment method carry-over flag | State flag | Change-flag |
| `intr_cd` | 紹介コード | Referral code | State flag | Change-flag |
| `svc_cd` | サービスコード | Service code | State flag | Change-flag |
| `upd_dtm` | 更新年月日时分秒（サービス契約） | Last update timestamp | State flag | Change-flag |
| `auto_shosa_tran_stat_cd` | 自動照会処理状態コード | Auto-inquiry processing status code | State flag | Change-flag |

The `_state` fields (always initialized to `""`) control UI rendering — for example, whether an input field is read-only or visible. The `_update` fields serve as change-detection flags (set when the user modifies the field).

#### List fields (repeatable items)

| Field ID | Display Name | Element Type |
|---|---|---|
| `svc_kei_stat_lis_list` | サービス契約ステータスリスト | `X33VDataTypeStringBean` |
| `intr_cd_list_list` | 紹介コードリスト | `X33VDataTypeStringBean` |

These are `X33VDataTypeList` collections, each pre-initialized with one element in the constructor. Elements are `X33VDataTypeStringBean` instances that support the same `loadModelData`/`storeModelData` introspection, allowing nested property resolution.

## Key Methods

### Constructor: `KKW00127SF02DBean()`

Initializes the two list fields with a single empty `X33VDataTypeStringBean` element each. This ensures the list fields are never `null` at construction time — the JSP can immediately bind to index 0 without a null check. All single-value fields are left at their Java default (`null` for String references, except `_value` fields which default to `""`).

### Getter / Setter Pairs

Each field has a standard getter and setter pair. For single-value fields, getters return the field and setters assign it. For list fields, getters return the `X33VDataTypeList` reference directly, allowing callers to modify its contents.

**Notable getters:**

- **`getJsflist_svc_kei_stat_lis()`** — Converts the internal `svc_kei_stat_lis_list` into an `ArrayList<SelectItem>` suitable for JSF `<h:selectOneMenu>` or similar components. Each list element's `value` is turned into a JSF `SelectItem` with the list index as its label. This bridges the framework's data structure to JSF UI components.
- **`getJsflist_intr_cd_list()`** — Same conversion, but for the `intr_cd_list_list` collection.
- **`getIndex()` / `setIndex(int)`** — A simple integer field that tracks the row index of this bean instance within a list context (useful when rendering repeated items).

### Core Introspection Methods

These three methods form the heart of the bean's role in the X33 data-binding framework. They are called by the framework (or by parent beans) to read and write field values using **string-based property keys** rather than hardcoded Java accessor calls.

#### `loadModelData(String key, String subkey) → Object`

Reads a field's value by matching the display-name `key` (e.g., `"サービス契約ステータス"`) and `subkey` (either `"value"` or `"state"`). Returns the corresponding String field value.

For list-type keys (containing a `/` separator), the method parses the key as `"<display_name>/<index>"` — for example, `"サービス契約ステータスリスト/0"` accesses the first element. A subkey of `"*"` returns the list size as an `Integer`.

**Behavior by key:**

| Key Pattern | Subkey | Returns |
|---|---|---|
| `"サービス契約ステータス"` | `"value"` | `svc_kei_stat_value` |
| `"サービス契約ステータス"` | `"state"` | `svc_kei_stat_state` |
| `"申込明細番号"` | `"value"` / `"state"` | `mskm_dtl_no_value` / `mskm_dtl_no_state` |
| `"サービス契約ステータスリスト/<n>"` | `"value"` / `"state"` | Element n's loaded data via `X33VDataTypeStringBean.loadModelData()` |
| `"サービス契約ステータスリスト/*"` | any | `svc_kei_stat_lis_list.size()` |
| `"紹介コードリスト/<n>"` | `"value"` / `"state"` | Element n's loaded data via `X33VDataTypeStringBean.loadModelData()` |
| `"紹介コードリスト/*"` | any | `intr_cd_list_list.size()` |
| Any other known single field | `"value"` / `"state"` | Corresponding value or state field |

If the key is `null`, the subkey is `null`, or no match is found, returns `null`.

#### `storeModelData(String key, String subkey, Object in_value) → void`

The write counterpart to `loadModelData`. Sets the field matching the given `key` and `subkey` to `in_value` (cast to `String`).

**Important overload variants:**

1. **`storeModelData(String gamenId, String key, String subkey, Object in_value)`** — A four-argument variant where `gamenId` (screen ID) is accepted but **ignored** — it delegates to the three-argument version. This is likely a framework-mandated signature for interface compliance.

2. **`storeModelData(String key, String subkey, Object in_value)`** — The primary write method. Delegates to the three-argument version with `isSetAsString = false`.

3. **`storeModelData(String key, String subkey, Object in_value, boolean isSetAsString)`** — The full implementation. The `isSetAsString` flag controls whether `Long`-type fields should be set from a String value (relevant when the framework has heterogeneous field types). For this bean, all fields are String-based, so this flag has no practical effect on the single-value setters.

For list items, the method calls the element's own `storeModelData(subkey, in_value)` to propagate the value into the nested `X33VDataTypeStringBean`.

#### `typeModelData(String key, String subkey) → Class<?>`

Returns the Java type of the field identified by `key`/`subkey`. For all single-value fields in this bean, the type is always `String.class`. For list size queries (`"*/"` pattern), it returns `Integer.class`. For list element access, it delegates to the element's `typeModelData(subkey)`.

This method enables the framework to perform type-safe casts when reading values dynamically.

### List Management Methods

#### `addListDataInstance(String key) → int`

Adds a new element to the appropriate list collection based on the display-name key. Creates the list structure (with one initial element) if it is `null`. Returns the index of the newly added element.

- Throws `X33SException` (via `X33VViewBaseBean.createExceptionForDataType`) if the list's maximum element count is exceeded.
- Returns `-1` if the key is `null` or does not match a known list field.

#### `removeElementFromListData(String key, int index) → void`

Removes the element at `index` from the matching list, but only if the index is within bounds (`0 <= index < size`).

#### `clearListDataInstance(String key) → void`

Clears all elements from the matching list collection.

### Static Utility Method

#### `listKoumokuIds() → ArrayList<String>`

Returns a list of all display-name keys used by this bean. This is called by parent beans (e.g., `KKW00127SFBean`) to populate introspection methods for nested data-type-bean fields. The list includes:

```
サービス契約ステータス
申込明細番号
サービス契約ステータスリスト
料金グループコード
サービス開始希望日
支払方法引継フラグ
紹介コードリスト
紹介コード
サービスコード
更新年月日时分秒（サービス契約）
自動照会処理状態コード
```

## Relationships

```mermaid
flowchart TD
    A["KKW001270PJP.jsp"] -->|"displays/ binds"| B["KKW00127SFBean"]
    B -->|"contains instance of"| C["KKW00127SF02DBean"]
    C -->|"uses"| D["X33VDataTypeList"]
    C -->|"uses"| E["X33VDataTypeStringBean"]
    C -->|"uses"| F["SelectItem"]
    B -->|"also contains"| G["KKW00127SF01DBean"]
    B -->|"also contains"| H["KKW00127SF03DBean"]
```

### Who uses this class

| Consumer | How |
|---|---|
| **`KKW00127SFBean`** | Instantiates `KKW00127SF02DBean` objects and stores them in the `ekk0081a010cbsmsg1list_list` field as repeatable list elements. Also delegates `listKoumokuIds()` calls to it for nested field introspection. |
| **`KKW001270PJP.jsp`** | Reads field values from the bean through the parent `KKW00127SFBean` to render the service contract agreement details screen. |

### Dependencies

| Dependency | Role |
|---|---|
| **`X33VDataTypeBeanInterface`** | Defines the contract for `loadModelData`/`storeModelData`/`typeModelData` introspection. |
| **`X33VListedBeanInterface`** | Defines the contract for dynamic list element management. |
| **`X33VDataTypeList`** | Collection type used to store repeatable list items. |
| **`X33VDataTypeStringBean`** | Element type for list items — each list slot holds one of these. |
| **`javax.faces.model.SelectItem`** | JSF component data type, used by `getJsflist_*` methods. |
| **`java.io.Serializable`** | Enables serialization of the bean. |

## Usage Example

```java
// Instantiate the bean
KKW00127SF02DBean bean = new KKW00127SF02DBean();

// Set a single-value field directly via setter
bean.setSvc_kei_stat_value("001");
bean.setSvc_kei_stat_state("");       // empty = editable

// Use introspection to set via display name (framework style)
bean.storeModelData("サービス契約ステータス", "value", "002");
bean.storeModelData("サービス契約ステータス", "state", "disabled");

// Read back via introspection
Object value = bean.loadModelData("サービス契約ステータス", "value");
// value == "002"

// Add a new list element
int newIndex = bean.addListDataInstance("サービス契約ステータスリスト");
// newIndex == 1

// Set value on the new list element
bean.storeModelData("サービス契約ステータスリスト/" + newIndex, "value", "active");

// Get JSF-selectable items from the list
ArrayList<SelectItem> selectItems = bean.getJsflist_svc_kei_stat_lis();

// Remove a list element
bean.removeElementFromListData("サービス契約ステータスリスト", 0);

// Clear the entire list
bean.clearListDataInstance("サービス契約ステータスリスト");

// Discover all field names
ArrayList<String> fields = KKW00127SF02DBean.listKoumokuIds();
```

## Notes for Developers

### Thread Safety

This bean is **not thread-safe**. It is designed to be instantiated per-request (or per-session) within the X33 framework's web processing pipeline. Each HTTP request gets its own bean instance (or reuses one from a scoped object). Never share an instance across threads.

### The `else if` in `addListDataInstance`

The constructor body of `addListDataInstance` starts with `if(key == null) { return -1; }` followed by `else if(...)`. This is not a logical error — the `else` is simply a stylistic consequence of early return. If `key` is not null, execution flows into the first list check. A refactoring to standalone `if` statements would improve readability but is not functionally required.

### List Initialization

The constructor pre-populates each list with exactly one element. This is a convention of the X33 framework: the JSP can bind to index 0 immediately. When the user needs more rows, `addListDataInstance` is called. Be aware that `addListDataInstance` creates the list lazily if it is `null` (e.g., after deserialization), but the initial constructor ensures it starts with one element.

### Key Naming Convention

All field keys use **Japanese display names** rather than technical IDs. This is intentional — the X33 framework uses these human-readable keys for i18n-ready binding. When adding a new field, you must add its Japanese key to `listKoumokuIds()` and update `loadModelData`/`storeModelData`/`typeModelData` in matching order.

### Field Naming Convention

The three suffixes `_update`, `_value`, `_state` are part of the X33 framework convention:
- **`_value`** — the actual data value (initialized to `""`)
- **`_state`** — UI state such as read-only, visible, disabled (initialized to `""`)
- **`_update`** — a flag set by the framework when the field is modified, used to determine which fields need to be persisted

### Deserialization

Because the bean implements `Serializable`, it may be stored in HTTP session or serialized across layers. After deserialization, list fields could theoretically be `null` if the serialization context doesn't properly reinitialize them. The `addListDataInstance` method handles this by creating the list lazily, but other methods like `loadModelData` that call `.size()` on a `null` list would throw a `NullPointerException`. In practice, the X33 framework handles this, but callers should be cautious.

### Inherited from `X33VViewBaseBean`

This bean likely extends a base class (referenced in the code as `X33VViewBaseBean` via `createExceptionForDataType`). The `storeModelData(String gamenId, ...)` four-argument variant and `createExceptionForDataType` calls indicate inherited behavior from this framework base class.
