#author("2021-12-14T02:35:57+00:00","","")
// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
#contents

[[Eclipse/プラグイン開発のTIPS集/ソースコードを解析するパーサASTParser]]やEclipse/プラグイン開発のTIPS集/org.eclipse.jdt.core.ICompilationUnitでもちょっとやりましたが、パッケージ・エクスプローラからSelection経由でICompilationUnit((Javaのソースとかですね))を取得することができました。その
Javaソースは、何とかっていう名前のJavaプロジェクトに属しているわけですが、Javaプロジェクト自体を操作するインタフェースもEclipseに用意されています。Javaプロジェクトを作成したり、削除したり、ソースを生成したりすることができるわけですね。以下にJavaプロジェクトを操作する方法をまとめておきます。


パッケージ・エクスプローラを見てもわかるとおり、Javaプロジェクトはツリー構造になってるわけで、よくあるコンポジットパタンになってます。コンポジットな要素たち全部が拡張しているルートのインタフェースが[[org.eclipse.jdt.core.IJavaElement>http://publib.boulder.ibm.com/infocenter/radhelp/v6r0m1/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/IJavaElement.html]]です。

**org.eclipse.jdt.core.IJavaElement [#ge8dcc8a]
全ての要素が拡張しているインタフェースですね。定数を見るとわかるのですが、要素は
 int JAVA_MODEL = 1;
 int JAVA_PROJECT = 2;
 int PACKAGE_FRAGMENT_ROOT = 3;
 int PACKAGE_FRAGMENT = 4;
 int COMPILATION_UNIT = 5;
 int CLASS_FILE = 6;
 int TYPE = 7;
 int FIELD = 8;
 int METHOD = 9;
 int INITIALIZER = 10;
 int PACKAGE_DECLARATION = 11;
 int IMPORT_CONTAINER = 12;
 int IMPORT_DECLARATION = 13;
 int LOCAL_VARIABLE = 14;
 int TYPE_PARAMETER = 15;

くらい種類があるようです。


**[[org.eclipse.jdt.core.IJavaModel>http://help.eclipse.org/help32/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/IJavaModel.html]] [#w8ab5b31]
ワークスペース内のJavaモデル(?)のルートです。IJavaElement#getJavaModel()で取得することができます。んがいまいちパッケージ・エクスプローラ上の概念でどこを指してるのかわからないですね。ただ
 IJavaProject[] getJavaProjects();
 IJavaProject getJavaProject(String name);
 IWorkspace getWorkspace();
などのメソッドを持っているようです。


**[[org.eclipse.jdt.core.IJavaProject>http://help.eclipse.org/help32/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/IJavaProject.html]] [#m6444966]
Javaプロジェクトです。 IJavaElement#getJavaProject() で取得することができます。よってコンポジットのどの要素からもJavaプロジェクトへの参照が得られるわけです。


**[[org.eclipse.jdt.core.IPackageFragmentRoot>http://help.eclipse.org/help32/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/IPackageFragmentRoot.html]] [#cf42b3a1]
Javaプロジェクト内のパッケージ階層のトップ要素です。ソースディレクトリやjarファイルなどに対応します。

たとえば
 IPackageFragmentRoot root = null;
 try {
   IJavaProject javaProject = element.getJavaProject();
   IPackageFragmentRoot[] roots = javaProject
       .getPackageFragmentRoots();
   for (IPackageFragmentRoot rootTmp : roots) {
     if (rootTmp.getKind() == IPackageFragmentRoot.K_SOURCE) {
       root = rootTmp;          ↑ソースディレクトリだったら
     }
   }
 } catch (JavaModelException e) {
   e.printStackTrace();
 }
などとしてソースディレクトリを取得することができます。

***他にもいろいろ確認してみた [#l04367c0]
他にも以下のやり方でソースディレクトリが取得できそうです。他にもいろいろメソッドを実行して試してみました。

#ref(ICompilationUnit.png)

上のようなディレクトリ構成で、いろいろなメソッドを実行しました。

 System.out.println("Path: " + element.getPath());
 System.out.println("Parent: " + element.getParent().getPath());
 System.out.println("PrimaryElement: "
         + element.getPrimaryElement().getPath());
 System.out.println("Primary: " + element.getPrimary().getPath());
 IPackageFragmentRoot root = (IPackageFragmentRoot) element
         .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
 System.out.println("Ancestor: " + root.getPath());
elementはキャプチャ内のBL.javaを指しているICompilationUnitのインスタンスです。

実行結果は以下の通り:
 Path: /HogeProject/src/nu/mine/kino/BL.java
 Parent: /HogeProject/src/nu/mine/kino
 PrimaryElement: /HogeProject/src/nu/mine/kino/BL.java
 Primary: /HogeProject/src/nu/mine/kino/BL.java
 Ancestor: /HogeProject/src

IJavaElement#getAncestor(int ancestorType) メソッドで、要素の型(JAVA_PROJECTとかPACKAGE_FRAGMENT_ROOTとか)を指定して上位ディレクトリのIJavaElementを取得することができます。上の例では
 IPackageFragmentRoot root = (IPackageFragmentRoot) element
        .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
として、BL.javaが入っているディレクトリのトップ階層つまりsrcディレクトリへの参照を取得しています。((test/hogehogeをソースディレクトリとしてたら、testでなくてtest/hogehogeのへの参照が得られました))

他のメソッドについてですが IJavaElement#getParent() については真上のディレクトリですね。他のヤツは、、んー全部BL.javaなんですよね。一応、[[JavaDocへのリンク>http://publib.boulder.ibm.com/infocenter/radhelp/v6r0m1/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/IJavaElement.html]]を載せておきます。。

***パッケージを作る [#ta053d03]
上の方法でソースディレクトリのIPackageFragmentRootを取得し、IPackageFragmentRootのメソッド
 IPackageFragment createPackageFragment(
    String name,
    boolean force,
    IProgressMonitor monitor)
を呼び出すことで、パッケージを作成することができます。たとえばさっきのelementのディレクトリ nu.mine.kino の下にsampleというパッケージを作成するには
 String elementName = element.getParent().getElementName();
 String sample = "sample";
 String newPackage = "".equals(elementName) ? sample
                     : elementName + "." + sample;
 IPackageFragment packageDir = root.createPackageFragment(
                                 newPackage, true,new NullProgressMonitor());
とします。単純に文字列連結だと、elementがデフォルトパッケージの時の条件分岐が必要になっちゃいますが、まあよしとしましょう((デフォルトパッケージの時はelement.getParent().getElementName()は""(空文字)なんですね))。


**[[org.eclipse.jdt.core.IPackageFragment>http://help.eclipse.org/help32/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/IPackageFragment.html]][#mfd3abc7]
上の例の
 IPackageFragment createPackageFragment(
    String name,
    boolean force,
    IProgressMonitor monitor)
で返ってくるオブジェクトが IPackageFragment です。つまりパッケージを表すインタフェースですね。このインタフェースにはJavaソースコードを生成する
 ICompilationUnit createCompilationUnit(
       String name, String contents,
       boolean force, IProgressMonitor monitor)
というメソッドがあります。
 ICompilationUnit hoge = packageDir.createCompilationUnit(
         "Hoge.java", "public class Hoge{}", true,
         new NullProgressMonitor());
 IPackageDeclaration declaration = hoge.createPackageDeclaration(
         newPackage, new NullProgressMonitor());
こんな感じでソースコードを生成することができるんですね。


**org.eclipse.jdt.core.ICompilationUnit [#r9ed8ac6]
Javaのソースコードですね。[[ソースコードを解析するパーサASTParser>Eclipse/プラグイン開発のTIPS集/ソースコードを解析するパーサASTParser#g0545711]] にも書きましたが以下のようにソースコードの情報を取得できます。elementがICompilationUnitのインスタンスです。

 logger.debug("ファイル名: " + element.getElementName());// ファイル名
 String sourceName = element.getElementName().substring(0,
 element.getElementName().lastIndexOf("."));
 logger.debug("クラス名: " + sourceName);
 logger.debug("クラスの完全修飾クラス名: "
   + element.getType(sourceName).getFullyQualifiedName());
 logger.debug("パッケージ名: " + element.getParent().getElementName());
 String source = cu.getPath().toPortableString();
 logger.debug("ソースへのパス: " + source);
実行結果は以下の通り。
 ファイル名: BL.java
 クラス名: BL
 クラスの完全修飾クラス名: nu.mine.kino.BL
 パッケージ名: nu.mine.kino
 ソースへのパス: /Samples/source/nu/mine/kino/BL.java

ただ 完全修飾クラス名 を取得するメソッドは、そのファイルのクラス名を取得しているのではなく((引数にクラス名渡してるくらいだから))、elementのパッケージ名に引数のクラス名を連結してるだけ、、みたいです。

***ソースコードのIResourceインスタンスを取得する。 [#xe2f4652]
JDT周りをやってるとIResouce系を忘れてしまいそうですが、ありました。
 // ソースコードに対応するファイルのIResource
 IResource resource = cu.getCorrespondingResource();
これでOKですね。



**関連リンク [#z06a92a2]
-Eclipse/プラグイン開発のTIPS集/org.eclipse.jdt.core.ICompilationUnit 自サイトに情報が散見しているので、このページにまとめ直し中。
-Eclipse/プラグイン開発のTIPS集/ソースコードを解析するパーサASTParser
-[[Java Tool Smithing, Extending the Eclipse Java Development Tools  .>http://eclipsecon.org/2005/presentations/EclipseCON2005_Tutorial29.pdf]]
-[[プラグインでリソースを扱う>http://www13.plala.or.jp/observe/PDE/PDEResources.html]]
-[[Eclipseプラグイン開発/ファイルの作成>http://yoichiro.cocolog-nifty.com/eclipse/2004/06/post.html]]
-[[プロジェクト配下のリソースの取得方法2>http://hp.vector.co.jp/authors/VA014436/prg_memo/java/eclipse2/012.html]]

----
この記事は
#vote(おもしろかった[6],そうでもない[2])
#vote(おもしろかった[11],そうでもない[3])

#comment
#topicpath


SIZE(10){現在のアクセス:&counter;}


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS