プロジェクト配下のリソースの取得方法2

前節では、有る意味力技でプロジェクト配下の情報を表示しました。
今度は、JDTを利用して表示してみます。
JDTとは、 Java Development Tool の略で、 Eclipseに標準で組み込まれています。
パッケージはorg.eclipse.jdtです。
これは、EclipseでJavaの開発を行うためのプラグインです。
無論、これが無ければプラグインの開発もままならないわけです。

とまぁ、紹介はそこそこに、まずはJava プロジェクトについて少し説明します。

Java Projectについて

JavaProjectの構成と今まで扱ってきたプロジェクトを比較してみます。
まずは構成を見比べてみます。

似ています。Java Project以下はJava Elementで構成されています。
Java ElementはJavaファイルであったり、メソッドであったりします。
上の図から誤解を恐れずに、今までのプロジェクトに関連付けると、
IWorkspaceRoot ≒ IJavaModel
IProject ≒ IJavaProject
IFolder ≒ IJavaElement
IFile ≒ IJavaElement
という関連になると思います。

また、Javaエレメントごとにインターフェイスが設けられています。
これはEclipseのヘルプに載っていますのでそちらを参照してください。

図.1【JavaProjectとプロジェクト】
JavaProjectへのアクセスは、 org.eclipse.jdt.core.JavaCoreクラスを利用して行います。
JavaCoreクラスのcreateメソッドでIProjectやIFileを変換する必要があります。

JavaCore.create()メソッド一覧
関数説明
static IJavaElement create(IFile file)
static IJavaElement create(IFolder folder)
static IJavaProject create(IProject project)
static IJavaElement create(IResource resource)
static IJavaModel create(IWorkspaceRoot root)
static IJavaElement create(String handleIdentifier)

入力が確定している場合は、各インターフェイスに対応したcreate()メソッドを利用し、不特定(IResoueceインターフェイスを拡張していることが前提)の場合は、IResourceを引数に使うcreate()メソッドを利用するのが良いと思います。
また、IJavaElementは多くのインターフェイスで拡張されています。
これは先に述べたように、エレメントごとのインターフェイスが用意されていることに関係しています。
Javaのエレメントに関するインターフェイスはIJavaElementの派生と覚えておく必要があります。

Java エレメントの種類(要約)
エレメント説明
IJavaModel ワークスペースに対応したルートの Java エレメントを表します。すべての Java プロジェクトの親です。
IJavaProject ワークスペース内の Java プロジェクトを表します。 (IJavaModel の子です)
IPackageFragmentRoot パッケージ・フラグメントのセットを表し、そのフラグメントを、フォルダー、JAR または Zip ファイルのいずれかである基本リソースにマップします。 (IJavaProjectの子です)
IPackageFragment パッケージ全体に対応するワークスペースの一部、またはパッケージの一部を表します。 (IPackageFragmentRoot の子です)
ICompilationUnit Java ソース (.java) ファイルを表します。 (IPackageFragment の子です)
IPackageDeclaration コンパイル単位内のパッケージ宣言を表します。 (ICompilationUnit の子です)
IImportContainer コンパイル単位内のパッケージのインポート宣言のコレクションを表します。 (ICompilationUnit の子です)
IImportDeclaration 1 つのパッケージのインポート宣言を表します。 (IImportContainer の子です)
IType コンパイル単位内のソース・タイプ、またはクラス・ファイル内のバイナリー形式のいずれかを表します。
IField 型内部のフィールドを表します。 (IType の子です)
IMethod 型内部のメソッドまたはコンストラクターを表します。 (IType の子です)
IInitializer 型内部の静的イニシャライザーまたはインスタンスのイニシャライザーを表します。 (IType の子です)
IClassFile コンパイル済みの (バイナリーの) 型を表します。 (IPackageFragment の子です)

ソース

上記のことを踏まえて、ソースを見てみましょう

JDTを利用したリソースの取得(前節との変更メソッドのみ)
    public void selectionChanged(IAction action, ISelection selection) {
        if(selection == null){
            return;
        }
        if(!(selection instanceof IStructuredSelection)){
            return;
        }
        IStructuredSelection iss = (IStructuredSelection)selection;
        Object obj = iss.getFirstElement();
        if(obj instanceof IAdaptable){
            IAdaptable ia = (IAdaptable)obj;
            String analyzePath = ia.toString();
            Vector v = pathAnalyzer(analyzePath);       //階層を解析する
            String prjName = (String)v.get(0);      //プロジェクト名の取得
            IWorkspace iw = ResourcesPlugin.getWorkspace();     //ワークスペースの取得
            IWorkspaceRoot iwr = iw.getRoot();                  //ワークスペースのルートを取得
            IProject prj = iwr.getProject(prjName);
            try{
                IJavaProject iPrj = JavaCore.create(prj);
                IJavaElement[] ije = iPrj.getChildren();
                listUp(ije, 0);
            }catch(Exception e){
            }
        }
    }
    void listUp(IJavaElement ijeList[], int nest){
        for(int i = 0; i < ijeList.length; i++){
            try{
                if(ijeList[i] != null){
                    IJavaElement ije = ijeList[i];
                    StringBuffer nestStr = new StringBuffer();
                    for(int j = 0; j < nest; j++){
                        if(j+1 < nest){
                            nestStr.append(" ");
                        }else{
                            nestStr.append("└");
                        }
                    }
                    System.out.print(nestStr.toString());
                    if(ije instanceof IPackageFragmentRoot){
                        IPackageFragmentRoot ipfr = (IPackageFragmentRoot)ije;
                        IJavaElement[] ijes = ipfr.getChildren();
                        System.out.println("Package Root : " + ije.getElementName());
                        listUp(ijes, nest + 1);
                    }else if(ije instanceof IPackageFragment){
                        IPackageFragment ipf = (IPackageFragment)ije;
                        IJavaElement[] ijes = ipf.getChildren();
                        System.out.println("Package : " + ije.getElementName());
                        listUp(ijes, nest + 1);
                    }else if(ije instanceof IImportContainer){
                        IImportContainer iic = (IImportContainer)ije;
                        IJavaElement[] ijes = iic.getChildren();
                        System.out.println("Import : " + ije.getElementName());
                        listUp(ijes, nest + 1);
                    }else if(ije instanceof IImportDeclaration){
                        System.out.println("Import : " + ije.getElementName());
                    }else if(ije instanceof IType){
                        System.out.println("Type : " + ije.getElementName());
                    }else if(ije instanceof IField){
                        System.out.println("Field : " + ije.getElementName());
                    }else if(ije instanceof IMethod){
                        System.out.println("Method : " + ije.getElementName());
                    }else if(ije instanceof IInitializer){
                        System.out.println("Initializer : " + ije.getElementName());
                    }else if(ije instanceof IClassFile){
                        IClassFile icf = (IClassFile)ije;
                        IJavaElement[] ijes = icf.getChildren();
                        System.out.println("ClassFile : " + ije.getElementName());
                    }else if(ije instanceof ICompilationUnit){
                        ICompilationUnit icu = (ICompilationUnit)ije;
                        IJavaElement[] ijes = icu.getChildren();
                        System.out.println("JavaSource : " + ije.getElementName());
                        listUp(ijes, nest + 1);
                    }else{
                        System.out.println("other : " + ije.getElementName());
                    }
                }
            }catch(Exception e){
                System.out.println("");
            }
        }
    }

処理自体は大きく変わっていません。
IFileなどがJavaに対応したエレメントに変わっただけですが、エレメントや子を持つ情報が増えているので、if文が多くなっています。
注目すべき点は、IJavaElementを各インターフェイスでキャストしていることです。
また、plugin.xmlの<requires>タグ内に<import plugin="org.eclipse.jdt.core"/>を追加し忘れないようにしてください。

結果は右図の様に、パッケージやインポート、ソースなど、いろいろな情報が表示されています。

【実行結果】