# CRW03407SF03DBean

## Purpose

`CRW03407SF03DBean` is a **data transfer object (DTO) / presentation-model bean** that holds the view-state for a campaign management screen in a Japanese enterprise web application. It encapsulates six display fields — detail index, campaign code, campaign name, effective date, and two row-styling properties — and provides a unified key/subkey-based dispatch layer so that JSP pages and their backing controllers can read and write these fields through a single, consistent model-data API.

## Design

This class follows the **JavaBean + Model-View-Controller (MVC) data bean** pattern commonly used in Japanese enterprise web frameworks built on JSP/Servlet technology. It implements two framework interfaces:

- **`X33VDataTypeBeanInterface`** — likely requires the bean to implement `loadModelData`, `storeModelData`, and `typeModelData` so that a generic view-controller can read/write/inspect typed data without knowing the specific bean structure at compile time.
- **`X33VListedBeanInterface`** — likely requires `listKoumokuIds()` (where *koumoku* is Japanese for "items" or "columns") so that a listing or table-generation utility can iterate over all recognized field names.

The bean has **no superclass** and **no outbound dependencies**. It is a pure data carrier: it contains no business logic, no database access, and no side effects beyond setting its own fields.

### Field Layout

Each of the six logical fields follows a consistent four-part structure:

| Component | Suffix | Type | Example |
|---|---|---|---|
| Value | `_value` | `String` (default `""`) | The actual data |
| Enabled | `_enabled` | `Boolean` (default `false`) | Whether the field is editable |
| State | `_state` | `String` (default `""`) | Visual/status indicator |
| Update | `_update` | `String` (nullable) | Update flag (used by framework) |

This uniformity enables the generic dispatch methods to handle all fields with the same dispatch logic.

## Key Methods

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

The **primary read method**. Given a logical field name (`key`) and a component (`subkey`), it returns the corresponding value via the appropriate getter. Returns `null` if either parameter is `null`, or if no matching field exists.

**Dispatch table:**

| `key` (Japanese) | `key` (English) | `subkey = "value"` | `subkey = "enable"` | `subkey = "state"` |
|---|---|---|---|---|
| 明細インデックス | Detail Index | `getL2_detail_index_value()` | `getL2_detail_index_enabled()` | `getL2_detail_index_state()` |
| キャンペーンコード | Campaign CD | `getL2_dsp_campaign_cd_value()` | `getL2_dsp_campaign_cd_enabled()` | `getL2_dsp_campaign_cd_state()` |
| キャンペーン名 | Campaign Name | `getL2_wrib_svc_nm_value()` | `getL2_wrib_svc_nm_enabled()` | `getL2_wrib_svc_nm_state()` |
| 適用月 | Effective Date | `getL2_wrib_svc_tstaymd_value()` | `getL2_wrib_svc_tstaymd_enabled()` | `getL2_wrib_svc_tstaymd_state()` |
| 行スタイルクラス | Row Style Class | `getL2_line_style_class_value()` | — | `getL2_line_style_class_state()` |
| 行スタイルID | Row Style ID | `getL2_line_style_id_value()` | — | `getL2_line_style_id_state()` |

**Note:** The row styling fields (*row style class* and *row style id*) have no `enable` subkey — they are visual-only fields without an enabled/disabled toggle.

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

### `storeModelData(...)` (three overloads)

The **primary write method**. The three overloads form a delegation chain:

1. **`storeModelData(String gamenId, String key, String subkey, Object in_value)`** — Accepts a screen ID (`gamenId`) parameter that is unused. Delegates to overload #2, essentially ignoring the screen ID (reserved for future use).
2. **`storeModelData(String key, String subkey, Object in_value)`** — Delegates to overload #3 with `isSetAsString = false`.
3. **`storeModelData(String key, String subkey, Object in_value, boolean isSetAsString)`** — The **real implementation**. Dispatches the `in_value` to the appropriate setter based on the `key`/`subkey` pair.

**Dispatch behavior (mirror of `loadModelData`):**

| `key` | `subkey = "value"` | `subkey = "enable"` | `subkey = "state"` |
|---|---|---|---|
| 明細インデックス | `setL2_detail_index_value()` | `setL2_detail_index_enabled()` | `setL2_detail_index_state()` |
| キャンペーンコード | `setL2_dsp_campaign_cd_value()` | `setL2_dsp_campaign_cd_enabled()` | `setL2_dsp_campaign_cd_state()` |
| キャンペーン名 | `setL2_wrib_svc_nm_value()` | `setL2_wrib_svc_nm_enabled()` | `setL2_wrib_svc_nm_state()` |
| 適用月 | `setL2_wrib_svc_tstaymd_value()` | `setL2_wrib_svc_tstaymd_enabled()` | `setL2_wrib_svc_tstaymd_state()` |
| 行スタイルクラス | `setL2_line_style_class_value()` | — | `setL2_line_style_class_state()` |
| 行スタイルID | `setL2_line_style_id_value()` | — | `setL2_line_style_id_state()` |

**Notes:**
- `in_value` is cast to `String` for value/state setters and to `Boolean` for enable setters. No null-check or type validation is performed — a mismatched type will throw a `ClassCastException` at runtime.
- The `isSetAsString` parameter exists but is never referenced in the method body. This is a likely code stub left over from a refactoring or an incomplete feature. **It has no effect.**
- Returns `void`. No side effects beyond field assignment.

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

Returns the **Java type** of the data associated with a given key/subkey pair. This is used by the framework to perform type-safe dispatch or validation.

| `key` | `subkey = "value"` | `subkey = "enable"` | `subkey = "state"` |
|---|---|---|---|
| (all six keys) | `String.class` | `Boolean.class` | `String.class` |

**Note:** Again, the row styling fields do not have an `enable` entry and simply fall through to `return null` if queried with `enable` as the subkey.

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

A **static** method that returns an `ArrayList` containing the six recognized field names in Japanese:

```
["明細インデックス", "キャンペーンコード", "キャンペーン名",
 "適用月", "行スタイルクラス", "行スタイルID"]
```

This allows framework code to enumerate all available fields without hard-coding the names.

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

A simple getter/setter for a row index integer. This is used to track the position of this bean's data within a list (e.g., the Nth row of a data table rendered in the JSP).

### Standard Getters/Setters

Each of the 24 field-specific properties (`_value`, `_enabled`, `_state`, `_update`) has a straightforward getter and setter. They perform direct field access with no validation, transformation, or side effects.

## Relationships

### Who Uses This Class (4 inbound connections)

This bean is consumed by four JSP pages:

```mermaid
flowchart TD
    JSP1["CRW034010PJP.jsp"]
    JSP2["CRW034050PJP.jsp"]
    JSP3["CRW034070PJP.jsp"]
    JSP4["CRW034090PJP.jsp"]

    JSP1 --> BEAN
    JSP2 --> BEAN
    JSP3 --> BEAN
    JSP4 --> BEAN

    BEAN --> IID1["X33VDataTypeBeanInterface"]
    BEAN --> IID2["X33VListedBeanInterface"]

    style BEAN fill:#e1f5fe
```

The naming pattern `CRW034010`, `CRW034050`, `CRW034070`, `CRW034090` suggests these are sequential or parallel screens within a campaign management module (module 03407). All four pages share the same data bean structure, implying they render different views or stages of the same campaign entity.

### What This Class Depends On

This class has **no outbound dependencies**. It imports only standard Java packages (`java.io.Serializable`, `java.util.ArrayList`). The only external contracts are the two interfaces it implements (`X33VDataTypeBeanInterface`, `X33VListedBeanInterface`), which it satisfies through its model-data methods.

### Internal Field Relationships

```mermaid
flowchart TD
    BEAN["CRW03407SF03DBean"]

    BEAN --> F1["l2_detail_index<br/>(_update, _value, _enabled, _state)"]
    BEAN --> F2["l2_dsp_campaign_cd<br/>(_update, _value, _enabled, _state)"]
    BEAN --> F3["l2_wrib_svc_nm<br/>(_update, _value, _enabled, _state)"]
    BEAN --> F4["l2_wrib_svc_tstaymd<br/>(_update, _value, _enabled, _state)"]
    BEAN --> F5["l2_line_style_class<br/>(_update, _value, _state)"]
    BEAN --> F6["l2_line_style_id<br/>(_update, _value, _state)"]
    BEAN --> IDX["index (int)"]

    style BEAN fill:#e1f5fe
```

Fields 1–4 follow the four-part pattern. Fields 5–6 (row styling) have no `_enabled` component.

## Usage Example

A typical JSP page or backing controller would interact with this bean through the model-data API:

```java
// Create the bean
CRW03407SF03DBean bean = new CRW03407SF03DBean();

// Set data via dispatch (key / subkey pattern)
bean.storeModelData("キャンペーンコード", "value", "DSP-00123");
bean.storeModelData("キャンペーンコード", "enable", true);
bean.storeModelData("キャンペーン名", "value", "Summer Promotion");
bean.storeModelData("適用月", "value", "202607");

// Read data back via dispatch
Object campaignCode = bean.loadModelData("キャンペーンコード", "value");
// Returns: "DSP-00123"

Boolean editable = bean.loadModelData("キャンペーンコード", "enable");
// Returns: true

// Check the type for a given key/subkey
Class<?> type = bean.typeModelData("キャンペーンコード", "value");
// Returns: String.class

// Get the list of all available field names
ArrayList<String> keys = CRW03407SF03DBean.listKoumokuIds();
// Returns all 6 field names in Japanese
```

Alternatively, direct getter/setter access is available:

```java
bean.setL2_dsp_campaign_cd_value("DSP-00123");
bean.setL2_dsp_campaign_cd_enabled(true);
String value = bean.getL2_dsp_campaign_cd_value();
```

The `index` field is typically set by the rendering framework when the bean represents a row in a table:

```java
bean.setIndex(0);  // First row in the table
```

## Notes for Developers

1. **Japanese key names:** The dispatch methods (`loadModelData`, `storeModelData`, `typeModelData`, `listKoumokuIds`) all use Japanese strings as field identifiers. These are hardcoded literals with no constants. If you need to reference a field name from Java code, you must type the exact Japanese string — there is no `static final` constant defined for them.

2. **No null safety in `storeModelData`:** The method casts `in_value` to `String` or `Boolean` without null checks or type validation. Passing the wrong type will result in a `ClassCastException`. The only guard is a null check on `key` and `subkey` themselves.

3. **Dead `isSetAsString` parameter:** The four-argument overload of `storeModelData` accepts an `isSetAsString` flag that is never used in the method body. It appears to be a vestige of an incomplete refactoring. Do not rely on it having any effect.

4. **Row styling fields lack `enable`:** `行スタイルクラス` (row style class) and `行スタイルID` (row style id) have no `_enabled` property. Calling `loadModelData("行スタイルクラス", "enable")` will return `null` because the dispatch falls through all `if/else` branches.

5. **`gamenId` parameter is unused:** The three-parameter `storeModelData` overload and the four-parameter overload that includes `gamenId` (screen ID) ignore the screen ID entirely. It is passed through and then discarded. This is likely reserved for future multi-screen routing logic.

6. **Thread safety:** This bean is **not thread-safe**. All fields are mutable, and the model-data methods perform direct field writes. In the typical JSP model, one instance per request/session is the norm, so this is not a practical concern unless the bean is shared across threads.

7. **Serializable:** The class implements `Serializable` but defines no `serialVersionUID`. If this bean is ever serialized (e.g., stored in a session), changes to the class structure could cause `InvalidClassException`. Consider adding an explicit `private static final long serialVersionUID` field.

8. **Consistent default values:** All `_value` fields default to `""` (empty string) and all `_enabled` fields default to `false`. This means uninitialized beans will have a predictable state.

9. **The `separaterPoint` variable:** Both `loadModelData` and `storeModelData` declare `int separaterPoint = key.indexOf("/");` but never use it. This is dead code, possibly left over from a planned nested key syntax (e.g., `parent/child` keys) that was never implemented.

10. **Four callers, shared model:** The fact that four different JSP pages (`CRW034010PJP`, `CRW034050PJP`, `CRW034070PJP`, `CRW034090PJP`) all use the same bean strongly suggests a unified data model across multiple screens. New fields added to this bean may need to be supported across all four pages.
