minimize

事業拡大のため、新しい仲間を募集しています。
→詳しくはこちら

Builderについて

Nature のところでちょっと説明した Builder についての詳細です。
あるプロジェクトの Nature 内で Builder を定義すると、
プロジェクト内のファイルが保存されるタイミングで毎回 Builder が実行されます。
また、プロジェクトのフルビルド時にも呼び出されます。

Builder の実装メソッドはたった一つです。

@Override
protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
        throws CoreException {
}

色々引数が渡されてきますが、特に使わなくても大丈夫です(笑)。
通常使うのは、2つのメソッドだけです。
とりあえず簡単な例を載せてみます。

@Override
protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
        throws CoreException {
    
    IProject project = getProject();
    IResourceDelta delta = getDelta(project);
    if (delta != null) {
        taskDelta(delta);
    } else {
        taskResource(project);
    }
    return new IProject[] { project };
}

このように、getProject()getDelta(project) さえあれば事足ります。
ここで取得した delta にはビルドが必要な全ツリー情報が格納されています。
フルビルドの場合これは null なので、代わりに project から全ツリー情報を取得します。
簡単な実装例は以下のようになります。

private void taskResource(IResource resource) throws CoreException {
    if (resource instanceof IContainer) {
        IContainer container = (IContainer)resource;
        for (IResource child : container.members()) {
            taskResource(child);
        }
    } else {
        // some task with child...
    }
}

private void taskDelta(IResourceDelta delta) throws CoreException {
    if (delta == null) {
        return;
    }
    IResourceDelta[] children = delta.getAffectedChildren();
    for (IResourceDelta child : children) {
        // some task with child.getResource() ...
        taskDelta(child);
    }
}

どちらも似たようなものです。
最終的に使うのは IResource のインスタンスになるでしょう。
Eclipse では全てのリソースを IResource のサブクラスとして扱います。

IPath について

ここではちょっと関連する話として、IPath について説明します。
これは簡単に言えば、リソースが存在するパスについての情報を表すものです。
しかし、ややとっつきにくいのでここで詳しく紹介することにします。

まず、IPath にはパスについて2つの表し方があります。
それは「内部パス」と「外部パス」です。
前者はEclipse内のリソースを扱うパス形式で、後者はEclipse外を扱う形式です。

内部パス

例えば、以下のようなプロジェクト構成を考えます。

myproject
|
|-- folder1
|   |
|   `- file.txt
|
|-- folder2
|
` README

このとき、それぞれを表すパスは以下のようになります。

/myproject
/myproject/folder1
/myproject/folder1/file.txt
/myproject/folder2
/myproject/README

このように、先頭が / で始まり、プロジェクト名が続き、
さらにプロジェクトルートからの相対パスを繋げて完成です。

外部パス

今度は外部パスです。

C:\
|
|-- folder1
|   |
|   `- file.txt
|
|-- folder2
|
` README

これをパスで表してみます。

C:/
C:/folder1
C:/folder1/file.txt
C:/folder2
C:/README

パスの取得方法

リソースからパスを取得するには2つの方法があります。
外部パスを取得する方法と、内部パスを取得する方法です。

resource.getLocation()

で外部パスを取得し、

resource.getFullPath()

で内部パスを取得します。

このメソッド名称が一番ややこしいですね。
FullPath の方が内部パスです。覚えておきましょう。

パスの使用方法

外部パスを java.io.File に変換するには以下のようにします。

File file = path.toFile();

ですから、Eclipse内リソースをFileに変換するには…

resource.getLocation.toFile();

でOKです。

内部パスは絶対パス情報を持っていないので、ファイルに変換してもうまくいきません。
パス文字列を取得するには以下のようにします。

String pathStr = path.toString();

これで、/myproject/folder2 のような文字列が取得できます。

リソースの作成

Eclipse内リソースを作成するには、内部パスを使用する必要があります。

((Workspace)ResourcesPlugin.getWorkspace()).newResource(path, type);

type には IResource.FILE もしくは IResource.FOLDER を指定します。
path には内部パスを指定します。
例えば、こんな感じです。

((Workspace)ResourcesPlugin.getWorkspace()).newResource(
        new Path("/myproject/folder3"), IResource.FOLDER);

正直、Workspace にキャストする必要があったりあまり良い方法ではありません。
他に良い方法を知ってたら教えて下さい。
リソースは作成しただけでは、java.io.File と同じように
実際にはファイルを作成するわけではありません。