かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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;
    }
    
}

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

太郎さんを取得