デシリアライズくらい簡単に出来るかと思ったらはまった

昨日の最小コードがあれば、後は簡単と思ってたらそうでもなかった。

はまったポイント

昨日のコードで下のように書いたけど

@Override
protected IDocument createDocument(Object element)
        throws CoreException {
    // このメソッドで返したIDocumentの値が表示される
    IDocument document = super.createDocument(element);
    
    if (document != null) {
        document.set("Hello Editor");
    }
    return document;
}

IDocument#get()で取れる文字列を元に出シリアライズすればいいと思って、InputStreamやら、OutputStreamやらいじっててどうしても出来ないと思ったら、IDocument#get()の時点ですでにエンコードされてるから、正しいバイナリの値が取れてなかったみたい。

こんな感じで書いてた(ダメな例)

protected IDocument createDocument(Object element)
        throws CoreException {
    // このメソッドで返したIDocumentの値が表示される
    IDocument document = super.createDocument(element);
    
    ByteArrayInputStream bais = new ByteArrayInputStream(document.get().getBytes());
    
    try {
        ObjectInputStream ois = new ObjectInputStream(bais);
        
        // oisからオブジェクト取り出したりしてdocumentに書き込む
        Object obj = ois.readObject();
        
        // objから文字列を作ってdocumentに書き込む(省略)
        String text = "";
        
        document.set(text);
        
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    
    return document;
}

するとこんな感じの例外が発生する

java.io.StreamCorruptedException: invalid stream header: AC3F0573
	at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
	at java.io.ObjectInputStream.<init>(Unknown Source)
	at DeserializeEditor$1.createDocument(DeserializeEditor.java:36)
...

今考えればかなり初歩的なミス・・・

正しくは

正しいかは知らないけど、こっちは上手く動いているっぽい

protected IDocument createDocument(Object element)
        throws CoreException {
    IPathEditorInput input = (IPathEditorInput)element;
    
    File file = input.getPath().toFile();
    
    // 空のドキュメントを作る
    IDocument document = createEmptyDocument();
    
    ObjectInputStream ois = null;
    try {
        ois = new ObjectInputStream(new FileInputStream(file));
        
        // oisからオブジェクト取り出したりしてdocumentに書き込む
        Object obj = ois.readObject();
        
        // objから文字列を作ってdocumentに書き込む(省略)
        String text = "";
        
        document.set(text);                 
        
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (ois != null) {
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    return document;
}

elementはこの場合、FileEditorInputなのでそれを使ってファイルを直接とって、ObjectInputStreamに入れちゃうって戦法ですね。
ちなみにFileEditorInputにキャストするには「org.eclipse.ui.ide」を依存関係に追加しないといけないので、今回はIPathEditorInputにキャストしてみた。
正確には型チェックとかしないとなのかもだけど、とりあえずこれでOK