# 機能設計書 56-選択パラメータ

## 概要

本ドキュメントは、Jenkinsの選択パラメータ（ChoiceParameterDefinition）機能の設計を記述する。選択パラメータは、事前定義された選択肢リストから1つの値を選択するためのパラメータ型であり、ドロップダウンリストとして表示される。

### 本機能の処理概要

**業務上の目的・背景**：ビルド実行時に、許容される値の範囲を限定したい場合がある。例えば、デプロイ先環境（development/staging/production）、ビルド構成（debug/release）、ターゲットプラットフォーム（windows/linux/mac）など、選択肢が明確に決まっている場合に使用する。自由入力を避けることで、入力ミスを防ぎ、ビルドの一貫性を保つことができる。

**機能の利用シーン**：
- 環境名（dev/staging/prod）を選択してデプロイする際
- ビルド構成（debug/release）を選択する際
- ターゲットブランチを限定された一覧から選択する際
- 特定のオプション値を選択する際

**主要な処理内容**：
1. 選択肢リストの定義（改行区切りまたはリスト形式）
2. ドロップダウン形式の入力UI表示
3. 選択値のバリデーション（選択肢に含まれるか）
4. 選択値からStringParameterValue生成
5. デフォルト値として先頭の選択肢を使用

**関連システム・外部連携**：
- SimpleParameterDefinition: 親クラス
- StringParameterValue: 実際の値を保持するクラス
- Pipeline DSL: `choice`または`choiceParam`シンボルで参照

**権限による制御**：パラメータ入力にはJob.BUILD権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 12 | ジョブ設定 | 主機能 | 選択パラメータの定義 |
| 20 | パラメータ入力 | 主機能 | ドロップダウンリストの表示 |

## 機能種別

データ入力 / パラメータ処理 / バリデーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | String | Yes | パラメータの名前 | 非null |
| choices | String/List | Yes | 選択肢（改行区切り文字列またはリスト） | 空でない、1つ以上の選択肢 |
| description | String | No | パラメータの説明 | - |

### 入力データソース

- ジョブ設定画面: ChoiceParameterDefinitionのconfig.jelly（テキストエリア）
- ビルド実行画面: ChoiceParameterDefinitionのindex.jelly（ドロップダウン）
- CLI/REST API: 選択肢に含まれる文字列値

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| choices | List<String> | 選択肢リスト |
| StringParameterValue | StringParameterValue | 選択されたパラメータ値 |

### 出力先

- XMLファイル: ジョブのconfig.xml内に定義を永続化
- StringParameterValue: ビルドのParametersActionに格納
- 環境変数: ビルド中に`$パラメータ名`で参照可能

## 処理フロー

### 処理シーケンス

```
1. ジョブ設定でChoiceParameterDefinitionを追加
   └─ 選択肢を改行区切りで入力
2. 選択肢の解析
   └─ CHOICES_DELIMITER（\r?\n）で分割してリスト化
3. パラメータ定義の保存
   └─ ジョブのconfig.xmlに永続化
4. ビルド実行時のパラメータ入力
   └─ ドロップダウンリストとして選択肢を表示
5. ユーザー選択処理
   └─ createValue(req, jo)でStringParameterValue生成
6. バリデーション
   └─ isValid()で選択肢に含まれるか確認
7. ビルドへのパラメータ渡し
   └─ ParametersAction経由でビルドに関連付け
```

### フローチャート

```mermaid
flowchart TD
    A[パラメータ入力画面] --> B[ドロップダウン表示]
    B --> C[ユーザーが選択]
    C --> D[選択値を取得]
    D --> E{isValid?}
    E -->|No| F[IllegalArgumentException]
    E -->|Yes| G[StringParameterValue生成]
    F --> B
    G --> H[ビルドに渡す]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-56-01 | 選択肢必須 | 選択肢は1つ以上必須 | 設定保存時 |
| BR-56-02 | デフォルト値 | デフォルト値がない場合、先頭の選択肢がデフォルト | getDefaultParameterValue時 |
| BR-56-03 | 選択値バリデーション | 入力値は選択肢リストに含まれる必要がある | createValue時 |
| BR-56-04 | 改行区切り | 選択肢は改行（\r?\n）で区切る | 設定入力時 |

### 計算ロジック

選択肢の解析:
- `CHOICES_DELIMITER = "\\r?\\n"`: 改行（CR+LF/LF両対応）で分割
- 空の選択肢も許容される（空文字列として保持）

## データベース操作仕様

本機能はデータベースを直接操作しない。

### ファイル永続化

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| パラメータ定義保存 | `jobs/{jobName}/config.xml` | WRITE | ChoiceParameterDefinitionとして保存 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | IllegalArgumentException | 選択値が選択肢に含まれない | エラーメッセージ「Illegal choice for parameter {name}: {value}」を表示 |
| - | FormValidation.error | 選択肢が空 | 「選択肢が必要です」メッセージ表示 |

### リトライ仕様

リトライは行わない。バリデーションエラー時は例外をスロー。

## トランザクション仕様

本機能はトランザクション管理を行わない。

## パフォーマンス要件

- createValue処理: O(n)（選択肢数に比例、isValid()でリスト検索）
- 選択肢リスト取得: O(1)

## セキュリティ考慮事項

- 選択肢は設定者が定義するため、不正な値の注入リスクは低い
- 選択肢に機密情報を含めないことを推奨

## 備考

- Pipeline DSLでは`choice(name: 'ENV', choices: ['dev', 'staging', 'prod'], description: 'Deploy environment')`で定義
- `@Symbol({"choice", "choiceParam"})`で両方のシンボル名をサポート
- newInstance()をオーバーライドしてJSONからの適切なパース処理を実装

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、ChoiceParameterDefinitionのフィールド構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ChoiceParameterDefinition.java | `core/src/main/java/hudson/model/ChoiceParameterDefinition.java` | クラス定義、choicesフィールド |
| 1-2 | SimpleParameterDefinition.java | `core/src/main/java/hudson/model/SimpleParameterDefinition.java` | 親クラスの機能 |

**読解のコツ**: `CHOICES_DELIMITER = "\\r?\\n"`が選択肢区切りの正規表現。CRLFとLFの両方に対応している。

#### Step 2: エントリーポイントを理解する

コンストラクタと選択肢設定メソッドを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ChoiceParameterDefinition.java | `core/src/main/java/hudson/model/ChoiceParameterDefinition.java` | コンストラクタ群、setChoices()メソッド |

**主要処理フロー**:
1. **30行目**: `CHOICES_DELIMITER = "\\r?\\n"`で区切り文字定義
2. **44-48行目**: 文字列からの選択肢設定コンストラクタ
3. **50-54行目**: 配列からの選択肢設定コンストラクタ
4. **71-77行目**: `@DataBoundConstructor`付きコンストラクタ
5. **93-111行目**: `setChoices(Object)`で文字列/リスト両対応の設定
6. **113-115行目**: `setChoicesText()`で改行区切り文字列を解析

#### Step 3: バリデーションを理解する

入力値検証の実装を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ChoiceParameterDefinition.java | `core/src/main/java/hudson/model/ChoiceParameterDefinition.java` | isValid()、checkValue()メソッド |

**主要処理フロー**:
- **150-152行目**: `isValid()`で`choices.contains()`による検証
- **162-166行目**: `checkValue()`で無効値の場合IllegalArgumentException
- **39-42行目**: `areValidChoices()`で静的バリデーション

#### Step 4: Descriptorを理解する

パラメータ型のメタデータと追加バリデーションを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ChoiceParameterDefinition.java | `core/src/main/java/hudson/model/ChoiceParameterDefinition.java` | DescriptorImpl内部クラス |

**主要処理フロー**:
- **204行目**: `@Extension @Symbol({"choice", "choiceParam"})`でシンボル名定義
- **221-226行目**: `newInstance()`でJSONから適切に選択肢をパース
- **231-237行目**: `doCheckChoices()`でフォームバリデーション

### プログラム呼び出し階層図

```
パラメータ入力フォーム送信
    │
    ├─ ChoiceParameterDefinition.createValue(req, jo)
    │      │
    │      └─ req.bindJSON(StringParameterValue.class, jo)
    │
    ├─ checkValue()
    │      │
    │      └─ isValid()
    │             │
    │             └─ choices.contains(value)
    │                    │
    │                    ├─ true: StringParameterValue返却
    │                    └─ false: IllegalArgumentException
    │
    └─ setDescription()
```

### データフロー図

```
[入力]                    [処理]                         [出力]

config.jelly          setChoicesText()                choices
(テキストエリア) ───▶  (改行で分割)           ───▶    List<String>
      │
      ▼
index.jelly           ChoiceParameterDefinition       StringParameterValue
(ドロップダウン) ───▶  .createValue()          ───▶    .value
      │                      │
      ▼                      ▼
選択値               isValid()                      環境変数
                     (選択肢チェック)               $パラメータ名
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ChoiceParameterDefinition.java | `core/src/main/java/hudson/model/ChoiceParameterDefinition.java` | ソース | 選択パラメータ定義 |
| StringParameterValue.java | `core/src/main/java/hudson/model/StringParameterValue.java` | ソース | 選択値（文字列として格納） |
| SimpleParameterDefinition.java | `core/src/main/java/hudson/model/SimpleParameterDefinition.java` | ソース | 親クラス |
| config.jelly | `core/src/main/resources/hudson/model/ChoiceParameterDefinition/config.jelly` | ビュー | 設定フォーム（テキストエリア） |
| index.jelly | `core/src/main/resources/hudson/model/ChoiceParameterDefinition/index.jelly` | ビュー | 入力フォーム（ドロップダウン） |
| Messages.properties | `core/src/main/resources/hudson/model/Messages.properties` | リソース | エラーメッセージ定義 |
