EclipseのPluginをSWT Browserで作る
Eclipse の Plugin を作ろうと思ったのだが調べてみると敷居が高い高い。
テンプレのプロジェクトは用意されているがいきなりこんな画面が現れて ぼーぜん とすることになる。 ちなみに下部のタブは其々違う設定画面が現れる。
Plugin開発の
チュートリアル
も有ることは有るが目次を見ただけで気が遠くなる。
しかも、この先には膨大な javadoc が待っている。
正直諦めそうになったのだが以前、 Eclipse内のライブラリからブラウザを起動してみた事を思い出して 内部ブラウザでPluginを作れないかと考えた。
で、ググったら出て来ましたよ、本家IBMのサイトが。
ブラウザの起動方法と最低限の通信方法の説明だけですが本家が可能性として有りだと言ってます。
...
そして、設定画面&Javadocと格闘しつつでっち上げたのがこれです。
HTMLのソースはこれだけです。
Eclipse.* は eclipse 側から呼んで貰うためのJavaScriptです。
<html>
<head>
<script src="./jquery-1.8.2.js"></script>
<script>
var Eclipse = {};
Eclipse.setContent = function(content) {
var data = JSON.parse(content);
var form = document.parson;
form.name.value = data.name;
form.addr.value = data.addr;
form.email.value = data.email;
};
Eclipse.getContent = function() {
var data = {};
var form = document.parson;
data.name = form.name.value ;
data.addr = form.addr.value ;
data.email = form.email.value ;
return JSON.stringify(data);
};
Eclipse.fireEvent = function(type) {
window.status = type;
window.status = null;
};
window.onload = function() {
Eclipse.fireEvent("load");
}
window.onerror = function(err) {
Eclipse.fireEvent("log,"+err);
}
$(function(){
$("input").bind("change",function() {
Eclipse.fireEvent("change");
});
});
</script>
</head>
<body>
<h1>Browser plugin sample</h1>
<form name="parson">
<table>
<tr><td>Name:</td><td><input name="name" /></td></tr>
<tr><td>Addr:</td><td><input name="addr" /></td></tr>
<tr><td>E-Mail:</td><td><input name="email" /></td></tr>
</table>
</form>
</body>
</html>
保存した後にテキストエディタで見るとJSON形式でちゃんと保存されている事がわかります。
Plugin側で作成したソースコードは1本だけです。
継承すべき TextEditor クラスを探すのは苦労しましたがその先はすんなり行きました。
package org.kotemaru.eclipse.browserpluginsample.editors; import 省略; public class BrowserEditor extends TextEditor { private static final String ENCODING = "utf-8"; private Browser browser; private boolean isDirty = false; public BrowserEditor() { super(); } @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { setSite(site); setInput(input); setPartName(input.getName()); } @Override public void createPartControl(Composite parent) { try { browser = new Browser(parent, SWT.NONE); browser.setJavascriptEnabled(true); browser.addStatusTextListener(new MyStatusTextListener()); URL aboutURL = this.getClass().getResource("/webapps/editor.html"); URL url = FileLocator.resolve(aboutURL); browser.setUrl(url.toString()); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } private class MyStatusTextListener implements StatusTextListener { @Override public void changed(StatusTextEvent ev) { log("status="+ev.text); String[] params = ev.text.split(","); String method = params[0]; if ("load".equals(method)) { onLoad(params); } else if ("change".equals(method)) { onChange(params); } else if ("log".equals(method)) { log(ev.text); } } } private void onLoad(String[] params) { StringBuilder sbuf = new StringBuilder(); try { IFileEditorInput input = (IFileEditorInput)getEditorInput(); InputStream in = input.getFile().getContents(); try { Reader reader = new InputStreamReader(in, ENCODING); int n; char[] buff = new char[1024]; while ((n=reader.read(buff))>=0) { sbuf.append(buff,0,n); } } finally { in.close(); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } String data = sbuf.toString(); data = data.replaceAll("'", "\\'").replaceAll("\n", "\\n"); browser.execute("Eclipse.setContent('"+data+"')"); } private void onChange(String[] params) { setDirty(true); } @Override public void doSave(IProgressMonitor monitor) { String content = (String) browser.evaluate("return Eclipse.getContent();"); try { IFile file = ((IFileEditorInput) getEditorInput()).getFile(); file.setContents( new ByteArrayInputStream(content.getBytes(ENCODING)), true, // keep saving, even if IFile is out of sync with the Workspace false, // dont keep history monitor); // progress monitor setDirty(false); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } public void setDirty(boolean b) { isDirty = b; firePropertyChange(EditorPart.PROP_DIRTY); } @Override public boolean isDirty() { return isDirty; } @Override public void dispose() { browser.dispose(); super.dispose(); } @Override public void setFocus() { } @Override public boolean isSaveAsAllowed() { return false; } @Override public void doSaveAs() { // Unsupported } private void log(String msg) { System.out.println(msg); // TODO:ちゃんとログ。 } }
本格的なPluginを作るにはまだ色々必要ですが JavaScript
でEclipse plugin開発ができる事が分かりました。
このサンプルのSVNリポジトリは以下にあります。
Eclipse4.2のPluginのuninstallではまったのでメモ(2)
追記。
プラグインのアンインストールで残っちゃうのはEclipse-3.7でも同じだった。
Linuxの場合は
~/.eclipse/org.eclipse.platform_{バージョン番号}/plugins/
配下にインストールされてるのでややこしい。
Eclipse plugin はバージョン番号に qualifier
を付けると日付に置き換えてくれる機能があって
これを使えばアンインストールしなくても更新されるって事らしい。
初期状態で付いてたのを意味が分からなかったんで削除してた orz
Eclipse4.2のPluginのuninstallではまったのでメモ
Eclipse-4.2ではプラグインのアンインストールが完全に行われない。
通常の手順でアンインストールを行うと一見削除されたように見えるのだが 実際は無効にしただけで削除していない。
この状態でプラグインを再インストールすると実際のインストールは行わず有効に戻すだけとなる。
これで何が問題になるかと言うと自分でプラグイン開発をしている場合、 修正を行って再インストールをしても修正が反映されない。 開発環境で実行すると正常に動作するのでかなり混乱する。
Eclipseのプラグイン開発は初めてやったので訳が分からず1日潰れてしまった。(;_;)
解決方法のメモ:
- %ECLIPSE_HOME%\plugins\ から 自前のプラグイン.jar のファイルを削除。
- %ECLIPSE_HOME%\artifacts.xml から自前のプラグインの
<artifact>
タグを探して削除。 - eclipse -clean
で完全に削除できる。
因みに 2. をやらないと再インストールでこんな感じのエラーとなる。
An error occurred during the org.eclipse.equinox.internal.p2.engine.phases.CheckTrust
phase. session context was:(profile=epp.package.jee,
phase=org.eclipse.equinox.internal.p2.engine.phases.CheckTrust, operand=, action=).
Error reading signed content.
The file "%ECLIPSE_HOME%\plugins\自前のプラグイン.jar" does not exist
Eclipseのプラグイン開発は敷居高過ぎ。
eclipseのアノテーションの設定ではまる、その2
- Velocity は singleton で環境を持っている。
- eclipse の標準ビルダーはアノテーション処理の実行環境をワークスペース内で共有するらしい。
- Velocity は環境の再初期化ができない。
- Velocityを使うアノテーション処理が複数プロジェクトにあると誤動作しまくり。
eclipse 好きになりかていたのですがまた嫌いになりました。
eclipseのアノテーションの設定ではまる
しかもエラーがどこにも出ない!! 原因は ant から
Linux でコマンドラインから eclipse を起動すれば標準出力にエラーが出ることが判明。 DOS窓は未確認。
Eclipse/SWTのBrowserではまった。
通常のブラウザはセキュリティ上の制限が厳しくWebアプリと ローカルアプリを連係させるのは難しかったが これで簡単にできるかもしれない。 SWT の開発環境は以前はデフォルトで入っていたらしいのだが 最近の版では別途インストールが必要らしい。 しかもプラットフォーム毎に異なるバイナリが使う必要がある。 以下のURLから使っているEclipseと同じ版の「SWT Binary and Source」 を落してきてインストールする。
- http://download.eclipse.org/eclipse/downloads/