# KKW01023SF02DBean

## Purpose

`KKW01023SF02DBean` is a data-bound form backing bean (D-Bean) that represents the view state for a screen within the KKW01023SF feature. It holds the field values, enabled/disabled states, change-tracking flags, and visual states for four business fields displayed on the target contract / service selection screen. It acts as the single source of truth for view-layer data between the JSP (`KKW010230PJP.jsp`) and the application's framework infrastructure.

## Design

This class follows the standard **Data Bean** pattern used in the X31C/X33V framework (a Japanese enterprise web framework built on top of Struts). It implements three interfaces:

- **`X33VDataTypeBeanInterface`** — declares the contract for `loadModelData()`, `storeModelData()`, and `typeModelData()` methods, enabling the framework to perform generic reflection-style binding of form data from/to the model layer.
- **`X33VListedBeanInterface`** — declares `listKoumokuIds()` which returns the list of recognized field keys the bean understands.
- **`java.io.Serializable`** — allows the bean to be serialized, likely for session storage or distributed caching.

There are no parent classes (it does not extend anything). It does not extend the framework's base bean directly; instead, the model-data methods (`loadModelData`, `storeModelData`, `typeModelData`) appear to be overrides that replace or augment whatever behavior the framework's base class might provide.

Each of the four screen fields is represented by four synchronized properties:

| Property | Purpose |
|---|---|
| `<field>_value` | The actual string data entered by the user (default: empty string) |
| `<field>_enabled` | Whether the field is editable (`false` by default) |
| `<field>_state` | Visual/operational state string (e.g., disabled, error) |
| `<field>_update` | Change-tracking flag set by the framework to detect modifications |

## Fields

The bean has 16 property fields and one index field, organized into four groups:

### 1. Document Count — `no_cnt`

| Field | Type | Default | Description |
|---|---|---|---|
| `no_cnt_update` | `String` | `null` | Update/change flag set by the framework |
| `no_cnt_value` | `String` | `""` | The document count value |
| `no_cnt_enabled` | `Boolean` | `false` | Whether the field is editable |
| `no_cnt_state` | `String` | `""` | Display state (e.g., `"disabled"`, `"error"`) |

### 2. Target Contract Identification Code Name — `tg_kei_skbt_cd_nm`

| Field | Type | Default | Description |
|---|---|---|---|
| `tg_kei_skbt_cd_nm_update` | `String` | `null` | Update flag |
| `tg_kei_skbt_cd_nm_value` | `String` | `""` | The contract code name |
| `tg_kei_skbt_cd_nm_enabled` | `Boolean` | `false` | Editable flag |
| `tg_kei_skbt_cd_nm_state` | `String` | `""` | Display state |

### 3. Target Contract Number — `tgt_kei_no`

| Field | Type | Default | Description |
|---|---|---|---|
| `tgt_kei_no_update` | `String` | `null` | Update flag |
| `tgt_kei_no_value` | `String` | `""` | The contract number |
| `tgt_kei_no_enabled` | `Boolean` | `false` | Editable flag |
| `tgt_kei_no_state` | `String` | `""` | Display state |

### 4. Target Service Name — `tgt_svc_nm`

| Field | Type | Default | Description |
|---|---|---|---|
| `tgt_svc_nm_update` | `String` | `null` | Update flag |
| `tgt_svc_nm_value` | `String` | `""` | The service name |
| `tgt_svc_nm_enabled` | `Boolean` | `false` | Editable flag |
| `tgt_svc_nm_state` | `String` | `""` | Display state |

### 5. Row Index — `index`

| Field | Type | Default | Description |
|---|---|---|---|
| `index` | `int` | `0` | Position of this bean in a list, used when rendering tabular data |

All four fields are declared as `protected`, meaning subclasses (if any) can access them directly. The `index` field is also `protected`.

## Key Methods

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

Retrieves a property value from this bean by field key and sub-key. This is the central polymorphic getter — the framework calls it with Japanese-language display names as the `key` and property descriptors as the `subkey`.

**Parameters:**
- `key` — The Japanese display name of the field (e.g., `"番号／件数"`, `"対象契約識別コード名称"`, `"対象契約番号"`, `"対象サービス名称"`)
- `subkey` — The property descriptor: `"value"`, `"enable"`, or `"state"`

**Returns:** The corresponding property value, cast to `Object`. Returns `null` if the key/subkey don't match any field, or if either parameter is `null`.

**Mapping table:**

| key (Japanese) | key (internal) | subkey | Returns |
|---|---|---|---|
| `"番号／件数"` | `no_cnt` | `"value"` | `no_cnt_value` |
| `"番号／件数"` | `no_cnt` | `"enable"` | `no_cnt_enabled` |
| `"番号／件数"` | `no_cnt` | `"state"` | `no_cnt_state` |
| `"対象契約識別コード名称"` | `tg_kei_skbt_cd_nm` | `"value"` | `tg_kei_skbt_cd_nm_value` |
| `"対象契約識別コード名称"` | `tg_kei_skbt_cd_nm` | `"enable"` | `tg_kei_skbt_cd_nm_enabled` |
| `"対象契約識別コード名称"` | `tg_kei_skbt_cd_nm` | `"state"` | `tg_kei_skbt_cd_nm_state` |
| `"対象契約番号"` | `tgt_kei_no` | `"value"` | `tgt_kei_no_value` |
| `"対象契約番号"` | `tgt_kei_no` | `"enable"` | `tgt_kei_no_enabled` |
| `"対象契約番号"` | `tgt_kei_no` | `"state"` | `tgt_kei_no_state` |
| `"対象サービス名称"` | `tgt_svc_nm` | `"value"` | `tgt_svc_nm_value` |
| `"対象サービス名称"` | `tgt_svc_nm` | `"enable"` | `tgt_svc_nm_enabled` |
| `"対象サービス名称"` | `tgt_svc_nm` | `"state"` | `tgt_svc_nm_state` |

The subkey comparison is case-insensitive (`equalsIgnoreCase`).

### `storeModelData(...)` → `void`

There are three overloaded versions of this setter method:

1. **`storeModelData(String gamenId, String key, String subkey, Object in_value)`** — Takes an extra `gamenId` (screen ID) parameter that is currently unused. Delegates to the second overload. This is likely a reserved extension point.

2. **`storeModelData(String key, String subkey, Object in_value)`** — The middle-ground overload. Delegates to the third version with `isSetAsString = false`.

3. **`storeModelData(String key, String subkey, Object in_value, boolean isSetAsString)`** — The core implementation. Accepts `key` (field name) and `subkey` (`"value"`, `"enable"`, or `"state"`), casts `in_value` to the appropriate type (`String` or `Boolean`), and invokes the matching setter.

**Parameters:**
- `key` — Japanese display name of the field
- `subkey` — `"value"`, `"enable"`, or `"state"`
- `in_value` — The data to set, must be castable to `String` or `Boolean`
- `isSetAsString` — A boolean flag (always passed as `false` from the current callers) that the method accepts but does not use in any logic. This appears to be a framework extension point for handling `Long` type values.

The method is symmetric with `loadModelData` — it uses the same `key`/`subkey` matching logic to dispatch to the appropriate setter.

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

Returns the Java type for a given field/subkey pair, enabling type-safe binding. This is a read-only variant of the load/store pattern.

**Parameters:** Same as `loadModelData` — `key` (field key) and `subkey` (`"value"`, `"enable"`, `"state"`).

**Returns:**
| key | subkey | Returns |
|---|---|---|
| Any of the four fields | `"value"` | `String.class` |
| Any of the four fields | `"enable"` | `Boolean.class` |
| Any of the four fields | `"state"` | `String.class` |

Returns `null` for unrecognized keys or subkeys, or if either parameter is `null`.

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

A **static** method that returns a list of the four Japanese display names that this bean recognizes. This is used by the framework to iterate over all fields for batch operations such as validation, logging, or export.

**Returns:** An `ArrayList<String>` containing:
- `"番号／件数"`
- `"対象契約識別コード名称"`
- `"対象契約番号"`
- `"対象サービス名称"`

Note: Being static, this can be called without instantiating the bean: `KKW01023SF02DBean.listKoumokuIds()`.

### `getIndex()` / `setIndex(int index)`

Simple getter/setter for the row index. Used when this bean represents a single row in a tabular list displayed on the screen.

## Relationships

```mermaid
flowchart LR
    A["KKW010230PJP<br>jsp (view)"] -->|"binds to"| B["KKW01023SF02DBean<br>this class"]
    B -->|"implements"| C["X33VDataTypeBeanInterface"]
    B -->|"implements"| D["X33VListedBeanInterface"]
    B -->|"implements"| E["Serializable"]
```

### Caller

- **`KKW010230PJP.jsp`** — This JSP page binds to the bean as the view model. The framework likely uses the `loadModelData`/`storeModelData` methods to populate form fields from the bean on page load and persist user changes back after submission.

### Downstream

No outbound dependencies. The bean is self-contained and references no other application types.

## Data Flow

```mermaid
flowchart TD
    A["JSP Load<br>KKW010230PJP.jsp"] -->|"framework calls"| B["loadModelData<br>key + subkey"]
    B -->|"returns field value"| A
    
    A -->|"user edits form"| C["User Input"]
    C -->|"framework calls"| D["storeModelData<br>key + subkey + value"]
    D -->|"updates field"| E["Bean properties"]
    E -->|"framework reads"| F["typeModelData<br>for type checking"]
    F -->|"returns Class"| G["Type validation"]
```

## Usage Example

The bean is not typically instantiated or manipulated directly by application code. Instead, the framework handles it. A typical pattern looks like this:

```java
// The framework instantiates the bean for the request scope
KKW01023SF02DBean bean = new KKW01023SF02DBean();

// Framework populates fields via polymorphic getter
Object value = bean.loadModelData("対象サービス名称", "value");
// Returns: tgt_svc_nm_value

Boolean enabled = bean.loadModelData("対象サービス名称", "enable");
// Returns: tgt_svc_nm_enabled

// Framework sets user input via polymorphic setter
bean.storeModelData("対象サービス名称", "value", "New Service Name");
bean.storeModelData("対象サービス名称", "enable", true);

// Framework verifies types before binding
Class<?> type = bean.typeModelData("対象サービス名称", "value");
// Returns: String.class

// Framework iterates over all fields
for (String fieldName : KKW01023SF02DBean.listKoumokuIds()) {
    // Process each field
}
```

In the JSP itself, the framework generates HTML form bindings automatically:

```jsp
<!-- The framework resolves these to bean properties -->
<%@ taglib prefix="xx" uri="/x31c-bean" %>
<xx:property bean="KKW01023SF02DBean" key="対象サービス名称" subkey="value" />
<xx:property bean="KKW01023SF02DBean" key="対象サービス名称" subkey="enable" />
```

## Notes for Developers

1. **Japanese keys, English fields.** The bridge between the Japanese display names (e.g., `"対象サービス名称"`) and the English property names (e.g., `tgt_svc_nm`) is hardcoded in the `if/else` chains in `loadModelData`, `storeModelData`, and `typeModelData`. To add a new field, you must update all three methods and add the key to `listKoumokuIds()`. Missing an update in any one method will cause silent mismatches.

2. **`isSetAsString` parameter is unused.** The `storeModelData(key, subkey, value, isSetAsString)` method accepts an `isSetAsString` flag that the Java code stores in a local variable `separaterPoint` (which actually holds the result of `key.indexOf("/")` — unrelated to the boolean). The `isSetAsString` parameter has no branching logic inside the method body. This appears to be a framework extension point that was never implemented in this bean. Do not rely on it.

3. **Case-insensitive subkey.** The `equalsIgnoreCase` call on the subkey means `"VALUE"`, `"Value"`, and `"value"` are all treated identically. This is convenient but can mask typos (e.g., `"valuet"` would simply fall through to `null`).

4. **`index` field is never used by this bean.** It has a getter/setter but no logic references it. It is likely used by the JSP for rendering row numbers or maintaining selection state in a table.

5. **Thread safety.** This bean is not thread-safe. Each HTTP request typically gets its own instance (request-scoped in Struts), so concurrent access is not expected. However, if the bean is stored in the session or a shared cache, concurrent modifications could cause data races on the `String` and `Boolean` fields.

6. **Immutability of field list.** The four fields and their key names are fixed at compile time. The `listKoumokuIds()` method returns a mutable `ArrayList` — callers that modify the returned list will not affect the bean, but they could introduce inconsistencies if they add keys that the bean's other methods don't recognize.

7. **`separaterPoint` variable is unused.** Each of `loadModelData`, `storeModelData`, and `typeModelData` computes `int separaterPoint = key.indexOf("/")` and never uses the result. This is likely a remnant from a previous design where keys were parsed by a separator character (perhaps to support nested field hierarchies). The current implementation uses exact string matching instead.

8. **Interface contracts.** Because this class implements `X33VDataTypeBeanInterface`, any framework code that performs generic data binding will expect these three methods (`loadModelData`, `storeModelData`, `typeModelData`) to be consistent. A mismatch between them (e.g., `loadModelData` returns a `String` but `typeModelData` returns `Integer.class`) will cause runtime binding errors.
