かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

FileSystem APIその3

FileSystemAPIその2 - かずきのBlog@Hatena」の続き。

前回は、.instanceという拡張子のfileに直接どのクラスのインスタンスを生成するのかを名前で示してあげた。
こんな風に

<file name="okazuki-modules-menus-Person.instance"/>

これだとお手軽。だけど多分デフォルトのコンストラクタでしかインスタンスが生成出来ないような気がする。
もうちょっと凝ったことをするために、インスタンスを生成するファクトリメソッドを指定する書き方もある。

書き方は簡単。fileタグの下にattrタグでinstanceClassとinstanceCreateを指定してやればいい。
instanceClassはstringvalueでクラス名を指定する。
instanceCreateはmethodvalueでファクトリメソッド名を指定する。

とりあえずこの間のPersonクラスに↓のようなメソッドを追加した。

    public static Person createFromFileObject(FileObject file) {
        Person result = new Person();
        result.setName((String) file.getAttribute("name"));
        return result;
    }

FileObjectからname属性を取得して、Personのnameにセットして返しているだけのシンプルな内容です。
じゃぁ、このメソッドを使ってインスタンスを作るように指定するものをlayer.xmlに書き足し!

    <folder name="okazuki">
        <!-- 前回からあったやつ -->
        <file name="okazuki-modules-menus-Person.instance"/>
        <!-- 今回付けたしたやつ -->
        <file name="myPerson.instance">
            <attr name="instanceClass" stringvalue="okazuki.modules.menus.Person" />
            <attr name="instanceCreate" methodvalue="okazuki.modules.menus.Person.createFromFileObject" />
            <attr name="name" stringvalue="太郎" />
        </file>
    </folder>

お試しのために、もう1つメニューを付け足してインスタンスを取得するためのコードを書いてみた。

package okazuki.modules.menus;

import org.openide.ErrorManager;
import org.openide.cookies.InstanceCookie;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.Repository;
import org.openide.loaders.DataObject;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;

public final class InstanceCreateAction2 extends CallableSystemAction {
    
    public void performAction() {
        try {
            FileObject root = Repository.getDefault().getDefaultFileSystem().getRoot();
            // FileObjectから
            FileObject myPerson = root.getFileObject("okazuki/myPerson.instance");
            // DataObjectにして
            DataObject myPersonDataObject = DataObject.find(myPerson);
            // InstanceCookieを取得してから
            InstanceCookie cookie = myPersonDataObject.getLookup().lookup(InstanceCookie.class);
            // インスタンスを作る
            Person person = (Person) cookie.instanceCreate();
            // んで、最後に名前を表示する
            System.out.println(person.getName() + "さんを取得");
        } catch (Exception e) {
            ErrorManager.getDefault().notify(e);
        }
    }
    
    public String getName() {
        return NbBundle.getMessage(InstanceCreateAction2.class, "CTL_InstanceCreateAction2");
    }
    
    protected void initialize() {
        super.initialize();
        // see org.openide.util.actions.SystemAction.iconResource() javadoc for more details
        putValue("noIconInMenu", Boolean.TRUE);
    }
    
    public HelpCtx getHelpCtx() {
        return HelpCtx.DEFAULT_HELP;
    }
    
    protected boolean asynchronous() {
        return false;
    }
    
}

実行してこのメニューをぽちっと押すと、下のようなメッセージがでた。
ちゃんと名前が設定されているのがわかると思う。

太郎さんを取得