java-itamae 基本設計

# プロジェクトの目的

プロパティファイルを読込み、ファイルに定義されたプロパティのキーと値に従って動作を実行するコマンドラインツールを作成する。

## リポジトリ

[java-itamae](https://github.com/JhonnyBravo/java-itamae)

## 参考とするプロジェクト

[itamae](https://github.com/itamae-kitchen/itamae)

# CLI 基本設計
## CLI 引数

```bash
java -jar ./java-itamae.jar --path path --encoding encoding
```

|オプション名称|説明|指定必須|
|---|---|---|
|--path, -p path|読込対象とするプロパティファイルのパスを指定する。|O|
|--encoding, -e encoding|読込対象とするプロパティファイルの文字エンコーディングを指定する。|X|

## 処理の流れ

```mermaid
stateDiagram-v2
  getArgs:CLI 引数解析
  args:CLI 引数
  getProperties:プロパティファイル読込
  convertToFileResourceModel:FileResourceModel 生成
  convertToDirectoryResourceModel:DirectoryResourceModel 生成
  convertToTemplateResourceModel:TemplateResourceModel 生成
  FileResource:File Resource
  DirectoryResource:Directory Resource
  TemplateResource:Template Resource
  state validateArgs <<choice>>
  state validateResourceName <<choice>>
  state validateTermCode <<choice>>
  errorTermination:異常終了
  normalTermination:正常終了

  [*] --> getArgs
  args --> getArgs
  getArgs --> validateArgs
  validateArgs --> getProperties:path != null
    getProperties --> validateResourceName
      validateResourceName --> convertToFileResourceModel:resourceName == file
        convertToFileResourceModel --> FileResource
        FileResource --> validateTermCode
      validateResourceName --> convertToDirectoryResourceModel:resourceName == directory
        convertToDirectoryResourceModel --> DirectoryResource
        DirectoryResource --> validateTermCode
      validateResourceName --> convertToTemplateResourceModel:resourceName == template
        convertToTemplateResourceModel --> TemplateResource
        TemplateResource --> validateTermCode
      validateResourceName --> errorTermination:resourceName != file && resourceName != directory && resourceName != template
  validateArgs --> errorTermination:path == null
  validateTermCode --> normalTermination:termCode != 1
    normalTermination --> [*]
  validateTermCode --> errorTermination:termCode == 1
    errorTermination --> [*]
```

1. CLI 引数 ``--path, -p path`` が指定されていることを確認する。
  1a. ``--path, -p path`` が指定されていない場合、エラーメッセージを出力して異常終了する。
  1b. ``--path, -p path`` に指定されたプロパティファイルが存在しない場合、エラーメッセージを出力して異常終了する。
  1c. 上記に該当しない場合、 ``--path, -p path`` に指定されたパスを変数 ``{path}`` に設定して後続処理へ遷移する。
2. CLI 引数 ``--encoding, -e encoding`` が指定されているかどうかを確認する。
  2a. ``--encoding, -e encoding`` が指定されていない場合、 OS のデフォルト文字エンコーディングを変数 ``{encoding}`` に設定して後続処理へ遷移する。
  2b. ``--encoding, -e encoding`` に不正な文字エンコーディングが指定されている場合、エラーメッセージを出力して異常終了する。
  2c. ``--encoding, -e encoding`` に有効な文字エンコーディングが指定されている場合、指定された文字エンコーディングを変数 ``{encoding}`` に設定して後続処理へ遷移する。
3. 変数 ``{path}`` に設定されたプロパティファイルを読み込む。読込時に使用する文字エンコーディングは変数 ``{encoding}`` に設定された値を適用する。
4. プロパティファイルのキー ``resourceName`` が指定されていることを確認する。
  4a. ``resourceName`` の値として ``file`` が指定されている場合、 ``<<FileResourceModel>>`` を生成し、 [File Resource](#file-resource) を実行する。
  4b. ``resourceName`` の値として ``directory`` が指定されている場合、 ``<<DirectoryResourceModel>>`` を生成し、 [Directory Resource](#directory-resource) を実行する。
  4c. ``resourceName`` の値として ``template`` が指定されている場合、 ``<<TemplateResourceModel>>`` を生成し、 [Template Resource](#template-resource) を実行する。
  4d. ``resourceName`` が指定されていない場合、または ``resourceName`` に無効な値が指定されている場合、エラーメッセージを出力して異常終了する。

## クラス設計

以下参照。

* [CLI 引数の解析](https://qiita.com/JhonnyBravo/items/77c52aaf7a1079b5d692#cli-%E5%BC%95%E6%95%B0%E3%81%AE%E8%A7%A3%E6%9E%90)
* [Resource クラス設計](https://qiita.com/JhonnyBravo/items/77c52aaf7a1079b5d692#resource-%E3%82%AF%E3%83%A9%E3%82%B9%E8%A8%AD%E8%A8%88)

# File Resource
## 実現する機能

```mermaid
flowchart TB
  FileResource([File Resource])
  createFile([ファイル作成])
  deleteFile([ファイル削除])
  updateOwner([所有者変更])
  updateGroup([グループ所有者変更])
  updateMode([パーミッション変更])
  FileResource---|action == create|createFile
  FileResource---|action == delete|deleteFile
  updateOwner-.->|owner != null|createFile
  updateGroup-.->|group != null|createFile
  updateMode-.->|mode != null|createFile
```

プロパティファイルを読込み、定義に従って以下の動作を実行する。

|機能名称|処理内容|条件|
|---|---|---|
|ファイル作成|ファイルを作成する。|action == create|
|ファイル削除|ファイルを削除する。|action == delete|
|所有者変更|ファイルの所有者を変更する。|action == create && owner != null|
|グループ所有者変更|ファイルのグループ所有者を変更する。|action == create && group != null|
|パーミッション変更|ファイルのパーミッション設定値を変更する。|action == create && mode != null|

## プロパティファイルのキー項目

|キー名称|説明|取り得る値|
|---|---|---|
|resourceName|リソース名称を指定する。|file|
|action|実行する動作を指定する。|create, delete|
|path|操作対象とするファイルのパスを指定する。|ファイルパス|
|owner|ファイル所有者として設定するユーザ名を指定する。|ユーザ名|
|group|ファイルのグループ所有者として設定するグループ名を指定する。|グループ名|
|mode|ファイルのパーミッション設定値を Unix 形式の 3 桁の数列で指定する。|パーミッション設定値|

## 処理の流れ

```mermaid
stateDiagram-v2
  properties:プロパティファイル
  convertToModel:FileResourceModel 生成
  createFile:ファイル作成
  deleteFile:ファイル削除
  state validateAction <<choice>>
  state validateTermCode <<choice>>
  errorTermination:異常終了
  normalTermination:正常終了

  [*] --> convertToModel
  properties --> convertToModel
  convertToModel --> validateAction
  validateAction --> createFile:action == create
    createFile --> validateTermCode
  validateAction --> deleteFile:action == delete
    deleteFile --> validateTermCode
  validateAction --> errorTermination:action != create && action != delete
  validateTermCode --> normalTermination:termCode != 1
    normalTermination --> [*]
  validateTermCode --> errorTermination:termCode == 1
    errorTermination --> [*]
```

### FileResourceModel 生成

プロパティファイルに定義されたキーと値を基に ``<<FileResourceModel>>`` を生成する。

|``<<FileResourceModel>>``|設定内容|バリデーションチェック|
|---|---|---|
|resourceName|固定値 ``file`` を設定する。|-|
|action|プロパティファイルのキー ``action`` に指定されている値を設定する。|キーの値が ``create`` または ``delete`` であること。|
|path|プロパティファイルのキー ``path`` に指定されている値を設定する。|キーの値が ``null`` ではないこと。|
|owner|プロパティファイルのキー ``owner`` に指定されている値を設定する。|-|
|group|プロパティファイルのキー ``group`` に指定されている値を設定する。|-|
|mode|プロパティファイルのキー ``mode`` に指定されている値を設定する。|0 から 7 の整数 3 桁で構成された数列であること。|

バリデーションチェックに抵触した場合、エラーメッセージを出力して異常終了する。

### ファイル作成

```mermaid
stateDiagram-v2
  resourceModel:FileResourceModel
  createFile:ファイル作成
  updateOwner:所有者変更
  updateGroup:グループ所有者変更
  updateMode:パーミッション設定変更
  state validateOwner <<choice>>
  state validateGroup <<choice>>
  state validateMode <<choice>>
  state validateTermCode <<choice>>
  errorTermination:異常終了
  normalTermination:正常終了

  [*] --> createFile
  resourceModel --> createFile
  createFile --> validateOwner
    validateOwner --> updateOwner:termCode != 1 && owner != null
      updateOwner --> validateGroup
  createFile --> validateGroup
    validateGroup --> updateGroup:termCode != 1 && group != null
      updateGroup --> validateMode
  createFile --> validateMode
    validateMode --> updateMode:termCode != 1 && mode != null
      updateMode --> validateTermCode
  validateTermCode --> normalTermination:termCode != 1
    normalTermination --> [*]
  validateTermCode --> errorTermination:termCode == 1
    errorTermination --> [*]
```

1. ``<<FileResourceModel.path>>`` に指定されたファイルパスが存在するかどうか確認する。
  1a. ファイルが既に存在する場合、変数 ``{termCode}`` へ 0 を設定する。
  1b. ファイルが存在しない場合、ファイルを新規作成して変数 ``{termCode}`` へ 2 を設定する。
  1c. ファイルの作成中にエラー(例: 作成先ディレクトリの操作権限を持っていない場合)が発生した場合、変数 ``{termCode}`` へ 1 を設定する。
2. 変数 ``{termCode}`` の値を確認する。
  2a. ``{termCode}`` の値が 1 である場合、異常終了する。
  2b. 上記に該当しない場合、後続処理へ遷移する。
3. ``<<FileResourceModel.owner>>`` の値が指定されているかどうか確認する。
  3a. 指定されている場合、 [所有者の変更](#所有者の変更) を実行する。
  3b. 上記に該当しない場合、後続処理へ遷移する。
4. 変数 ``{termCode}`` の値を確認する。
  4a. ``{termCode}`` の値が 1 である場合、異常終了する。
  4b. 上記に該当しない場合、後続処理へ遷移する。
5. ``<<FileResourceModel.group>>`` の値が指定されているかどうか確認する。
  5a. 指定されている場合、 [グループ所有者の変更](#グループ所有者の変更) を実行する。
  5b. 上記に該当しない場合、後続処理へ遷移する。
6. 変数 ``{termCode}`` の値を確認する。
  6a. ``{termCode}`` の値が 1 である場合、異常終了する。
  6b. 上記に該当しない場合、後続処理へ遷移する。
7. ``<<FileResourceModel.mode>>`` の値が指定されているかどうか確認する。
  7a. 指定されている場合、 [パーミッション設定の変更](#パーミッション設定の変更) を実行する。
  7b. 上記に該当しない場合、後続処理へ遷移する。
8. 変数 ``{termCode}`` の値を確認する。
  8a. ``{termCode}`` の値が 1 である場合、異常終了する。
  8b. 上記に該当しない場合、正常終了する。

### ファイル削除

```mermaid
stateDiagram-v2
  resourceModel:FileResourceModel
  deleteFile:ファイル削除
  state validateTermCode <<choice>>
  errorTermination:異常終了
  normalTermination:正常終了

  [*] --> deleteFile
  resourceModel --> deleteFile
  deleteFile --> validateTermCode
  validateTermCode --> normalTermination:termCode != 1
    normalTermination --> [*]
  validateTermCode --> errorTermination:termCode == 1
    errorTermination --> [*]
```

1. ``<<FileResourceModel.path>>`` に指定されたファイルパスが存在するかどうか確認する。
  1a. ファイルが存在しない場合、変数 ``{termCode}`` へ 0 を設定する。
  1b. ファイルが存在する場合、ファイルを削除して変数 ``{termCode}`` へ 2 を設定する。
  1c. ファイルの削除中にエラー(例: ファイルの削除権限を持っていない場合)が発生した場合、変数 ``{termCode}`` へ 1 を設定して異常終了する。
2. 変数 ``{termCode}`` の値を確認する。
  2a. 変数 ``{termCode}`` の値が 1 である場合、異常終了する。
  2b. 上記に該当しない場合、正常終了する。

### クラス設計

下記を参照。

* [FileResourceModel](https://qiita.com/JhonnyBravo/items/77c52aaf7a1079b5d692#fileresourcemodel)
* [FileResourceImpl](https://qiita.com/JhonnyBravo/items/77c52aaf7a1079b5d692#fileresourceimpl)

# Directory Resource
## 実現する機能

```mermaid
flowchart TB
  DirectoryResource([Directory Resource])
  createDirectory([ディレクトリ作成])
  deleteDirectory([ディレクトリ削除])
  updateOwner([所有者変更])
  updateGroup([グループ所有者変更])
  updateMode([パーミッション変更])
  DirectoryResource---createDirectory
  DirectoryResource---deleteDirectory
  updateOwner-.->|owner != null|createDirectory
  updateGroup-.->|group != null|createDirectory
  updateMode-.->|mode != null|createDirectory
```

プロパティファイルを読込み、定義に従って以下の動作を実行する。

|機能名称|処理内容|条件|
|---|---|---|
|ディレクトリ作成|ディレクトリを作成する。|action == create|
|ディレクトリ削除|ディレクトリを削除する。|action == delete|
|所有者変更|ディレクトリの所有者を変更する。|action == create && owner != null|
|グループ所有者変更|ディレクトリのグループ所有者を変更する。|action == create && group != null|
|パーミッション変更|ディレクトリのパーミッション設定値を変更する。|action == create && mode != null|

## プロパティファイルのキー項目

|キー名称|説明|取り得る値|
|---|---|---|
|resourceName|リソース名称を指定する。|directory|
|action|実行する動作を指定する。|create, delete|
|path|操作対象とするディレクトリのパスを指定する。|ディレクトリパス|
|owner|ディレクトリ所有者として設定するユーザ名を指定する。|ユーザ名|
|group|ディレクトリのグループ所有者として設定するグループ名を指定する。|グループ名|
|mode|ディレクトリのパーミッション設定値を Unix 形式の 3 桁の数列で指定する。|パーミッション設定値|

## 処理の流れ

```mermaid
stateDiagram-v2
  properties:プロパティファイル
  convertToModel:DirectoryResourceModel 生成
  createDirectory:ディレクトリ作成
  deleteDirectory:ディレクトリ削除
  state validateAction <<choice>>
  state validateTermCode <<choice>>
  errorTermination:異常終了
  normalTermination:正常終了

  [*] --> convertToModel
  properties --> convertToModel
  convertToModel --> validateAction
  validateAction --> createDirectory:action == create
    createDirectory --> validateTermCode
  validateAction --> deleteDirectory:action == delete
    deleteDirectory --> validateTermCode
  validateAction --> errorTermination:action != create && action != delete
  validateTermCode --> normalTermination:termCode != 1
    normalTermination --> [*]
  validateTermCode --> errorTermination:termCode == 1
    errorTermination --> [*]
```

### DirectoryResourceModel 生成

プロパティファイルに定義されたキーと値を基に ``<<DirectoryResourceModel>>`` を生成する。

|``<<DirectoryResourceModel>>``|設定内容|バリデーションチェック|
|---|---|---|
|resourceName|固定値 ``directory`` を設定する。|-|
|action|プロパティファイルのキー ``action`` に指定されている値を設定する。|キーの値が ``create`` または ``delete`` であること。|
|path|プロパティファイルのキー ``path`` に指定されている値を設定する。|キーの値が ``null`` ではないこと。|
|owner|プロパティファイルのキー ``owner`` に指定されている値を設定する。|-|
|group|プロパティファイルのキー ``group`` に指定されている値を設定する。|-|
|mode|プロパティファイルのキー ``mode`` に指定されている値を設定する。|0 から 7 の整数 3 桁で構成された数列であること。|

バリデーションチェックに抵触した場合、エラーメッセージを出力して異常終了する。

### ディレクトリ作成

```mermaid
stateDiagram-v2
  resourceModel:DirectoryResourceModel
  createDirectory:ディレクトリ作成
  updateOwner:所有者変更
  updateGroup:グループ所有者変更
  updateMode:パーミッション設定変更
  state validateOwner <<choice>>
  state validateGroup <<choice>>
  state validateMode <<choice>>
  state validateTermCode <<choice>>
  errorTermination:異常終了
  normalTermination:正常終了

  [*] --> createDirectory
  resourceModel --> createDirectory
  createDirectory --> validateOwner
    validateOwner --> updateOwner:termCode != 1 && owner != null
      updateOwner --> validateGroup
  createDirectory --> validateGroup
    validateGroup --> updateGroup:termCode != 1 && group != null
      updateGroup --> validateMode
  createDirectory --> validateMode
    validateMode --> updateMode:termCode != 1 && mode != null
      updateMode --> validateTermCode
  validateTermCode --> normalTermination:termCode != 1
    normalTermination --> [*]
  validateTermCode --> errorTermination:termCode == 1
    errorTermination --> [*]
```

1. ``<<DirectoryResourceModel.path>>`` に指定されたディレクトリパスが存在するかどうか確認する。
  1a. ディレクトリが既に存在する場合、変数 ``{termCode}`` へ 0 を設定する。
  1b. ディレクトリが存在しない場合、ディレクトリを新規作成して変数 ``{termCode}`` へ 2 を設定する。
  1c. ディレクトリの作成中にエラー(例: 作成先親ディレクトリの操作権限を持っていない場合)が発生した場合、変数 ``{termCode}`` へ 1 を設定する。
2. 変数 ``{termCode}`` の値を確認する。
  2a. ``{termCode}`` の値が 1 である場合、異常終了する。
  2b. 上記に該当しない場合、後続処理へ遷移する。
3. ``<<DirectoryResourceModel.owner>>`` の値が指定されているかどうか確認する。
  3a. 指定されている場合、 [所有者の変更](#所有者の変更) を実行する。
  3b. 上記に該当しない場合、後続処理へ遷移する。
4. 変数 ``{termCode}`` の値を確認する。
  4a. ``{termCode}`` の値が 1 である場合、異常終了する。
  4b. 上記に該当しない場合、後続処理へ遷移する。
5. ``<<DirectoryResourceModel.group>>`` の値が指定されているかどうか確認する。
  5a. 指定されている場合、 [グループ所有者の変更](#グループ所有者の変更) を実行する。
  5b. 上記に該当しない場合、後続処理へ遷移する。
6. 変数 ``{termCode}`` の値を確認する。
  6a. ``{termCode}`` の値が 1 である場合、異常終了する。
  6b. 上記に該当しない場合、後続処理へ遷移する。
7. ``<<DirectoryResourceModel.mode>>`` の値が指定されているかどうか確認する。
  7a. 指定されている場合、 [パーミッション設定の変更](#パーミッション設定の変更) を実行する。
  7b. 上記に該当しない場合、後続処理へ遷移する。
8. 変数 ``{termCode}`` の値を確認する。
  8a. ``{termCode}`` の値が 1 である場合、異常終了する。
  8b. 上記に該当しない場合、正常終了する。

### ディレクトリ削除

```mermaid
stateDiagram-v2
  resourceModel:DirectoryResourceModel
  deleteDirectory:ディレクトリ削除
  state validateTermCode <<choice>>
  errorTermination:異常終了
  normalTermination:正常終了

  [*] --> deleteDirectory
  resourceModel --> deleteDirectory
  deleteDirectory --> validateTermCode
  validateTermCode --> normalTermination:termCode != 1
    normalTermination --> [*]
  validateTermCode --> errorTermination:termCode == 1
    errorTermination --> [*]
```

1. ``<<DirectoryResourceModel.path>>`` に指定されたディレクトリパスが存在するかどうか確認する。
  1a. ディレクトリが存在しない場合、変数 ``{termCode}`` へ 0 を設定する。
  1b. ディレクトリが存在する場合、ディレクトリを削除して変数 ``{termCode}`` へ 2 を設定する。
  1c. ディレクトリの削除中にエラー(例: ディレクトリの削除権限を持っていない場合)が発生した場合、変数 ``{termCode}`` へ 1 を設定して異常終了する。
2. 変数 ``{termCode}`` の値を確認する。
  2a. 変数 ``{termCode}`` の値が 1 である場合、異常終了する。
  2b. 上記に該当しない場合、正常終了する。

### クラス設計

下記を参照。

* [DirectoryResourceModel](https://qiita.com/JhonnyBravo/items/77c52aaf7a1079b5d692#directoryresourcemodel)
* [DirectoryResourceImpl](https://qiita.com/JhonnyBravo/items/77c52aaf7a1079b5d692#directoryresourceimpl)

## 所有者の変更

1. ``<<ResourceModel.path>>`` に指定されたファイルまたはディレクトリから現在の所有者を取得し、変数 ``{curOwner}`` へ設定する。
2. ``<<ResourceModel.owner>>`` の値と変数 ``{curOwner}`` の値を比較する。
  2a. ``<<ResourceModel.owner>>`` の値と変数 ``{curOwner}`` の値が同一である場合、変数 ``{termCode}`` へ 0 を設定する。
  2b. ``<<ResourceModel.owner>>`` の値と変数 ``{curOwner}`` の値が異なる場合、 ``<<ResourceModel.path>>`` に指定されたファイルまたはディレクトリの所有者を ``{curOwner}`` へ更新して変数 ``{termCode}`` へ 2 を設定する。
  2c. 所有者の更新中にエラー(例: 存在しないユーザ名が ``<<ResourceModel.owner>>`` に指定されている場合)が発生した場合、変数 ``{termCode}`` へ 1 を設定する。

## グループ所有者の変更

1. ``<<ResourceModel.path>>`` に指定されたファイルまたはディレクトリから現在のグループ所有者を取得し、変数 ``{curGroup}`` へ設定する。
2. ``<<ResourceModel.group>>`` の値と変数 ``{curGroup}`` の値を比較する。
  2a. ``<<ResourceModel.group>>`` の値と変数 ``{curGroup}`` の値が同一である場合、変数 ``{termCode}`` へ 0 を設定する。
  2b. ``<<ResourceModel.group>>`` の値と変数 ``{curGroup}`` の値が異なる場合、 ``<<ResourceModel.path>>`` に指定されたファイルまたはディレクトリのグループ所有者を ``{curGroup}`` へ更新して変数 ``{termCode}`` へ 2 を設定する。
  2c. グループ所有者の更新中にエラー(例: 存在しないグループ名が ``<<ResourceModel.group>>`` に指定されている場合)が発生した場合、変数 ``{termCode}`` へ 1 を設定する。

## パーミッション設定の変更

1. ``<<ResourceModel.path>>`` に指定されたファイルまたはディレクトリから現在のパーミッション設定値を取得し、変数 ``{curMode}`` へ設定する。
2. ``<<ResourceModel.mode>>`` の値と変数 ``{curMode}`` の値を比較する。
  2a. ``<<ResourceModel.mode>>`` の値と変数 ``{curMode}`` の値が同一である場合、変数 ``{termCode}`` へ 0 を設定する。
  2b. ``<<ResourceModel.mode>>`` の値と変数 ``{curMode}`` の値が異なる場合、 ``<<ResourceModel.path>>`` に指定されたファイルまたはディレクトリのパーミッション設定値を ``{curMode}`` へ更新して変数 ``{termCode}`` へ 2 を設定する。
  2c. パーミッション設定値の更新中にエラー(例: 操作権限を持たないファイルまたはディレクトリのパスが ``<<ResourceModel.path>>`` に指定されている場合)が発生した場合、変数 ``{termCode}`` へ 1 を設定する。

# Template Resource
## 実現する機能

```mermaid
flowchart TB
  TemplateResource([Template Resource])
  readContents([ファイル内容読込])
  updateContents([ファイル内容更新])
  deleteContents([ファイル内容削除])
  updateContents-.->|include|readContents
  deleteContents-.->|include|readContents
  TemplateResource---|action == create|updateContents
  TemplateResource---|action == delete|deleteContents
```

プロパティファイルを読込み、定義に従って以下の動作を実行する。

|機能名称|処理内容|条件|
|---|---|---|
|ファイル内容更新|ファイルの内容を更新する。 ``source`` に指定されたファイルの内容を読込み、 ``path`` に指定されたファイルへ書込む。|action == create|
|ファイル内容削除|ファイルの内容を削除する。|action == delete|

## プロパティファイルのキー項目

|キー名称|説明|取り得る値|
|---|---|---|
|resourceName|リソース名称を指定する。|template|
|action|実行する動作を指定する。|create, delete|
|path|書込み対象とするファイルのパスを指定する。|ファイルパス|
|source|読込み対象とするファイルのパスを指定する。|ファイルパス|
|encoding|ファイルの読書きに使用するファイルエンコーディングを指定する。|エンコーディング名称|

## 処理の流れ

```mermaid
stateDiagram-v2
  properties:プロパティファイル
  convertToModel:TemplateResourceModel 生成
  updateContents:ファイル内容更新
  deleteContents:ファイル内容削除
  state validateAction <<choice>>
  state validateTermCode <<choice>>
  errorTermination:異常終了
  normalTermination:正常終了

  [*] --> convertToModel
  properties --> convertToModel
  convertToModel --> validateAction
  validateAction --> updateContents:action == create
    updateContents --> validateTermCode
  validateAction --> deleteContents:action == delete
    deleteContents --> validateTermCode
  validateAction --> errorTermination:action != create && action != delete
  validateTermCode --> normalTermination:termCode != 1
    normalTermination --> [*]
  validateTermCode --> errorTermination:termCode == 1
    errorTermination --> [*]
```

### TemplateResourceModel 生成

プロパティファイルに定義されたキーと値を基に ``<<TemplateResourceModel>>`` を生成する。

|``<<TemplateResourceModel>>``|設定内容|バリデーションチェック|
|---|---|---|
|resourceName|固定値 ``template`` を設定する。|-|
|action|プロパティファイルのキー ``action`` に指定されている値を設定する。|キーの値が ``create`` または ``delete`` であること。|
|path|プロパティファイルのキー ``path`` に指定されている値を設定する。|キーの値が ``null`` ではないこと。|
|source|プロパティファイルのキー ``source`` に指定されている値を設定する。|キー ``action`` の値が ``create`` である場合に、キー ``source`` の値が ``null`` ではないこと。|
|encoding|プロパティファイルのキー ``encoding`` に指定されている値を設定する。 ``encoding`` の指定が無い場合、 OS のデフォルト文字エンコーディングを適用する。|-|

バリデーションチェックに抵触した場合、エラーメッセージを出力して異常終了する。

### ファイル内容の更新

```mermaid
stateDiagram-v2
  sourceFile:読込元ファイル(TemplateResourceModel.source)
  targetFile:書込先ファイル(TemplateResourceModel.path)
  readContents:ファイル内容読込
  updateContents:ファイル内容更新
  state validateTermCode <<choice>>
  errorTermination:異常終了
  normalTermination:正常終了

  [*] --> readContents
  sourceFile --> readContents
  readContents --> updateContents
  targetFile --> updateContents
  updateContents --> validateTermCode
  validateTermCode --> normalTermination:termCode != 1
    normalTermination --> [*]
  validateTermCode --> errorTermination:termCode == 1
    errorTermination --> [*]
```

1. ``<<TemplateResourceModel.path>>`` に指定されたファイルパスが存在するかどうか確認する。
  1a. ファイルが存在しない場合、変数 ``{termCode}`` へ 1 を設定して異常終了する。
  1b. ファイルが存在する場合、後続処理へ遷移する。
2. ``<<TemplateResourceModel.source>>`` に指定されたファイルパスが存在するかどうか確認する。
  2a. ファイルが存在しない場合、変数 ``{termCode}`` へ 1 を設定して異常終了する。
  2b. ファイルが存在する場合、後続処理へ遷移する。
3. ``<<TemplateResourceModel.source>>`` に指定されたファイルの内容を読込む。
  3a. 読込中にエラーが発生した場合、変数 ``{termCode}`` へ 1 を設定して異常終了する。
  3b. 読込に成功した場合、取得したファイルの内容を変数 ``{srcContents}`` へ設定して後続処理へ遷移する。
4. ``<<TemplateResourceModel.path>>`` に指定されたファイルへ変数 ``{srcContents}`` の内容を上書きする。
  4a. 書込中にエラーが発生した場合、変数 ``{termCode}`` へ 1 を設定して異常終了する。
  4b. 書込に成功した場合、変数 ``{termCode}`` へ 2 を設定して正常終了する。

### ファイル内容の削除

```mermaid
stateDiagram-v2
  targetFile:書込先ファイル(TemplateResourceModel.path)
  readContents:ファイル内容読込
  deleteContents:ファイル内容削除
  state validateContents <<choice>>
  state validateTermCode <<choice>>
  errorTermination:異常終了
  normalTermination:正常終了

  [*] --> readContents
  targetFile --> readContents
  readContents --> validateContents
  validateContents --> normalTermination:contents.isEmpty() == true
  validateContents --> deleteContents:contents.isEmpty() != true
  deleteContents --> validateTermCode
  validateTermCode --> normalTermination:termCode != 1
    normalTermination --> [*]
  validateTermCode --> errorTermination:termCode == 1
    errorTermination --> [*]
```

1. ``<<TemplateResourceModel.path>>`` に指定されたファイルパスが存在するかどうか確認する。
  1a. ファイルが存在しない場合、変数 ``{termCode}`` へ 1 を設定して異常終了する。
  1b. ファイルが存在する場合、後続処理へ遷移する。
2. ``<<TemplateResourceModel.path>>`` に指定されたファイルの内容を読込む。
  2a. 読込中にエラーが発生した場合、変数 ``{termCode}`` へ 1 を設定して異常終了する。
  2b. 読込に成功した場合、取得したファイルの内容を変数 ``{dstContents}`` へ設定して後続処理へ遷移する。
3. 変数 ``{dstContents}`` に設定されたファイル内容が空であるかどうか確認する。
  3a. ファイルの内容が空である場合、変数 ``termCode`` へ 0 を設定して正常終了する。
  3b. ファイルの内容が空ではない場合、後続処理へ遷移する。
4. ``<<TemplateResourceModel.path>>`` に指定されたファイルの内容を全削除する。
  4a. 削除中にエラーが発生した場合、変数 ``{termCode}`` へ 1 を設定して異常終了する。
  4b. 削除に成功した場合、変数 ``{termCode}`` へ 2 を設定して正常終了する。

### クラス設計
下記を参照。

* [TemplateResourceModel](https://qiita.com/JhonnyBravo/items/77c52aaf7a1079b5d692#templateresourcemodel)
* [TemplateResourceImpl](https://qiita.com/JhonnyBravo/items/77c52aaf7a1079b5d692#templateresourceimpl)