PlantUMLソースコードリーディング(1)

# 概要

[PlantUML](https://plantuml.com/ja/) の仕様をソースコードから分析したくなったため、現時点（2020/01/03）でどのような設計で実装しているのか追いかけるための足ががりとなるポイントをまとめておく。（個別のPlantUMLのコマンド実装の設計については別記事で書いていきたい）

# ソースコードリポジトリ

https://github.com/plantuml/plantuml

# 大まかな構造

`net.sourceforge.plantuml.Run` の実行時に受け取った文字列またはファイル内容のPlantUML用の文字列を解析処理に渡す処理がある。以下の順番で呼ばれる。

1. [net.sourceforge.plantuml.Run#main()](https://github.com/plantuml/plantuml/blob/099843c8307b4fc97d88f99a8fab3ee5a4b9a20c/src/net/sourceforge/plantuml/Run.java#L85)
1. [net.sourceforge.plantuml.Run#manageAllFiles()](https://github.com/plantuml/plantuml/blob/099843c8307b4fc97d88f99a8fab3ee5a4b9a20c/src/net/sourceforge/plantuml/Run.java#L85)
1. [net.sourceforge.plantuml.Run#processArgs()](https://github.com/plantuml/plantuml/blob/099843c8307b4fc97d88f99a8fab3ee5a4b9a20c/src/net/sourceforge/plantuml/Run.java#L85)
1. [net.sourceforge.plantuml.Run#manageFileInternal()](https://github.com/plantuml/plantuml/blob/099843c8307b4fc97d88f99a8fab3ee5a4b9a20c/src/net/sourceforge/plantuml/Run.java#L546-L548)
1. [net.sourceforge.plantuml.BlockUml#getDiagram()](https://github.com/plantuml/plantuml/blob/099843c8307b4fc97d88f99a8fab3ee5a4b9a20c/src/net/sourceforge/plantuml/BlockUml.java#L163)
1. [net.sourceforge.plantuml.PSystemBuilder#createPSystem()](https://github.com/plantuml/plantuml/blob/099843c8307b4fc97d88f99a8fab3ee5a4b9a20c/src/net/sourceforge/plantuml/PSystemBuilder.java#L128)
1. [net.sourceforge.plantuml.PSystemBuilder#getAllFactories()](https://github.com/plantuml/plantuml/blob/099843c8307b4fc97d88f99a8fab3ee5a4b9a20c/src/net/sourceforge/plantuml/PSystemBuilder.java#L153)

ここで、`net.sourceforge.plantuml.PSystemBuilder#getAllFactories()` の処理で各モジュール（文字解析）が初期化されている。
Factoryを定義する際に、文字を解析するための文字パターンを各モジュールのどこかで定義している。
例えば、 [`colors` というPlantUMLのコマンド](http://www.plantuml.com/plantuml/uml/SoWkIImgAStDuKhEpyalAkPoICrB0N81) の正規表現は以下の部分で定義されている。

[ソースコード](https://github.com/plantuml/plantuml/blob/099843c8307b4fc97d88f99a8fab3ee5a4b9a20c/src/net/sourceforge/plantuml/eggs/PSystemColorsFactory.java#L48)

```java
public class PSystemColorsFactory extends PSystemSingleLineFactory {

	@Override
	protected AbstractPSystem executeLine(String line) {
		final Pattern pattern = Pattern.compile("^colors?\\s*(#?\\w+)?\\s*$");
		final Matcher matcher = pattern.matcher(line);
		if (matcher.matches()) {
			return new PSystemColors(matcher.group(1));
		}
		return null;
	}

}
```

[シーケンス図を表示するPlantUMLのコマンド](http://www.plantuml.com/plantuml/uml/SoWkIImgAStDuNBCoKnELT2rKt3AJx9IS2mjoKZDAybCJYp9pCzJ24ejB4qjBk42oYde0jM05MDHLLoGdrUSoeLkM5u-K5sHGY9sGo6ARNHr8QeJSQc66kwGcfS2SZ00)は以下の辺りで実装している。

[ソースコード](https://github.com/plantuml/plantuml/blob/099843c8307b4fc97d88f99a8fab3ee5a4b9a20c/src/net/sourceforge/plantuml/sequencediagram/SequenceDiagramFactory.java#L94)

```java
public class SequenceDiagramFactory extends PSystemCommandFactory {

	// ...中略 ...

	@Override
	protected List<Command> createCommands() {

		final List<Command> cmds = new ArrayList<Command>();

		addCommonCommands1(cmds);

		cmds.add(new CommandActivate());
		cmds.add(new CommandDeactivateShort());

		cmds.add(new CommandParticipantA());
		cmds.add(new CommandParticipantA2());
		cmds.add(new CommandParticipantA3());
		cmds.add(new CommandParticipantA4());
		cmds.add(new CommandArrow());
		// ... 中略 ...
	}
}
```

矢印でノードおよび関係を定義する正規表現は [この辺り](https://github.com/plantuml/plantuml/blob/099843c8307b4fc97d88f99a8fab3ee5a4b9a20c/src/net/sourceforge/plantuml/sequencediagram/command/CommandArrow.java#L79-L116) で実装していると思われる。

# まとめ

* PlantUMLの実装解析についてのとっかかりとなる部分を記載
* src/net/sourceforge/plantuml/モジュール名 という階層構造で整理されている
* 機能が多い分、文字解析用のモジュールが多く読み解くのは大変