# CRW03407SF02DBean

## Purpose

`CRW03407SF02DBean` is a JavaBean-based data carrier that encapsulates the model state for a tab-based configuration page in the web application. It holds three groups of display properties — **tab code** (`l1_tab_cd`), **tab name** (`l1_tab_nm`), and **page ID** (`l1_pg_id`) — each with sub-properties for value, enabled status, and state. It also provides generic property accessors (`loadModelData`, `storeModelData`, `typeModelData`) that route requests to the correct getter/setter based on string-based key lookup, making it compatible with the framework's data-binding conventions. It is used by five JSP pages that serve different sub-workflows of the same domain feature.

## Design

`CRW03407SF02DBean` is a **passive data object** (often called a "bean" in Java EE / JSP MVC apps). It holds no business logic beyond serialization-safe getters/setters and the property-routing triad (`loadModelData`, `storeModelData`, `typeModelData`). Its architectural role is to serve as a **transfer object** between JSP view layers and underlying services, enabling generic data-binding frameworks to read and write fields by name.

It implements two framework interfaces:

- **`X33VDataTypeBeanInterface`** — appears to require the `loadModelData`, `storeModelData`, and `typeModelData` methods, providing a contract for generic data-type introspection and serialization.
- **`X33VListedBeanInterface`** — appears to require the `listKoumokuIds()` static method, which returns the canonical list of property key names known to the bean.

No superclass is extended, and no additional interfaces are implemented beyond these two.

## Fields

The bean declares three groups of protected fields, each with a parallel set of four properties:

| Property Group | Value Field | Enabled Field | State Field | Update Fields |
|---|---|---|---|---|
| **Tab Code** (`l1_tab_cd`) | `l1_tab_cd_value` (String, default "") | `l1_tab_cd_enabled` (Boolean, default false) | `l1_tab_cd_state` (String, default "") | `l1_tab_cd_update` (String) |
| **Tab Name** (`l1_tab_nm`) | `l1_tab_nm_value` (String, default "") | `l1_tab_nm_enabled` (Boolean, default false) | `l1_tab_nm_state` (String, default "") | `l1_tab_nm_update` (String) |
| **Page ID** (`l1_pg_id`) | `l1_pg_id_value` (String, default "") | `l1_pg_id_enabled` (Boolean, default false) | `l1_pg_id_state` (String, default "") | `l1_pg_id_update` (String) |

The `update` fields are `String` and start with `null`, suggesting they capture delta-change metadata (e.g., "this field was modified during this request cycle"). The `state` fields are empty-string-initialized, likely holding UI state strings like CSS classes or status labels.

Additionally:

- **`index`** (`int`) — An integer index, likely used for row-based list rendering or ordering when this bean is used as part of a collection.

### Field Defaults

- All `_value` fields are initialized to `""` (empty string).
- All `_enabled` fields are initialized to `Boolean.FALSE`.
- All `_state` fields are initialized to `""` (empty string).
- All `_update` fields are `null` by default.

## Key Methods

### Constructor

```java
public CRW03407SF02DBean()
```

Performs no special initialization — all fields rely on their declaration-time defaults. The body is intentionally minimal.

---

### Property Getters and Setters

Each of the three property groups has a full set of getter/setter methods. Here is the canonical pattern:

| Method | Return Type | Description |
|---|---|---|
| `getL1_tab_cd_value()` | `String` | Returns the tab code value |
| `setL1_tab_cd_value(String)` | `void` | Sets the tab code value |
| `getL1_tab_cd_enabled()` | `Boolean` | Returns whether the tab code is enabled |
| `setL1_tab_cd_enabled(Boolean)` | `void` | Sets the enabled status |
| `getL1_tab_cd_state()` | `String` | Returns the tab code state |
| `setL1_tab_cd_state(String)` | `void` | Sets the tab code state |
| `getL1_tab_cd_update()` | `String` | Returns the tab code update flag |
| `setL1_tab_cd_update(String)` | `void` | Sets the tab code update flag |

The same eight methods exist for `tab_nm` (tab name) and `pg_id` (page ID). A total of **24** getter/setter methods.

There is also a separate getter/setter for `index`:

| Method | Return Type | Description |
|---|---|---|
| `getIndex()` | `int` | Returns the row/index number |
| `setIndex(int)` | `void` | Sets the row/index number |

---

### loadModelData

```java
public Object loadModelData(String key, String subkey)
```

**Purpose:** Dynamically retrieve a field value by string key and sub-key, acting as a type-erased property router.

**Parameters:**
- `key` — The property group name in Japanese. Must be one of: `"タブコード"` (Tab Code), `"タブ名称"` (Tab Name), or `"画面ID"` (Page ID).
- `subkey` — The sub-property name. Must be one of: `"value"`, `"enable"`, or `"state"` (case-insensitive).

**Return value:** The field value cast to `Object`. For `"value"` or `"state"` subkeys, returns `String`. For `"enable"`, returns `Boolean`. Returns `null` if either parameter is `null` or if the key/subkey combination is unrecognized.

**Behavior:** Internally performs string comparison against the three Japanese key names, then dispatches to the corresponding getter. For example, `loadModelData("タブコード", "value")` calls `getL1_tab_cd_value()`.

**Side effects:** None. This is a pure read operation.

---

### storeModelData (three overloads)

```java
public void storeModelData(String key, String subkey, Object in_value)
public void storeModelData(String key, String subkey, Object in_value, boolean isSetAsString)
public void storeModelData(String gamenId, String key, String subkey, Object in_value)
```

**Purpose:** The write counterpart to `loadModelData`. Sets a field by string key and sub-key with type-cast dispatch.

**Parameters:**
- `key` — Same Japanese key names as `loadModelData`.
- `subkey` — Same `"value"`, `"enable"`, `"state"` pattern (case-insensitive).
- `in_value` — The value to set, cast to `String` or `Boolean` depending on the subkey.
- `isSetAsString` (third signature only) — Unused in the body. Appears to be a framework hook for future type coercion (e.g., setting a `Long` field as a `String` value). When `false`, delegates to the two-argument version.
- `gamenId` (third signature only) — Unused. Passed through to the two-argument version. Likely a legacy parameter from a framework evolution.

**Return value:** `void`.

**Behavior:** Mirrors `loadModelData` in dispatch logic but calls setters instead. For example, `storeModelData("タブ名称", "enable", true)` calls `setL1_tab_nm_enabled(Boolean.valueOf(...))`. The cast `(String)` or `(Boolean)` on `in_value` is unchecked — passing the wrong type will throw a `ClassCastException`.

**Side effects:** Mutates the bean's fields.

---

### typeModelData

```java
public Class<?> typeModelData(String key, String subkey)
```

**Purpose:** Returns the runtime type of a field, enabling type-safe deserialization or data-binding frameworks to know what type to expect.

**Parameters:** Same `key` and `subkey` pattern as `loadModelData`/`storeModelData`.

**Return value:**
- `String.class` for `"value"` and `"state"` subkeys.
- `Boolean.class` for `"enable"` subkey.
- `null` if key or subkey is `null` or unrecognized.

**Behavior:** Identical dispatch logic to `loadModelData`/`storeModelData`. This method ensures type consistency — whatever type `storeModelData` casts to, `typeModelData` returns that same `Class<?>`.

---

### listKoumokuIds

```java
public static ArrayList<String> listKoumokuIds()
```

**Purpose:** Returns the canonical list of property key names (項目名, "koumoku ids") that this bean supports. This static method fulfills the `X33VListedBeanInterface` contract.

**Return value:** An `ArrayList<String>` containing exactly three entries:

```
"タブコード"
"タブ名称"
"画面ID"
```

**Side effects:** Creates and returns a new list on each invocation — the caller is responsible for the returned list's lifecycle.

---

## Relationships

### Who Depends on CRW03407SF02DBean

This bean is referenced by five JSP pages, all in the same module family (the `CRW0340*` series), suggesting they are different views or workflows within the same feature:

```mermaid
flowchart TD
    subgraph JSPs["JSP View Pages"]
        J1["CRW034010PJP.jsp"]
        J2["CRW034020PJP.jsp"]
        J3["CRW034030PJP.jsp"]
        J4["CRW034050PJP.jsp"]
        J5["CRW034060PJP.jsp"]
    end

    subgraph BEAN["CRW03407SF02DBean"]
        M1["loadModelData"]
        M2["storeModelData"]
        M3["typeModelData"]
        M4["listKoumokuIds"]
        G1["tabCd getters/setters"]
        G2["tabNm getters/setters"]
        G3["pgId getters/setters"]
        F1["index"]
    end

    J1 --> BEAN
    J2 --> BEAN
    J3 --> BEAN
    J4 --> BEAN
    J5 --> BEAN
```

### What CRW03407SF02DBean Depends On

No outbound references to other application classes are found. The bean only depends on:

- `java.io.Serializable` — for HTTP session or request scope serialization.
- `X33VDataTypeBeanInterface` — a framework interface (likely in a shared library) that defines the data-type contract.
- `X33VListedBeanInterface` — a framework interface defining the "listed bean" contract (item enumeration).

This isolation makes it a pure data carrier with no side dependencies.

## Usage Example

Based on the method signatures and the property-routing pattern, here is the typical usage:

### Creating and Populating the Bean

```java
CRW03407SF02DBean bean = new CRW03407SF02DBean();

// Direct property access
bean.setL1_tab_cd_value("T001");
bean.setL1_tab_nm_value("Main Settings");
bean.setL1_pg_id_value("PG010");
bean.setL1_tab_cd_enabled(true);
bean.setIndex(0);

// Or via generic routing
bean.storeModelData("タブコード", "value", "T001");
bean.storeModelData("タブ名称", "enable", Boolean.TRUE);
bean.storeModelData("画面ID", "state", "active");
```

### Reading via Generic Routing

```java
Object tabCdValue = bean.loadModelData("タブコード", "value");        // "T001"
Object tabCdEnabled = bean.loadModelData("タブコード", "enable");     // true
Class<?> tabCdType = bean.typeModelData("タブコード", "value");       // String.class
```

### Enumerating Supported Keys

```java
ArrayList<String> keys = CRW03407SF02DBean.listKoumokuIds();
// returns ["タブコード", "タブ名称", "画面ID"]
```

## Notes for Developers

### Thread Safety

This bean is **not thread-safe**. It has no synchronization, and its fields are plain mutable instance variables. It is intended for single-threaded use within a single request scope.

### Null Safety

- `loadModelData` and `typeModelData` return `null` if either `key` or `subkey` is `null`. No exception is thrown.
- `storeModelData` silently returns (does nothing) if `key` or `subkey` is `null`.
- The `isSetAsString` parameter is accepted but not used in the current body. Do not rely on its value for behavior.
- The `gamenId` parameter in the three-argument `storeModelData` is also unused.

### Case Sensitivity

The key matching in `loadModelData`/`storeModelData`/`typeModelData` is **case-sensitive** (uses `String.equals()`), but the subkey matching is **case-insensitive** (uses `String.equalsIgnoreCase()`). This means `"タブコード"` is required, but `"VALUE"`, `"value"`, or `"Value"` will all resolve correctly.

### Japanese Key Names

The `key` parameter uses Japanese identifiers. If you are adding new fields or new routing paths, remember to update all three methods (`loadModelData`, `storeModelData`, `typeModelData`) and `listKoumokuIds()` consistently. A missing entry in any one of the four methods will cause silent failures (null returns or ignored sets).

### Serializable

The class implements `Serializable` but does not declare a `serialVersionUID`. This means serialization is fragile across class versions — any field addition or removal will trigger an `InvalidClassException`. Consider adding an explicit `serialVersionUID` if this bean is serialized across JVM restarts or to a persistent store.

### UI State Fields

The `_state` fields (e.g., `l1_tab_cd_state`) are distinct from the `_value` fields. While `_value` holds the actual business data (e.g., a tab code string), `_state` likely carries UI metadata such as CSS class names, tooltip text, or validation error messages. The naming convention suggests this bean is designed to be consumed directly by a JSP page that renders UI controls with conditional styling based on `value`, `enabled`, and `state`.

### Unused `separaterPoint` Variable

The `separaterPoint` local variable is computed in every data-routing method (`key.indexOf("/")`) but never used. This appears to be scaffolding for a future feature where the key might be a dotted or slash-separated path (e.g., `"タブコード/subitem"`). If this feature is never implemented, the variable can be safely removed.

### No Domain Logic

This bean intentionally contains no validation, no business rules, and no side effects beyond field mutation. All validation and processing should happen in the JSP pages or backing controllers that use it.
