読者です 読者をやめる 読者になる 読者になる

techium

このブログは何かに追われないと頑張れない人たちが週一更新をノルマに技術情報を発信するブログです。もし何か調査して欲しい内容がありましたら、@kobashinG or @muchiki0226 までいただけますと気が向いたら調査するかもしれません。

Intellij Ideaプラグインでモジュール生成時にフォルダ/ファイルを作成する

Intellijでセットアップウィザードを作成を前回行いました。

blog.techium.jp

そこでセットアップウィザードを終えたあとにプロジェクトフォルダにファイルの自動生成を行う方法をご説明します。

前回のセットアップウィザードで使用したコードのSampleModuleBuilderを拡張して利用します。
SampleModuleBuilderは前回はModuleBuilderを使っていましたが今回作りたいプロジェクトはJavaアプリ用のためなのでJavaModuleBuilderに継承を変更します。
まずJavaModuleBuilderを継承したときgetModuleTypeをOverrideし、SampleModuleTypeを返却できるようにします。

[SampleModuleBuilder.java]

public class SampleModuleBuilder extends JavaModuleBuilder {
    @NotNull
    @Override
    public ModuleType getModuleType() {
        return SampleModuleType.getInstance();
    }
}

これでこちらが作成したModuleTypeをBuilderが利用してくれるようになります。
この状態でビルドして実行すると次のようなフォルダ構成を生成してくれます。

<プロジェクト名>
├── src
└── <プロジェクト名>.iml

JavaModuleBuilderの方でsrcのフォルダ作成は行ってくれます。
それではプロジェクト生成した時にsrc内にフォルダとファイルを作成してみましょう。

ファイルの生成は次のコードのように実装します。

[SampleModuleBuilder.java]

public class SampleModuleBuilder extends JavaModuleBuilder implements ModuleBuilderListener {
    @Override
    public void setupRootModel(ModifiableRootModel modifiableRootModel) throws ConfigurationException {
        addListener(this);
        super.setupRootModel(modifiableRootModel);
    }

    @NotNull
    @Override
    public ModuleType getModuleType() {
        return SampleModuleType.getInstance();
    }

    @Override
    public void moduleCreated(@NotNull Module module) {
        ApplicationManager.getApplication().runWriteAction(new Runnable() {
            @Override
            public void run() {
                try {
                    VirtualFile baseDir = module.getProject().getBaseDir();
                    if (baseDir != null) {
                        VirtualFile src = baseDir.findChild("src");
                        VirtualFile main = src.createChildDirectory(this, "main");
                        VirtualFile test = main.createChildData(this, "test.java");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

ModuleBuilderListenerをimplementsしてmoduleCreatedの実装を行います。
moduleCreatedはモジュールが作成された際に呼び出されるメソッドでsetupRootModelでaddListenerでthisを指定することでコールバックされるようになります。
addListenerはJavaModuleBuilderの継承元であるModuleBuilderに定義されておりそこで登録されます。

moduleCreatedでApplicationManager.getApplication().runWriteActionと呼び出しています。
これはおそらくファイル書き込みなどの書き込みアクションを行うものだと思われます。(資料無しコメント無しのため他のプラグインのコードから読み取ったので自自信がありませんが…)
ここでファイル制御を行います。
moduleCreatedの引数のModuleにはこのモジュール自体の情報が付与されています。
今回はプロジェクト情報をを取り出し、そのベースのURLに紐づくVirtualFileを取り出しています。
VirtualFileはIntellijのプラットフォームが表現するファイルシステムの仮想ファイルのことで仮想ファイルを作成とか削除とかリネームなどを行うと実際のファイルもその操作に応じた動きを行ったりします。
module.getProject().getBaseDir()でプロジェクトのベースのVirtualFileを取得することができます。
このVirtualFile内にはsrcとプロジェクト名のimlファイルが入っています。 そしてbaseDir.findChild("src")でJavaMoudleBuilderが作成したsrcフォルダのVirtualFileを取得することができます。
src.createChildDirectory(this, "main")を使ってsrcフォルダ内にmainというフォルダを作成し、main.createChildData(this, "test.java")を使ってtest.javaをmain内に作成しています。

これを実行すると下記のようなフォルダ構成になります。

<プロジェクト名>
├── src
│   └── main
│       └── test.java
└── <プロジェクト名>.iml

これでプロジェクト作成時に思い通りにフォルダ、ファイルの生成ができるようになります。