# 機能設計書 53-ルートアクション

## 概要

本ドキュメントは、JenkinsのRootAction（ルートアクション）機能の設計を記述する。RootActionは、Jenkinsのルートレベル（トップページ）に新しいアクションを追加するための拡張ポイントであり、プラグインがJenkinsのメインナビゲーションに機能を追加する手段を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Jenkinsは多くのプラグインによって機能拡張されるが、それらの機能にアクセスするためのエントリーポイントが必要である。RootActionは、Jenkinsのトップレベルにメニュー項目やリンクを追加し、プラグインが提供する機能への導線を確保する。これにより、ユーザーはJenkinsのサイドバーやヘッダーからプラグイン機能に直接アクセスできるようになる。

**機能の利用シーン**：
- プラグインがJenkinsのサイドバーに新しいメニュー項目を追加する際
- 管理画面へのショートカットを追加する際
- カスタムダッシュボードやレポートページを提供する際
- システム監視やヘルスチェック機能を追加する際

**主要な処理内容**：
1. `RootAction`インターフェースの実装と`@Extension`による登録
2. アクションのURL、アイコン、表示名の提供
3. Staplerによるリクエストルーティング
4. バッジ表示機能（通知数等の視覚的インジケータ）
5. プライマリアクション指定（ヘッダー常時表示）

**関連システム・外部連携**：
- Stapler: URLルーティングとリクエスト処理
- Jelly/Groovy: ビュー（ページ）のレンダリング
- 拡張機構（ExtensionList）: RootActionの自動発見・登録

**権限による制御**：RootAction自体は権限制御を提供しない。各実装クラスが`getIconFileName()`でnullを返すことでメニュー非表示とするか、Staplerのアクセスチェックで権限制御を行う。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | ダッシュボード（View一覧） | 主機能 | RootActionがサイドバーに表示される |
| 28 | Jenkins管理 | 参照画面 | 管理系RootActionへの導線 |

## 機能種別

UI拡張 / ナビゲーション / 拡張ポイント

## 入力仕様

### 入力パラメータ

RootActionインターフェースの実装に必要なメソッド:

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | インターフェースとしての入力はなし | - |

### 入力データソース

- Jenkinsの拡張機構: `@Extension`アノテーション付きRootAction実装クラス
- HTTPリクエスト: Staplerがルーティングするリクエスト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| iconFileName | String | サイドバーに表示するアイコンのパス（nullで非表示） |
| displayName | String | サイドバーに表示する名前 |
| urlName | String | アクションのURLパス（Jenkinsルートからの相対） |
| badge | Badge | バッジ情報（通知数等、オプション） |
| isPrimaryAction | boolean | ヘッダー常時表示するかどうか |

### 出力先

- サイドバー: Jenkinsの左側ナビゲーションメニュー
- ヘッダー: プライマリアクションの場合、ヘッダー領域に表示
- URLエンドポイント: `{JenkinsRoot}/{urlName}`でアクセス可能

## 処理フロー

### 処理シーケンス

```
1. Jenkins起動時のRootAction登録
   └─ ExtensionListがRootAction実装を発見
2. ページレンダリング時のサイドバー構築
   └─ 各RootActionのgetIconFileName()をチェック
3. アクション表示判定
   └─ nullでなければサイドバーに追加
4. ユーザーによるアクションクリック
   └─ StaplerがgetUrlName()に基づきルーティング
5. アクションページの表示
   └─ RootAction実装のビュー（index.jelly等）をレンダリング
```

### フローチャート

```mermaid
flowchart TD
    A[Jenkinsページ表示] --> B[サイドバー構築]
    B --> C[RootAction一覧取得]
    C --> D{各RootActionをループ}
    D --> E{getIconFileName != null?}
    E -->|Yes| F[サイドバーに追加]
    E -->|No| G[スキップ]
    F --> H{isPrimaryAction?}
    H -->|Yes| I[ヘッダーにも追加]
    H -->|No| J[サイドバーのみ]
    G --> D
    I --> D
    J --> D
    D -->|完了| K[サイドバー表示]
    K --> L[ユーザーがクリック]
    L --> M[Staplerルーティング]
    M --> N[RootActionのビュー表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-53-01 | URL一意性 | urlNameはJenkinsルート内で一意 | 常時 |
| BR-53-02 | 非表示制御 | iconFileNameがnullの場合、メニュー非表示 | ページ表示時 |
| BR-53-03 | プライマリ表示 | isPrimaryAction=trueならヘッダー常時表示 | v2.516以降 |
| BR-53-04 | バッジ表示 | getBadge()がnullでなければバッジを表示 | v2.507以降 |

### 計算ロジック

特になし。表示/非表示はgetIconFileName()の戻り値のみで判定。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | Not Found | urlNameに対応するリソースが見つからない | エラーページ表示 |
| 403 | Forbidden | アクションへのアクセス権限がない | アクセス拒否画面表示 |

### リトライ仕様

リトライは行わない。

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

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

## パフォーマンス要件

- RootAction一覧取得: O(n)（登録数に比例）
- 個々のRootActionメソッド呼び出し: O(1)

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

- RootAction実装は、必要に応じて独自の権限チェックを実装すべき
- 機密情報を扱うアクションはACLによるアクセス制御を推奨
- Staplerの自動ルーティングにより、意図しないメソッド公開に注意

## 備考

- RootActionはActionインターフェースを継承しており、getIconFileName()、getDisplayName()、getUrlName()を実装する
- v2.507でバッジ機能、v2.516でプライマリアクション機能が追加された

---

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

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

### 推奨読解順序

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

まず、RootActionインターフェースの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RootAction.java | `core/src/main/java/hudson/model/RootAction.java` | インターフェース定義、継承関係 |
| 1-2 | Action.java | `core/src/main/java/hudson/model/Action.java` | 親インターフェースの定義 |

**読解のコツ**: RootActionはActionを継承し、ExtensionPointをマーカーとして持つ。これによりプラグインから拡張可能になっている。

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

RootActionがどのように登録・利用されるかを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RootAction.java | `core/src/main/java/hudson/model/RootAction.java` | @Extensionとの組み合わせ |
| 2-2 | Jenkins.java | `core/src/main/java/jenkins/model/Jenkins.java` | RootActionの取得と利用 |

**主要処理フロー**:
1. **42行目**: `RootAction extends Action, ExtensionPoint`の定義
2. **50-52行目**: `getBadge()`メソッドでバッジ取得（v2.507以降）
3. **64-66行目**: `isPrimaryAction()`メソッドでヘッダー表示判定（v2.516以降）

#### Step 3: バッジ機能を理解する

v2.507で追加されたバッジ機能の詳細を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RootAction.java | `core/src/main/java/hudson/model/RootAction.java` | getBadge()のデフォルト実装 |
| 3-2 | Badge.java | `core/src/main/java/jenkins/management/Badge.java` | Badgeクラスの構造 |

**主要処理フロー**:
- **50-52行目**: `getBadge()`はデフォルトでnullを返す（バッジなし）
- Badgeはアクションボタンに表示される視覚的インジケータ

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

```
Jenkins（ページ表示）
    │
    ├─ ExtensionList.lookup(RootAction.class)
    │      │
    │      └─ 全RootAction実装を取得
    │
    ├─ sidepanel.jelly（サイドバー構築）
    │      │
    │      └─ RootAction.getIconFileName()
    │      └─ RootAction.getDisplayName()
    │      └─ RootAction.getUrlName()
    │      └─ RootAction.getBadge()
    │      └─ RootAction.isPrimaryAction()
    │
    └─ Stapler（リクエストルーティング）
           │
           └─ /jenkins/{urlName} → RootAction実装
```

### データフロー図

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

@Extension              ExtensionList                  サイドバー
RootAction実装  ───▶    (自動発見・登録) ───▶         メニュー項目
                             │                              │
                             ▼                              ▼
                     Jenkins.getActions()              Staplerルート
                             │                         /{urlName}
                             ▼
                     サイドバー構築
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RootAction.java | `core/src/main/java/hudson/model/RootAction.java` | ソース | ルートアクションインターフェース |
| Action.java | `core/src/main/java/hudson/model/Action.java` | ソース | 親インターフェース |
| Badge.java | `core/src/main/java/jenkins/management/Badge.java` | ソース | バッジクラス |
| Jenkins.java | `core/src/main/java/jenkins/model/Jenkins.java` | ソース | RootActionの登録先 |
| sidepanel.jelly | `core/src/main/resources/lib/layout/sidepanel.jelly` | ビュー | サイドバー表示 |
