tohokuaikiのチラシの裏

技術的ネタとか。

Confluenceのプラグインを作ってみる(7) Atlassian Templateを使ってみる

目的は、管理画面の作成をやってみたいのだけど、まだ遠いのでとりあえず。

AtlassianのパッケージSALとテンプレートAtlassian Template Renderer.

SALというパッケージを使うと、Confluenceのユーザー認証などの共通機能が使えるらしい。

また、Atlassian Template Rendererを使うと他のテンプレートエンジン(たとえばVelocity)なんかの連携もできるらしい。

細かいことは抜きにして、とりあえずサンプル

当該ページにあるサンプルコード

package com.atlassian.plugins.tutorial.xproductadminui;
 
import javax.servlet.http.HttpServlet;
 
import com.atlassian.sal.api.auth.LoginUriProvider;
import com.atlassian.sal.api.user.UserManager;
import com.atlassian.templaterenderer.TemplateRenderer;
 
public class AdminServlet extends HttpServlet
{
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    {
    }
}

を実行させるためには、pom.xmlにcom.atlassian.templaterendererとcom.atlassian.salを使えるための依存性を記述する必要がある。

ということで、

<dependency>
	<groupId>com.atlassian.sal</groupId>
	<artifactId>sal-api</artifactId>
	<version>2.7.0</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>com.atlassian.templaterenderer</groupId>
	<artifactId>atlassian-template-renderer-api</artifactId>
	<version>1.3.2</version>
	<scope>provided</scope>
</dependency>

を記述。pom.xmlを書き直したので、atlas-cliを起動してたらquitして再起動させる。

このdependencyは、artifactIdとversionが合ってないと動かない。
https://maven.atlassian.com/content/groups/public/com/atlassian/sal/
とかからヴァージョン情報を集める必要がある。artifactIdが分からない場合はどうするんだろう・・・。

で、サンプルコード

最初にあげたページにあるサンプルは、javaやってるならすぐ色々と足りない部分は気づくのだろうけど、自分はjava経験ゼロなので、色々直すのに苦労した。

で、こんな感じ。

package jp.junoe.confluence.plugins.exampleadminservlet;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URI;
 
import com.atlassian.sal.api.auth.LoginUriProvider;
import com.atlassian.sal.api.user.UserManager;
import com.atlassian.templaterenderer.TemplateRenderer;

import java.io.IOException;
 
public class ExampleAdminServlet extends HttpServlet
{
  private UserManager userManager = null;
  private LoginUriProvider loginUriProvider = null;
  private TemplateRenderer renderer = null;

  
  public void ExampleAdminServlet(UserManager userManager, LoginUriProvider loginUriProvider, TemplateRenderer renderer)
  {
    this.userManager = userManager;
    this.loginUriProvider = loginUriProvider;
    this.renderer = renderer;
  }
  
  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
  {
      String username = userManager.getRemoteUsername(request);
      if (username != null && !userManager.isSystemAdmin(username))
      {
          redirectToLogin(request, response);
          return;
      }
      
      response.setContentType("text/html;charset=utf-8");
      renderer.render("admin.vm", response.getWriter());
  }
  
  
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    {
        String username = userManager.getRemoteUsername(request);
        if (username != null && !userManager.isSystemAdmin(username))
        {
            redirectToLogin(request, response);
            return;
        }
        
        response.setContentType("text/html;charset=utf-8");
        renderer.render("admin.vm", response.getWriter());
    }
   
    
  private void redirectToLogin(HttpServletRequest request, HttpServletResponse response) throws IOException
  {
    response.sendRedirect(loginUriProvider  .getLoginUri(getUri(request)).toASCIIString());
  }
  
  private URI getUri(HttpServletRequest request)
  {
      StringBuffer builder = request.getRequestURL();
      if (request.getQueryString() != null)
      {
          builder.append("?");
          builder.append(request.getQueryString());
      }
      
    return URI.create(builder.toString());
  }
}

テンプレートを使う

さっきのコードで、テンプレートを使うための準備。
atlassian-plugin.xml に下記のコンポーネントを使う宣言を書く。また、Servletを使うのでエントリポイントを定義する。

	<component-import key="userManager" interface="com.atlassian.sal.api.user.UserManager" />
	<component-import key="loginUriProvider" interface="com.atlassian.sal.api.auth.LoginUriProvider" />
	<component-import key="renderer" interface="com.atlassian.templaterenderer.velocity.one.six.VelocityTemplateRenderer" />
	
	<servlet name="Example Admin Control panel" key="exampleadminservlet" class="jp.junoe.confluence.plugins.exampleadminservlet.ExampleAdminServlet">
		<url-pattern>/junoe/exampleadmincp</url-pattern>
	</servlet>

ここまでで、
http://localhost:1990/confluence/plugins/servlet/junoe/exampleadmincp
にアクセスすると、NotFoundではなくSERVER Errorになる。当然ながら、admin.vmというテンプレートが無い。


・・・が、このチュートリアルだけ見ててもどこに作るかわからない。

そういう時はソースコード見る。Atlassianのコードは公開されている。サイコウである。オンラインでも見ることができる。チュートリアルのコードは
https://svn.atlassian.com/fisheye/browse/public/contrib/tutorials

これを見ると、src/main/resources/に置けばいいみたいなんだけど・・・。

NetBeansでデバッガを接続してみる。

どーもよく分からなかったので、NetBeansでデバッガ接続。参考:Confluenceのプラグインを作ってみるメモ(2) - tohokuaikiのチラシの裏

すると、どうもdoGetのuserManager変数がnullになってるっぽい。エラーメッセージ

java.lang.NullPointerException
at jp.junoe.confluence.plugins.exampleadminservlet.ExampleAdminServlet.doGet(ExampleAdminServlet.java:33)

もそれっぽい。

というか、この新しく作ったメンバ変数、userManager/loginUriProvider/rendererが働いてないっぽい。

しかし、デバッガってすごいな。ブレイクポイントをポート通して実プログラムを止めてしまうんだもの・・・。


しかし、分からない(続く)