# Eo / Common

## Overview

The `eo.common` package is the foundational shared-library layer for the EO customer foundation system (顧客基幹システム). It sits at the base of the application architecture, providing utilities and constants that every other module — from the I/O dispatch layer to the contract management service layer and beyond — depends on. Without `eo.common`, the rest of the system has no shared vocabulary of string literals, encoding rules, business codes, or string manipulation helpers.

The module has no classes, interfaces, or methods of its own. Instead, it is a namespace that holds two child packages:

| Package | Role |
|---|---|
| [`eo.common.constant`](Source/koptCommon/src/eo/common/constant/) | Centralized constants — magic strings, numeric codes, and fixed text used across the entire application |
| [`eo.common.util`](Source/koptCommon/src/eo/common/util/) | String utility helpers — null-safe guards and byte-length-aware truncation for legacy Japanese encoding |

Together these sub-modules form the **shared vocabulary** of the system. Constants answer "what are the valid values?" while utilities answer "how do we safely handle strings that may be null or contain multi-byte characters?"

## Sub-module Guide

### Constant — the shared code dictionary

The [`constant`](Source/koptCommon/src/eo/common/constant/) package is the single source of truth for every literal and numeric code in the application. Instead of scattering "magic" strings like `"A0"` (Set-Top Box device type) or `"A05"` (1G pricing plan) across service classes, every consumer references a `public static final` field here. This design means a change — adding a new pricing plan code, updating a record type, or migrating from Shift_JIS to UTF-8 — happens in one place.

The package contains three constant classes, organized by domain layer:

| Class | Domain | Typical consumer |
|---|---|---|
| [`JDKStrConst`](Source/koptCommon/src/eo/common/constant/JDKStrConst.java) | Infrastructure — file I/O, encodings, device types, logistics statuses | I/O layer, dispatch services |
| [`JKKStrConst`](Source/koptCommon/src/eo/common/constant/JKKStrConst.java) | Business domain — pricing plans, service categories, contract statuses, display text | Service layer, UI layer, contract management |
| [`JPCModelConstant`](Source/koptCommon/src/eo/common/constant/JPCModelConstant.java) | Model layer — function codes, search error flags, DB/transaction error codes | Model/DAO layer, error handling |

**How they relate:** The three classes form a vertical slice through the application architecture:

- `JDKStrConst` lives at the bottom, describing *how* data moves (file formats, encodings, device IDs).
- `JKKStrConst` sits in the middle, describing *what* the business offers (plans, services, statuses).
- `JPCModelConstant` sits above, describing *what went wrong* (error codes, function routing).

A single service method might import all three: it reads a file using `JDKStrConst` encoding, looks up a pricing plan from `JKKStrConst`, and returns an error code from `JPCModelConstant`. This triad is the pattern.

### Util — the string safety net

The [`util`](Source/koptCommon/src/eo/common/util/) package provides a single class, [`JKKStringUtil`](Source/koptCommon/src/eo/common/util/JKKStringUtil.java), with static helper methods. Its responsibilities fall into two categories:

1. **Null-safe string inspection and transformation** — methods like `isNullBlank`, `nullToBlank`, and `nullToSpace` prevent `NullPointerException` in a codebase where null string fields are common (e.g., customer names, optional addresses). These are the first line of defense against null-pointer crashes.

2. **Byte-length-aware truncation** — the `subStringByte` method cuts strings to a fixed byte count while respecting Shift_JIS / EUC-JP character widths. This is critical because the system exchanges data with legacy Japanese applications where truncating at a character boundary could produce invalid multi-byte sequences.

**How it relates to constant:** `util` is the only consumer of `eo.common` that has any operational logic at all. While `constant` provides *what the values are*, `util` provides *how to safely process them*. For example, when `JDKStrConst` defines `ENCODE_SJIS` as `"Shift_JIS"`, the `subStringByte` method is the tool that ensures data written with that encoding remains valid when truncated to fit a database column.

## Key Patterns and Architecture

### Constant-class pattern

All three constant classes follow the same structural pattern:

```
private constructor()  // prevents instantiation
  public static final FIELDS  // accessible via class name
```

This makes the classes pure namespace containers — no state, no side effects. They can be referenced from anywhere in the application without concern for object lifecycle or thread safety.

### Domain segregation by prefix

The `JDK` / `JKK` / `JPC` prefixes are not arbitrary. They map to the architectural layer each class serves:

- **JDK** = infrastructure/kernel (low-level mechanics)
- **JKK** = contract management (business domain)
- **JPC** = persistence/model (error codes and routing)

When adding new constants, developers should choose the class whose prefix matches the domain of the new value.

### Error code range convention

`JPCModelConstant` organizes error codes into numbered ranges that indicate the error domain:

| Range | Domain |
|---|---|
| 0–9 | Function codes |
| 1–5 | Search error flags |
| 0–4 | Result codes |
| 1000–1450 | Schema validation |
| 2000 | Search limits |
| 6000–6100 | External IF errors |
| 8011–8023 | DB errors |
| 8051–8076 | Request context errors |
| 8900 | Fatal template error |

This convention means a developer can glance at an error code and immediately know which subsystem to investigate.

### Null-guard triad

`JKKStringUtil` provides three increasingly strict null checks:

| Method | Checks |
|---|---|
| `isNullBlank` | `null` or `""` |
| `isNullSpace` | `null`, `""`, or whitespace-only |
| `isNullEmpty` | `null`, `""`, or empty `ArrayList` |

The progression reflects the real-world need for different levels of string emptiness detection. `isNullBlank` is the most frequently used guard in the codebase; the others exist for edge cases where whitespace or collection emptiness also matter.

### Byte-length truncation

The `subStringByte` method implements a character-by-character byte counter that classifies characters as 1-byte or 2-byte based on their Unicode range. This is the safest way to truncate strings destined for Shift_JIS / EUC-JP fields, because it ensures the result is a valid prefix of the source encoding. The trade-off is that it is O(n) in string length — acceptable for the infrequent truncation calls, but worth noting for performance-sensitive paths.

```mermaid
flowchart TD
    A["start subStringByte str, len"] --> B["dstlen 0, i 0"]
    B --> C{"i less than str.length?"}
    C -->|no| D["return str unchanged"]
    C -->|yes| E["count bytes for char"]
    E --> F{"1 or 2 bytes?"}
    F -->|ASCII, Yen sign, half-kana| G["dstlen plus 1"]
    F -->|Kanji, full-width, others| H["dstlen plus 2"]
    G --> I{"dstlen greater than len?"}
    H --> I
    I -->|yes| J["return str.substring 0, i"]
    I -->|no| K["i increment"]
    K --> C
```

### File transmission workflow

The constants in `JDKStrConst` describe a file-based dispatch protocol used to exchange data between systems:

```mermaid
flowchart TD
    A["Template definition .def file"] --> B["Read and parse"]
    B --> C["Write CSV data records"]
    C --> D["Tag each record with type code"]
    D --> E["Move file to send or error directory"]
    E --> F["Environment variable resolves path"]
    F --> G["External system receives file"]
```

Each `.def` file defines the layout of a corresponding `.csv` data file. Records are tagged with numeric type codes (`"0"` for header, `"1"` for data, `"9"` for trailer) that the receiving system uses to parse sections. The directory paths are resolved from environment variables at runtime, making the system configurable without code changes.

## Dependencies and Integration

This module has no internal package dependencies — it imports only standard Java libraries. It is a leaf node in the dependency tree, consumed by every other layer:

```mermaid
flowchart TD
    A["Service / Controller
layer"] --> B["JKKStrConst"]
    A --> C["JPCModelConstant"]
    D["I/O layer"] --> E["JDKStrConst"]
    D --> F["JKKStringUtil.subStringByte"]
    G["UI layer"] --> B
    G --> H["Fixed text strings"]
    I["Model / DAO
layer"] --> C
    I --> J["DB error handling
search flags"]
    E --> K["File dispatch
transmission
record type codes"]
    B --> L["Contract routing
pricing lookups"]
```

### External consumers

- **Service / Controller layer** — reads pricing plans, service categories, and function codes to route requests
- **Model / DAO layer** — uses DB error codes and search error flags for error handling
- **I/O layer** — uses file names, record type codes, and encoding constants for dispatch file transmission
- **UI layer** — uses fixed Japanese text strings for labels, messages, and form fields

### Package dependencies

| Dependency | Type | Used by |
|---|---|---|
| `java.util.ArrayList` | Standard library | `JKKStringUtil.isNullEmpty()` |
| `java.util.Arrays`, `java.util.List` | Standard library | `JKKStrConst` |

No other application packages are imported. The module is self-contained.

## Notes for Developers

### Adding constants

1. **Choose the right class.** Infrastructure → `JDKStrConst`, business domain → `JKKStrConst`, model layer → `JPCModelConstant`.
2. **Follow the naming convention.** Use `public static final` fields with descriptive names in UPPER_SNAKE_CASE.
3. **Add add markers.** Wrap new constant blocks with `// ANK-XXXX-00-00 ADD START` / `ADD END` comments, mirroring the existing revision history pattern.
4. **For pricing plans,** add to the `CD00134` section in `JKKStrConst` using the next available alphabetical code.

### Gotchas

- **Japanese encoding.** Many files use `Shift_JIS`. Ensure file I/O respects this encoding, especially for dispatch files. The `subStringByte` method assumes Shift_JIS / EUC-JP semantics — do not use it for UTF-8 data (where multi-byte characters are 3–4 bytes, not 2).
- **Preserved typo.** `JPCModelConstant.SAERCH_TYPE_IKT` has a misspelling in the field name (`SAERCH` instead of `SEARCH`). This must not be changed for backward compatibility.
- **Large file.** `JKKStrConst.java` is approximately 6,800 lines. Use file search rather than scanning the whole file when looking for a specific constant.
- **Private constructors.** All three constant classes have private constructors. They cannot be instantiated, extended, or mocked in the usual way. Static reflection or direct static access is required for testing.
- **Environment variables.** Directory constants (`MID_DIR_DK`, `GAIBU_SEND_DIR_DK`, etc.) are resolved from runtime environment variables, not hardcoded values. Changing their values requires environment configuration, not code changes.
- **`isNullEmpty` uses raw types.** The method casts to raw `ArrayList` and suppresses the unchecked warning. In new code, prefer `instanceof List<?>` for type safety and broader applicability.

### Encoding summary

| Constant | Encoding | Use case |
|---|---|---|
| `ENCODE_SJIS` / `ENCODE_SJIS2` | `Shift_JIS` | Legacy file I/O, dispatch CSV files |
| `CHAR_SET_SJIS` | `Shift_JIS` | Standard Japanese encoding |
| `CHAR_SET_WIN31J` | `Windows-31J` | Windows Japanese (Java alias for Shift_JIS) |
| `CHAR_SET_UTF8` | `UTF-8` | Universal encoding |
| `CHAR_SET_EUC` | `EUC-JP` | EUC Japanese |
| `CHAR_SET_JIS` | `ISO-2022-JP` | JIS encoding |

When in doubt, `ENCODE_SJIS` is the default for dispatch and legacy file operations.

### Cross-module references

- **Service contract lifecycle:** Defined by `SVC_KEI_STAT_*` constants in `JDKStrConst`, mirrored for billing/ops by `SEIOPSVC_KEI_STAT_*` in `JKKStrConst`.
- **Price plan hierarchy:** `CD00133` (group) contains `CD00134` (individual plans). Each plan is identified by a short code (`A05`, `AB0`, etc.) and encodes product family, speed tier, customer type, and add-ons.
- **Device type taxonomy:** `JDKStrConst` defines hex-like device codes (`"A0"` for STB, `"B0"` for B-CAS, `"F0"` for Router) used across dispatch and logistics operations.
