ancestorsを作ってみる
rubyも少しやってた身としてはancestorsがなにげに便利。
ということで、Scala版を作った。
class Any2Ancestors(c:Class[_]) { def ancestors() = { def ans(o:Class[_], l:List[String]):List[String] = { if (o.getSuperclass == null) l else ans(o.getSuperclass, l:::o.getName::Nil) } ans(c,Nil) } } implicit def any2Ancestors(any:Any):Any2Ancestors = new Any2Ancestors(any.getClass)
暗黙の変換便利すぎwww
なんか、もっときれいになりそうな気もするけど。
scala> List(1,2,3).ancestors res9: List[String] = List(scala.collection.immutable.$colon$colon, scala.collection.immutable.List)
デシリアライズくらい簡単に出来るかと思ったらはまった
昨日の最小コードがあれば、後は簡単と思ってたらそうでもなかった。
はまったポイント
昨日のコードで下のように書いたけど
@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
テキストを加工してエディタに表示する
訳あって、シリアライズされたファイルを扱うことがあったから、何とかデシリアライズして見れないものかと思って、調べてみた。
以下、最小構成
依存関係
plugin.xml
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.4"?> <plugin> <extension point="org.eclipse.ui.editors"> <editor class="DeserializeEditor" default="false" extensions="properties" icon="icons/sample.gif" id="DeserializeViewer.editor1" name="name"> </editor> </extension> </plugin>
ここでとりあえず大事なのはclass指定くらいかな?
extensionsは対象の拡張子。
iconはなにげに必須。
ソース
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.IVerticalRuler; import org.eclipse.jface.text.source.projection.ProjectionSupport; import org.eclipse.jface.text.source.projection.ProjectionViewer; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.editors.text.FileDocumentProvider; import org.eclipse.ui.editors.text.TextEditor; public class DeserializeEditor extends TextEditor { public DeserializeEditor() { super(); setDocumentProvider(new FileDocumentProvider(){ @Override protected IDocument createDocument(Object element) throws CoreException { // このメソッドで返したIDocumentの値が表示される IDocument document = super.createDocument(element); if (document != null) { document.set("Hello Editor"); } return document; } @Override protected void doSaveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException { // 保存処理 } }); } @Override protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { ISourceViewer viewer = new ProjectionViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles); getSourceViewerDecorationSupport(viewer); return viewer; } @Override public void createPartControl(Composite parent) { super.createPartControl(parent); ProjectionViewer viewer = (ProjectionViewer) getSourceViewer(); ProjectionSupport projectionSupport = new ProjectionSupport(viewer, getAnnotationAccess(), getSharedColors()); projectionSupport.install(); } }
実行すると、どんなporpertiesファイルを開いても"Hello Editor"と表示される。
FileDocumentProvider#createDocument()で返すのは表示する文字列。elementに元のデータが入っている。
FileDocumentProvider#doSaveDocument()は保存時の処理。
表示内容と、生データが異なるので上手いこと保存しろってことだと思う(後で調べる)
DeserializeEditor()→コンストラクタ内でDocumentProviderをセット
DeserializeEditor#createSourceViewer()→ViewerにProjectionViewerを使うことを教えてる?(後で調べる)
DeserializeEditor#createPartControl()→よくわかんない(あとで調べる)
まとめ
英語力の無さに泣けてきた。
ざっくりとしかわからないのがつらい。
TextEditorを読み込み専用で開きたい
org.eclipse.ui.editors.text.TextEditorを継承したクラスで下のようにすればいいのか?
http://dev.eclipse.org/newslists/news.eclipse.tools/msg50392.html
protected void doSetInput(IEditorInput input) throws CoreException { super.doSetInput(input); ((IFileEditorInput)input).getFile().setReadOnly(true); }
org.eclipse.ui.IFileEditorInputはパッケージがorg.eclipse.uiなのにorg.eclipse.ui.ideプラグインを入れないと使えない。
ちなみに、今Eclipse3.6でやってみたら、setReadOnly()はdeprecatedになっていた。
正しくはこっち
protected void doSetInput(IEditorInput input) throws CoreException { super.doSetInput(input); IFile file = ((IFileEditorInput) input).getFile(); ResourceAttributes attributes = file.getResourceAttributes(); attributes.setReadOnly(true); file.setResourceAttributes(attributes); }
Mon, Oct 26
- 23:42 @iharakenji カメラ→保存・整理→プリントまでを簡単にならないかなと。flickrがアップは簡単だけどダウンが使えなかった。 [in reply to iharakenji]
- 23:15 1年振り位に親に息子の写真を送った。写真の管理が面倒で送れてなかったけど、あいかわらず写真をどう管理していいのか解決策が見つからない。
- 23:11 寒い
- 18:33 rssリーダも無料なのか。とりあえず落としとこ。 TwitBird Pro : 今日だけ無料!!全員ダウンロードして損はない!秀逸すぎるTwitterアプリ! http://bit.ly/3JcAzW
- 00:59 特定の文字が入ってるとダメみたいだ。眠いから、また明日にしよう。 RT @as_a_rimit はてブポケットからtwitterrificへの連携がうまくいかなくなってる。再起動したけど、ダメだった。便利だったのに。
- 00:56 はてブポケットからtwitterrificへの連携がうまくいかなくなってる。再起動したけど、ダメだった。便利だったのに。
- 00:33 寒い。寝よう
Powered by twtr2src