日頃より、弊社をご愛顧いただきまして誠にありがとうございます。この度、ゴーツーラボ 株式会社が営むアトラシアン製品ライセンスの販売および SI サービスの提供事業をリックソフト 株式会社に譲渡することで合意し、事業譲渡契約を締結する運びとなりました。詳細については、「事業譲渡に関するお知らせ」をご参照ください。

ドラッグ アンド ドロップでファイルを添付する JIRA プラグインの詳解

2010-09-08 (Wed)  •  By 伊藤  •  活用のヒント  •  Jira 翻訳

今回の記事は、JIRA アドオンに関するアトラシアン ブログ「Under the hood of JIRA Drag and Drop Attachments plugin 」の弊社翻訳版です。原文と差異がある場合は、原文の内容が優先されます。

このブログ投稿では、JIRA 課題ページに挿入されるセットアップ不要のプラグインの作成方法について説明するよ。それから、最新ブラウザー上でのドラッグ アンド ドロップを数行で実現する方法についても説明するね。それでは始めようか。

どうやって入れようか

頭を掻きむしりながら、どうやったら自分自身を JIRA 課題ページへ添付できるか考えてみたよ。そうだ、カスタム フィールドを使おう! シンプルで、エレガントで、簡単なコード ソリューションじゃない?

でも、ひとつだけ欠点があるんだ。管理者が設定しなくちゃいけないんだよ。何かベターな方法はないかな?

Atlassian Plugins Framework 2.5 では web-resource/context に関する救済策が用意されているんだ。これによって、あらかじめ指定したコンテキスト (例えば ユーザーや管理者ページなど) へ自動的にリソースを添付できるわけ。ああっ、しまった! JIRA 4.1 上で動作するようにしたいんだけど、APF 2.5 がないじゃん。:-(

ついてないってこと? そうじゃなくって、数行追加すればいいだけだ。これが僕の servlet-filter だよ。:-)

<servlet-filter name="JIRA Drag and Drop Attachment Resources"
  key="servlet-filter"
  class="com.atlassian.jira.plugins.dnd.attachment.AttachDndResourcesFilter"
  location="before-dispatch" weight="200">
  <url-pattern>/browse/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
</servlet-filter>

何をするものかって? /browse/* (たいていは課題画面) に一致するすべてのリクエストを処理して、以下の行のリソースを添付するんだ。

public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain)
throws IOException, ServletException
{
WebResourceManager webResourceManager = ComponentManager.getInstance().getWebResourceManager();
webResourceManager.requireResource("com.atlassian.jira.plugins.jira-dnd-attachment-plugin:javascript");
filterChain.doFilter(servletRequest, servletResponse);
}

これで、誰かが課題ページを表示するたびに僕のコードが挿入されるわけ。

よし、入ったぞ。それから?

チャチャっといこう。

簡単なことさ。jQuery を使用した HTML を作成して、それを右コラムの最後に添付するだけ。正しいマークアップと CSS に注意を払って、エレメントの残りはこんな感じにする。これがドロップ領域になる。

そうさ、ドラッグ アンド ドロップ イベントで対話操作できるんだ。

drop_zone
.bind("dragenter", dndAttachment.ignoreEvent)
.bind("dragover", dndAttachment.ignoreEvent)
.bind("drop", dndAttachment.handleDrop);

ignoreEvent 関数は伝達を無視/防止するので、ブラウザーはファイルを開かないようになるんだ。ファイルがこの領域にドロップされた後、handleDrop でアップロードが行われる。

準備完了。送ってみよう

うーん、どうやって送信したらいいのかな? マルチパート フォーム リクエスト ボディを作成しなくちゃいけないのかな? コードをたくさん記述しなくちゃいけないし、バイナリ データの取り扱いも心配しなくちゃいけないし。でも、その心配はご無用さ。

var xhr = new XMLHttpRequest(), upload = xhr.upload;
upload.onprogress = function(event) {
//
// handle on progress using new API
//
};
xhr.open("POST", contextPath + "/rest/jira-dnd-attachment/1.0/issue/" + key + "/attachments?filename=" + file.fileName, true);
xhr.onreadystatechange = function(event) {
if (event.target.readyState == 4) {
//
// handle end of upload
//
}
};
xhr.send(file);

やらなくちゃいけないことは、handleDrop に対する引数として利用可能な event.originalEvent.dataTransfer. ファイルからエレメントを実際に送信するだけ。

すべては 200 行のそれなりにまとまった JavaScript に収まっているでしょ。

よし、受け取って!

ご覧のとおり、ファイルの受信はとても簡単。

ファイルを取得して、temp へコピーして、AttachmentManager に引き渡して、IssueUpdateBean を作成して課題の履歴にトレースを保存する。ところで、セキュリティ チェックを忘れないでね。そうすれば問題はないはずさ。

以上。僕のブログを読んでくれてありがとう!

  前の記事 次の記事  

関連記事