Showing posts with label mixer2. Show all posts
Showing posts with label mixer2. Show all posts

Sunday, May 27, 2012

mixer2がjavax.cache (JSR-107)に対応

mixer2 1.1.3をリリースしました。既にmavenセントラルリポジトリから利用可能です。

まだ一部ですが、javadocを英語と日本語の併記にしたほか、 ロードしたテンプレートをキャッシュして性能向上させられるなりました。 JSR-107として規格化されつつある javax.cache.Cache の実装クラスのインスタンスをMixer2Engine内にsetするだけで使えます。 詳しくは javadoc に。

とはいっても、実は、手元でいろいろためしたのですが、キャッシュを使ってもそれほど性能はあがりません。^^;) いまのところおそらく唯一であろうJSR107の実装であるehcache-1.4.0beta1を使ってテストしたのですが、 mixer2が普通にhtmlテンプレート文字列をロードしてHtml型オブジェクト化するのと、キャッシュからHtml型オブジェクトを取り出すのとではそれほど大きな性能差が見られませんでした。

見方はいろいろですが、mixer2の性能はもともとそれほど悪くはないと言えるのかもしれませんし、ehcacheの今後の改良次第で差が現れてくるのかもしれません。いずれにせよJSR-107を実装するキャッシュフレームワークはどんどん種類が増えてくるはずですので、今後に期待しましょう。

Thursday, March 15, 2012

mixer2をmavenのセントラルリポジトリに登録しました

とりあえず最新版を登録しました。 http://search.maven.org/#artifactdetails|org.mixer2|mixer2|1.1.0|jar です。 以後、バージョンアップはすべてセントラルに登録していきます。

これまでは独自リポジトリでやっていたので、repositoryタグに http://mixer2.org/mvn/ を指定する必要がありましたが、 これからは普通に dependencyタグを書くだけで利用できます。

ソースコードも、プロジェクト自体をgithubに置いて晒すことにしました。 https://github.com/nabedge/mixer2です。 readme.mdファイルはそのうち作るつもりです。 これまでも*-sources.jarの形で公開はしていたのですが、これでみなさんにforkしてもらいやすくなりました。 ライセンスはApache License 2です。

詳しい説明は http://mixer2.org/site/にあります。 これからも、ごひいきに!

Sunday, August 28, 2011

Chrome+HTML5カンファレンスでライトニングトークしてきました。

先週、Chrome+HTML5 カンファレンス at Google Japan(六本木ヒルズ)で、ライトニングトークに参加してきました。お礼が遅れてしまいましたが、当日の運営の皆様に感謝します。

Thursday, May 5, 2011

mixer2 1.0.8リリース。TableBuilderでテーブルを組むのが楽になりました。

詳しくは公式サイトのほうをご覧ください。mixer2 - TableBuilder です。あとJavaDocも。→TableBuilder (mixer2 1.0.8 API)

table,tr,tdだけでなく、tbodyやthead,tfootタグにも対応していますので、ブラウザ側でも、たとえばjqueryのdatatables等のライブラリと組み合わせやすいでしょう。たとえば「ASCII.jp:JavaScriptだけで表<table>を並び替え!」とか。

Saturday, April 23, 2011

Tableタグを作るBuilderクラスをつくってます

mixer2で、table,tr,tdタグを組もうとすると、こうなります。

import static org.mixer2.xhtml.TagCreator.*;
...
Table table = new Table();
// 一個目のtd
Td td1 = td(); // td = new Td(); と同じ意味になります。
Tr tr = tr();
td1.getContent.add("a");
tr.getThOrTd().add(td1);
// 2個目のtd
td2 = td();
td2.getContent.add("b");
tr.getThOrTd().add(td2);
// tableに収める
table.getTr().add(tr);
...

面倒ですよね(笑)。他のタグならともかく、tableタグはデータ表示などの目的での利用頻度がものすごく高いタグですので、これじゃあちょっと、あんまりです。

そこで、こんな風に、わかりやすくtableを組めるTableBuilderクラスをつくっているところです。

...
TableBuilder tb = new TableBuilder();
tb.tr(0).td(0).add("a"); // 1行目、1列目のtdにaがはいる
tb.tr(0).td(1).add("b"); // 1行目、2列目のtdにbがはいる
Table table = tb.build(); // これでtableタグ全体ができる
...

もちろんこれだけでなく、行、列のindexを指定しなくてもadd("a")とかするだけで最後尾に自動的にtrやtdを作るようなメソッドもつくろうかなとも思っています。いろいろと試しているところです。

mixer2の次期リリースに搭載できると思います。乞うご期待。

Wednesday, April 20, 2011

mixer2 version1.0.6リリース。FormUtilクラスを追加しました。

formタグ内部のinputやselect等に、JavaBeanクラスの内容を自動的に挿入するユーティリティが追加されました。詳しくは mixer2 - Form and JavaBean をご覧ください。

Strutsのアクションフォームクラスや、Spring MVCのcommandクラスでも使われている、一般的なJavaBeanをそのまま使うことができます。Webアプリにおいて、formタグを使ったCRUD的な画面を生成する際に、結構便利に使えると思われます。

Saturday, March 19, 2011

mixer2 version1.0.4で部分マーシャル機能が追加されました

従来のmixer2は、Webページの全体、つまり<html>から</html>までを一気に文字列化する必要がありました。

version1.0.4以降、任意のタグ、例えば<div>から</div>までなど、htmlの一部分だけを出力(マーシャル)することができるようになりました。

これによって、たとえばVelocityやJSPなど、他のテンプレートエンジンと組み合わせて使うために、Webページの一部だけをmixer2で出力したいという要求に答えられるようになりました。

Sunday, March 6, 2011

mixer2での繰り返しデータの埋め込み

先月のことですが、こんなツイートを見かけました。

mixer2おもしろそう。 http://goo.gl/W1pRO スクリプトや式といった処理と、テンプレートをキレイに分けられそう。繰り返しデータの埋め込みもサポートされているなら、Wicketのテンプレートだけ取り出したような、自分的には理想のテンプレートエンジンになりそう。
とある方のつぶやきより)

mixer2に好感を持っていただけているようでうれしいです。

嬉しいよというついでに、「繰り返しデータの埋め込みもサポートされているなら」という点について、mixer2開発者としての説明をしてみたいと思います。

ツイート主さんの懸念、というよりは素朴な疑問と言うべきそれは、とても当然です。 Hello Worldには本当にHelloWorldを表示することしか書いてませんから。 どんなプログラマーでも、Javaでの開発でよく使われるJSPやVelocityのような従来のテンプレートエンジンとの比較を無意識に考えてしまうので、「じゃあ、ループしながら値を埋め込むようなときはどうすんだろ?」とふと思うのは当然です。

結論を言うと、
Q.たとえばDB検索の結果とかで複数の値があるとき、それを繰り返し処理しながら表示するのって、mixer2ではどうやんの?
A.普通にJavaでforやwhileなどを使ってください。
なのです。

具体的なサンプルソースは本家サイトのTIPSのページの下のほうに書いておきました。

さて、上のリンク先、見ていただけましたでしょうか?そう、コードが長いですww。 JSPだったら<c:foreach>のようなカスタムタグを含めた3,4行ですみそうなところが、 mixer2だと10行くらいになっちゃってます(コメント行いれると15,6行!)

もちろん、これがベストプラクティスだということではありません。 こうした繰り返し処理を簡略化する汎用ユーティリティのようなものをmixer2のほうで用意するべきなのかもしれません。

ともあれ、ひとまずはmixer2を使う側のコーディングでどうにでもなりますよ、ということはなんとなくわかっていただけると思います。なにしろ、VelocityのVTL言語でもなくJSPのカスタムタグでもなく、ただのJavaコーディングなのですから。

Wednesday, February 23, 2011

タグの中身の操作方法

XHTML/HTMLのタグの多くは内部に任意のタグまたは文字列を持つことができます(入れ子タグ)。 mixer2でのタグの中のタグ/文字列へのアクセスと操作方法の基本について解説します。

divやspanのように、中になんでも入れられるようなタグの場合は必ずプロパティとしてcontent(java.util.List型)を持っており、それに対するgetContent(), setContent(), unsetContent()で操作することができます。

例えば次のような形でテンプレートをloadしたと仮定します。

<html>
<head>
   <title>タイトルです</title>
</head>
<body>
    <div id="foo">aaa<b>bbb</b>ccc</div>
</body>
</html>
Html html = mixer2Engine.loadHtmlTemplate(new File("テンプレファイル"));
Div div = html.getById("foo",Div.class);
java.util.List list1 = div.getContent();

このとき、list1の内部は次のような値が格納されています。

添え字内容
0java.lang.Stringaaa
1org.mixer2.jaxb.xhtml.BBタグオブジェクト
2java.lang.Stringccc

list1はdivタグの中身の実体をList型で抱えていますので、あとは普通にList型を扱うように add(追加したいもの)、remove(消したいものの添え字)、set(添え字、置換物)等のメソッドで扱えます。

Html html = mixer2Engine.loadHtmlTemplate(new File("テンプレファイル"));
Div div = html.getById("foo",Div.class);
java.util.List list1 = div.getContent();

list1.add("ddd"); 
list1.set(1, new Br());
list1.remove(2);
System.out.println(m2e.saveToString(html));

上記によって、divタグの中を次のように書き換えたものを得ることができます。

<html>
<head>
<title>タイトルです</title>
</head>
<body>
<div id="foo">aaa<br />ddd</div>
</body>
</html>

Friday, February 18, 2011

モックhtmlの内容を操作する(アンカーリンク編)

通常のJava/JSPによるWeb開発では、htmlモックをJSPに書きなおす作業をします。この作業によって、Webデザイナーでは手が出せないような呪文が埋め込まれていきます。<form> が<html:form>になったり、<c:if test="${user.isLogin == true }" />こんにちは${user.name}さん!</c:if> と書き加えたりする、あの作業です。

JSPに書きなおす作業が発生し、さらにJSPに書き換えたが最後デザイナーはほとんど手が出せなくなる(うっかり修正してJSPの呪文を壊すとまずい)のですから、この工程に入った瞬間から開発現場の生産性はガタ落ちです。jspなのでアプリとして実行できる状態まで作業しないと、見栄えの確認も修正もできません。モックhtml作成のときのように「ちょっとブラウザで表示してみて見栄えを確認してまた修正する」といったことはできないのです。

そんな愚痴はさておき、ではmixer2ではそこをどう解決するのか?といったお話を少しずつ書いてゆきます。今日はアンカーリンク編です。aタグとformタグ(のaction属性等)についてお話しします。

たとえばテンプレート(htmlモック)に書いたaタグで
<a href="detail.html">
となっている箇所はすべて
<a href="/contextPath/foo/detail?id=99">
のような形に書き換えなければならない、と想定します。

この場合まず、テンプレートを作る段階で当該のaタグにid属性またはclass属性をつけておいてもらうのが早道です。

<a href="detail.html" id="detailLink" > ※このリンクがページ上に唯一ならid属性で
あるいは
<a href="detail.html" class="detailLink" > ※リンクがページ上に複数あるならclass
といった感じです。命名規則は特にありませんのでデザイナーとプログラマーの間で適当に取り決めておいてください。

テンプレート(htmlモック)をMixer2EngineでロードしてHtml型のオブジェクトに変換したら、次のようにします。

File file = ResourceUtil.getResourceAsFile("detail.html");
Html html = mixer2Engine.loadHtmlTemplate(file);
// id属性で走査して書き換え
html.getById("detailLink", A.class).setHref(
    request.getContextPath() + "/foo/detail?id=" + 99);
// class属性で走査してそれら全部を書き換え
for (A a : html.getDescendants("detailLink", A.class)) {
    a.setHref(request.getContextPath() + "/foo/detail?id=" + 99);
}

これで、該当のid属性またはclass属性を持つaタグのhref属性はすべて動的に書きかえられます。

formタグも同様です。htmlモック上では紙芝居のように画面遷移させるために
<form id="fooForm" method="get" action="thanks.html">
のようになっていたとすると、

html.getById("fooForm",Form.class).setAction(request.getContextPath() + "/foo/thanks");
html.getById("fooForm",Form.class).setMethod("post");

によって、
<form id="fooForm" method="post" action="/contextPath/foo/thanks">
に書き換えることができます。

Saturday, February 12, 2011

テンプレートhtmlをファイルじゃなくDBに保存できる

Webアプリのテンプレート、といえばJSPファイルです。しかし、mixer2ではカスタムタグ満載のjspではなく、デザイナーさんが作った普通のモックhtmlのファイルでOKです。

さらに、mixer2のテンプレートは、ファイルである必要すらありません。HelloWorldの例のようなjava.io.Fileオブジェクトだけでなく、Stringもテンプレートとして読み込めるからです。メソッドはloadHtmlTemplate(java.lang.String)です。

たとえばECサイト構築のASPサービスがあるとします。店舗ごとにまったく異なるデザインを見せるために、テンプレートは店舗ごとに異なるものを管理する必要があります。ブログサービスでも似たようなものですね。

店舗が10個くらいのうちはいいのですが、数百、数千となってくると、テンプレートをファイルで管理することが難しくなってきます。商品データ等と同様に、テンプレートもDB上で管理したくなってきます。

しかしJSPではテンプレートをDBで管理することは事実上困難です。Velocityも、DataSourceResourceLoaderによってテンプレートをDB管理することはできるものの、J2EEサポートを必要とするといった制約があり、使い勝手はあまりよくないようです。

しかしmixer2では単なるStringとして定義されたテンプレートhtmlを扱えます。
SAStrutsでのHelloWorldサンプルを、テンプレートをDBから読み込むとすると次のようになります。
// O/RマッパーとしてS2JDBCを使っていて、
// TEMPLATE_TABLEのTEMPLATEというカラムに
// テンプレートが保存されていると仮定します。
public class IndexAction {

    @Resource
    protected Mixer2Engine mixer2Engine;

    @Resource
    protected JdbcManager jdbcManager;

    public String htmlString;

    @Execute(validator = false)
    public String index() throws IOException, TagTypeUnmatchException {
        TemplateTable tt = jdbcManager
            .from(TemplateTable.class)
            .where(eq(id(),999))
            .getSingleResult();
        String templateString = tt.template;
        Html html = mixer2Engine.loadHtmlTemplate(templateString);
        html.getById("hellomsg", Div.class).unsetContent();
        html.getById("hellomsg", Div.class).getContent().add("Hello World!");
        htmlString = mixer2Engine.saveToString(html);
        return "index.jsp";
    }
}

以上、TIPSでした。