# バッチ設計書 43-ConvertTo-PseudoLocalization.ps1

## 概要

本ドキュメントは、リソースファイル（.resw/.xml）の文字列を擬似ローカライズ（Pseudo-Localization）に変換するPowerShellスクリプト「ConvertTo-PseudoLocalization.ps1」のバッチ設計書である。

### 本バッチの処理概要

指定されたリソースファイル内の文字列を、LocStudioのPseudoReplacementDefs.xmlに準拠した文字マッピングを用いて擬似ローカライズ文字列に変換する。変換後のXMLドキュメントオブジェクトを返却する。.reswファイルと.xmlファイルの両形式に対応している。

**業務上の目的・背景**：擬似ローカライズ（Pseudo-Localization）は、国際化（i18n）対応の品質を検証するための手法である。英語文字列をアクセント付き文字やUnicode特殊文字に置換し、さらに文字列長を40%増加させることで、UIのレイアウト崩れ、文字切れ、ハードコードされた文字列の検出を事前に行う。Windows Terminalでは「qps-ploc」ロケールとしてこの擬似ローカライズリソースを管理している。

**バッチの実行タイミング**：ビルドプロセスの一部として、リソースファイルの変更時に実行される。Generate-PseudoLocalizations.ps1（No.44）から呼び出されることが多い。

**主要な処理内容**：
1. LocStudio準拠の文字マッピングテーブル（a-z、A-Z）を初期化する
2. 入力XMLファイルを読み込む（.reswまたは.xml形式）
3. 各文字列エントリに対して、`{Locked=...}`コメントで指定されたロック文字列をUnicode Private Use Areaのプレースホルダーに置換する
4. キーのSHA1ハッシュをシードとした決定的乱数生成器を用いて、各文字をマッピングテーブルのランダムな対応文字に置換する
5. プレースホルダーを元のロック文字列に復元する
6. 文字列長の40%に相当するパディング文字列（` !!!`パターン）を末尾に追加する
7. .xmlファイルの場合、`_locComment_text`コメントと`_locID`属性を除去する
8. 変換後のXMLドキュメントオブジェクトを返却する

**前後の処理との関連**：Generate-PseudoLocalizations.ps1（No.44）から呼び出され、qps-plocディレクトリ配下のリソースファイルを一括変換する際に使用される。入力はen-USディレクトリの英語リソースファイルである。

**影響範囲**：擬似ローカライズリソースファイルに影響を与える。UIの表示テスト用であり、本番の翻訳リソースには影響しない。

## バッチ種別

コード生成（リソース変換）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（ビルド時・リソース変更時） |
| 実行時刻 | ビルドプロセス依存 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | Generate-PseudoLocalizations.ps1からの呼び出し／手動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| 入力リソースファイルの存在 | Pathパラメータで指定されたパスに.reswまたは.xmlファイルが存在すること |
| PowerShell実行環境 | PowerShellが利用可能であること（System.Security.Cryptography.SHA1が利用可能） |

### 実行可否判定

必須パラメータ（Path）が指定されていること。入力ファイルが.reswまたは.xml形式であること。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| Path | string | Yes | なし | 変換対象のリソースファイルパス（.reswまたは.xml） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| リソースファイル | XML (.resw) | /root/data構造を持つリソースファイル。各data要素にname、value、commentを含む |
| リソースファイル | XML (.xml) | _locID属性を持つ要素を含むXMLファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 戻り値（XmlDocument） | XMLオブジェクト | 擬似ローカライズされたXMLドキュメントオブジェクト |

### 出力ファイル仕様

本スクリプトはファイル出力を直接行わず、XMLドキュメントオブジェクトを返却する。ファイルへの保存は呼び出し元（Generate-PseudoLocalizations.ps1等）が行う。

| 項目 | 内容 |
|-----|------|
| ファイル名 | 呼び出し元が決定 |
| 出力先 | 呼び出し元が決定 |
| 文字コード | 呼び出し元が決定（通常UTF-8 BOMなし） |
| 区切り文字 | 該当なし（XML形式） |

## 処理フロー

### 処理シーケンス

```
1. 文字マッピングテーブル初期化
   └─ a-z, A-Zの各文字に対するUnicode代替文字のハッシュテーブルを作成
2. XMLファイル読み込み
   └─ [System.Xml.XmlDocument]::new()でXMLドキュメントを作成し、Load()で読み込み
   └─ PreserveWhitespace = $true でホワイトスペースを保持
3. ファイル形式の判定
   └─ .reswの場合: /root/data ノードを列挙
   └─ .xmlの場合: //*[@_locID] ノードを列挙
4. 各エントリに対してGetPseudoLocalization関数を実行
   ├─ 4a. {Locked=...}コメントの解析
   │   └─ ロック文字列をUnicode Private Use Area (U+E000～)のプレースホルダーに置換
   │   └─ {Locked}や{Locked=qps-ploc}の場合は元の値をそのまま返却
   ├─ 4b. 決定的乱数生成
   │   └─ キーのSHA1ハッシュからInt32シードを生成
   │   └─ System.Randomインスタンスを作成
   ├─ 4c. 文字置換
   │   └─ 各文字をマッピングテーブルの対応文字にランダム置換
   │   └─ マッピングに存在しない文字はそのまま保持
   ├─ 4d. プレースホルダー復元
   │   └─ Unicode Private Use Areaの文字を元のロック文字列に復元
   └─ 4e. 40%パディング追加
       └─ 文字列長の40%分の「 !!!」パターンを末尾に追加
5. .xml形式の場合の後処理
   └─ _locComment_textコメントの除去
   └─ _locID属性の除去
6. XMLドキュメントオブジェクトの返却
   └─ return $content
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[文字マッピングテーブル初期化]
    B --> C[XMLファイル読み込み]
    C --> D{ファイル形式判定}
    D -->|.resw| E[/root/data ノード列挙]
    D -->|.xml| F[//*_locID ノード列挙]
    E --> G[各エントリにGetPseudoLocalization適用]
    F --> G
    G --> H[Locked文字列をプレースホルダーに置換]
    H --> I[SHA1シードで乱数生成器作成]
    I --> J[文字マッピング置換]
    J --> K[プレースホルダーを元に復元]
    K --> L[40%パディング追加]
    L --> M{.xml形式?}
    M -->|Yes| N[_locComment_text除去・_locID属性除去]
    M -->|No| O[XMLドキュメント返却]
    N --> O
    O --> P[バッチ終了]
```

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

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

本バッチはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | パラメータ不足 | 必須パラメータPathが未指定 | Pathパラメータを指定する |
| N/A | ファイル読み込みエラー | 入力ファイルが存在しないまたは読み取り不可 | ファイルパスと権限を確認する |
| N/A | XML解析エラー | 入力ファイルが不正なXML形式 | 入力ファイルのXML構造を確認する |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（リトライ機構なし） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

エラー発生時はPowerShellの標準エラーが出力される。入力ファイルの形式と内容を確認し、再実行する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし（メモリ内XML操作のみ） |
| コミットタイミング | 該当なし（ファイル保存は呼び出し元が実行） |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1リソースファイル内の全文字列エントリ |
| 目標処理時間 | 数秒以内 |
| メモリ使用量上限 | 特に制限なし（XMLドキュメントサイズに依存） |

## 排他制御

入力ファイルの読み取りのみであり、書き込みは行わないため排他制御は不要。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 標準出力 | なし | スクリプトは標準出力への明示的なログ出力を行わない |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| ビルドエラー | 発生時 | ビルドシステム（CI/CD） |

## 備考

- 文字マッピングはLocStudioのPseudoReplacementDefs.xmlに準拠している。
- SHA1ハッシュをシードとすることで、同一キーに対して常に同じ擬似ローカライズ結果が得られる（決定的）。コメントにもUseRandomizedStringHashAlgorithmへの対策として明記されている。
- `{Locked}`（値なし）と`{Locked=qps-ploc}`の場合は文字列を変換せず元の値をそのまま返す。これはロック指定された文字列やqps-ploc固有の指定を保護するための仕様である。
- ロック文字列の一時置換にUnicode Private Use Area（U+E000～）を使用しており、通常のテキストとの衝突を回避している。
- 40%パディングは国際化テストの標準的な手法で、多くの言語が英語より長い文字列になることをシミュレートする。
- ソースファイルパス: `tools/ConvertTo-PseudoLocalization.ps1`
