# 機能設計書 72-Java言語サポート

## 概要

本ドキュメントは、Doom EmacsにおけるJava言語の開発サポート機能について記述する。Javaソースファイルの編集、Android開発サポート、Groovyサポート、LSP統合によるコード補完・デバッグ機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Javaはエンタープライズ開発やAndroidアプリケーション開発において主要な言語である。Emacs上でJava開発を効率的に行うためには、高度なコード補完、エラー検出、デバッグ機能が必要となる。本モジュールはlsp-javaを中心とした統合開発環境を提供し、Java開発者の生産性向上を目的としている。

**機能の利用シーン**：Javaプロジェクト（Maven、Gradle）の開発時に、ソースコードの編集、クラス・パッケージ名の自動検出、テストの実行・デバッグ、Androidレイアウトファイルの編集などの場面で利用される。

**主要な処理内容**：
1. java-modeおよびjava-ts-modeによるJavaソースファイルの編集サポート
2. lsp-javaによるLanguage Server Protocol統合（コード補完、リファクタリング、エラー検出）
3. dap-javaによるデバッグサポート（ブレークポイント、ステップ実行）
4. android-modeによるAndroid開発サポート
5. groovy-modeによるGradle/Groovyスクリプトサポート
6. パッケージ名・クラス名の自動検出機能

**関連システム・外部連携**：
- Eclipse JDT Language Server: Java Language Server
- DAP (Debug Adapter Protocol): デバッグサポート
- Android SDK: Android開発ツール

**権限による制御**：特になし。ただし、JDKおよびLanguage Serverがシステムにインストールされている必要がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | Javaソースバッファ | 主画面 | Javaファイルの編集、テスト実行 |
| - | *lsp-java*バッファ | 結果表示画面 | LSPサーバーログ |
| - | Groovyバッファ | 補助画面 | Gradleスクリプト編集 |

## 機能種別

言語サポート / 開発環境統合

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| +lsp | フラグ | No | LSPサポートを有効化 | doom!ブロックで指定 |
| +tree-sitter | フラグ | No | Tree-sitterサポートを有効化 | doom!ブロックで指定 |

### 入力データソース

- Javaソースファイル（*.java）
- Gradleビルドファイル（build.gradle, *.gradle）
- Groovyスクリプト（*.groovy）
- AndroidManifest.xml

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| パッケージ名 | 文字列 | +java-current-package関数が返すパッケージ名 |
| クラス名 | 文字列 | +java-current-class関数が返すクラス名 |
| テスト結果 | テキスト | dap-java経由のテスト実行結果 |

### 出力先

- LSP補完候補: ミニバッファまたは補完UI
- エラー/警告: flycheckまたはflymakeオーバーレイ
- デバッグ情報: dap-modeバッファ

## 処理フロー

### 処理シーケンス

```
1. Javaファイルを開く
   └─ java-mode または java-ts-mode が起動
2. LSPモード有効時
   └─ lsp! が呼び出され、Eclipse JDT Language Serverに接続
3. Androidプロジェクト検出
   └─ AndroidManifest.xml の存在を確認し、android-mode を有効化
4. パッケージ/クラス名検出
   └─ +java-project-package-roots に基づきパス解析
```

### フローチャート

```mermaid
flowchart TD
    A[Javaファイルを開く] --> B{+tree-sitter?}
    B -->|Yes| C[java-ts-mode起動]
    B -->|No| D[java-mode起動]
    C --> E{+lsp?}
    D --> E
    E -->|Yes| F[lsp-java有効化]
    E -->|No| G[基本編集モード]
    F --> H{Android?}
    G --> H
    H -->|Yes| I[android-mode有効化]
    H -->|No| J[開発作業]
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | パッケージルート検出 | java/, test/, main/, src/ またはディレクトリ深度でパッケージルートを特定 | +java-current-package 実行時 |
| BR-02 | Android検出 | AndroidManifest.xml または src/main/AndroidManifest.xml の存在でAndroidプロジェクト判定 | java-mode, groovy-mode, nxml-mode フック時 |
| BR-03 | プロジェクトルート | build.gradle, gradlew の存在でプロジェクトルートを特定 | projectile 使用時 |

### 計算ロジック

**パッケージ名計算**:
- `+java-project-package-roots` に基づき、ファイルパスからパッケージ名を導出
- ディレクトリ区切りを `.` に変換（例: `src/main/java/com/example/` → `com.example`）

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

### 操作別データベース影響一覧

データベース操作なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | user-error | java-mode以外で+java-current-package実行 | "Not in java-mode or java-ts-mode" メッセージ表示 |
| - | user-error | パッケージ名を推定できない | "Can't deduce package name" メッセージ表示 |
| - | user-error | クラス名を推定できない | "Can't deduce the class name" メッセージ表示 |

### リトライ仕様

リトライ機能なし

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

トランザクション管理なし

## パフォーマンス要件

- lsp-javaのワークスペースディレクトリは `doom-profile-data-dir` 内に配置
- インデックス作成はLanguage Serverの初回起動時に非同期で実行

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

- LSPワークスペースは `doom-profile-data-dir/java-workspace` に保存される
- デバッグセッション中のデータはメモリ内で処理

## 備考

- lsp-java は lsp-treemacs に暗黙的に依存しているため、自動的にインストールされる
- Emacs 29.1+ で java-ts-mode が利用可能

---

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

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

### 推奨読解順序

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

パッケージルート検出のための変数定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config.el | `modules/lang/java/config.el` | +java-project-package-roots 変数の定義 |

**読解のコツ**: この変数はリストまたは整数を含み、パッケージ名導出のルールを定義する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | config.el | `modules/lang/java/config.el` | モジュール全体の設定構造 |
| 2-2 | +lsp.el | `modules/lang/java/+lsp.el` | LSP関連設定 |

**主要処理フロー**:
1. **3-18行目**: `+java-project-package-roots` 変数定義
2. **20-21行目**: projectileにGradleプロジェクトルートファイルを追加
3. **27-29行目**: +lsp かつ非eglot時に `+lsp.el` をロード

#### Step 3: LSP統合を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | +lsp.el | `modules/lang/java/+lsp.el` | lsp-javaとdap-javaの設定 |

**主要処理フロー**:
- **4-13行目**: `lsp-java` パッケージ設定、ワークスペースディレクトリ設定
- **8-9行目**: java-modeとjava-ts-modeにlsp!フックを追加
- **16-27行目**: `dap-java` デバッグサポート設定

#### Step 4: ユーティリティ関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | autoload/java.el | `modules/lang/java/autoload/java.el` | パッケージ名・クラス名検出関数 |

**主要処理フロー**:
- **36-70行目**: `+java-current-package` - ファイルパスからパッケージ名を導出
- **73-82行目**: `+java-current-class` - ファイル名からクラス名を導出
- **85-89行目**: `+java/open-groovy-repl` - Groovy REPL起動

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

```
java-mode / java-ts-mode
    │
    ├─ +lsp フラグ有効時
    │      ├─ lsp-java
    │      │      └─ Eclipse JDT Language Server 接続
    │      └─ dap-java (デバッガ有効時)
    │             ├─ dap-java-run-test-class
    │             └─ dap-java-debug-test-class
    │
    ├─ android-mode
    │      └─ +java-android-mode-maybe-h
    │             └─ AndroidManifest.xml 検出
    │
    └─ groovy-mode
           ├─ set-docsets!
           ├─ set-eval-handler!
           └─ set-repl-handler! → +java/open-groovy-repl
```

### データフロー図

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

Javaソースファイル ───▶ java-mode/java-ts-mode ───▶ シンタックスハイライト
        │                      │
        │                      ▼
        └────────────▶ lsp-java ───────────────────▶ コード補完/エラー検出
                              │
                              ▼
                       dap-java ───────────────────▶ デバッグ情報
                              │
ファイルパス ─────────▶ +java-current-package ─────▶ パッケージ名文字列
                              │
ファイル名 ──────────▶ +java-current-class ────────▶ クラス名文字列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.el | `modules/lang/java/config.el` | ソース | モジュール設定、android-mode、groovy-mode設定 |
| +lsp.el | `modules/lang/java/+lsp.el` | ソース | LSP/DAP統合設定 |
| autoload/java.el | `modules/lang/java/autoload/java.el` | ソース | パッケージ/クラス名検出、REPL起動 |
| autoload/lsp.el | `modules/lang/java/autoload/lsp.el` | ソース | LSP関連ユーティリティ |
| packages.el | `modules/lang/java/packages.el` | ソース | 依存パッケージ定義 |
| doctor.el | `modules/lang/java/doctor.el` | ソース | 環境診断スクリプト |
