Hatena::Diary

s-ishigamiのcoding日記 RSSフィード

自画像

2009-12-05

Mayaa ファイルの共通化

 同じ機能のテンプレートが複数セット存在する場合を考えます。例えば、/1/A.htmlと、/2/A.htmlは、デザインが違いますが、全く同じ機能だとします。このとき、/1/A.mayaa を /2/A.mayaa に複製するのが基本です。しかし、それだと、/1/A.mayaaを修正したときは、同時に/2/A.mayaaも修正しなくてはなりません。/3/A.mayaa、/4/A.mayaaのように、さらに複製されていた場合はなおさら厄介です。

 

 複数のテンプレートが共通のMayaaファイル(Specファイル?)を参照する場合、手っ取り早い方法としては、templateSuffixを使う方法があります。

http://mayaa.seasar.org/documentation/template_suffix.html

 しかし、上記のようにフォルダでテンプレートをグループ分けしたい場合は、suffixは使いにくいです。

 シンボリックリンクによる方法も簡単です。これなら、Mayaaのカスタマイズなしに、すぐに使えます。しかし、Windows上でテストできない点が私はネックだと思いました。Javaシステムなので、OSサーバに依存しないで解決したいです。

 この度、Mayaa ユーザメーリングリストにて、次のように質問させていただきました。

 http://ml.seasar.org/archives/mayaa-user/2009-December/000868.html

 suga様の回答(ありがとうございます。)を参考に、SourceDescriptorのカスタマイズによって解決しました。以下ソースを貼っておきます。

package mypackage;

import java.io.InputStream;
import java.util.Date;

import org.seasar.mayaa.impl.source.PageSourceDescriptor;
import org.seasar.mayaa.source.SourceDescriptor;

public class MyPageSourceDescriptor extends PageSourceDescriptor {

	// ルートのmayaaファイルを探しに行くディスクリプタ
	private SourceDescriptor rootDescriptor = new PageSourceDescriptor();

	// 注意:SystemIDはmayaaファイルの絶対パス
	/**
	 * ソースSystemIDを設定する。
	 * 
	 * @param systemID
	 */
	@Override
	public void setSystemID(String systemID) {
		super.setSystemID(systemID);

		// ルートのパス取得。
		String rootId = getRootId(systemID);
		if (rootId != null) {
			rootDescriptor.setSystemID(rootId);
		} else {
			rootDescriptor.setSystemID(systemID);
		}
	}

	// 要求パスからルートのパスを解決する。
	private String getRootId(String systemId) {
		if (systemId.startsWith("/client_info/")) {
			int pt = systemId.indexOf("/", "/client_info/".length());
			if (pt != -1) {
				return systemId.substring(pt);
			}
		}
		return null;
	}

	/**
	 * ソースが存在するかどうかを取得する。
	 * 
	 * @return ファイルが存在すればtrue。無ければfalse。
	 */
	@Override
	public boolean exists() {
		// ルートの方が見つかりやすいから、処理高速化のためルート優先
		return rootDescriptor.exists() || super.exists();
	}

	/**
	 * ファイルのインプットストリームを取得する。
	 * 
	 * @return ストリーム。もしファイルが無い場合は、null。
	 */
	@Override
	public InputStream getInputStream() {
		InputStream result = super.getInputStream();
		if (result == null) {
			result = rootDescriptor.getInputStream();
		}
		return result;
	}

	private static final Date nullDate = new Date(0);

	/**
	 * ファイルの日付を取得する。
	 * 
	 * @return ファイルの最終更新日付。ファイルが無い場合は「new Date(0)」を返す。
	 */
	@Override
	public Date getTimestamp() {
		Date result = super.getTimestamp();
		if (result.equals(nullDate)) {
			result = rootDescriptor.getTimestamp();
		}
		return result;
	}
}

 このようにラッパーにすることで、外側からは完全に隠蔽しつつ、内部で代替ロジックを動かすことができます。教科書的に言えばMyPageSourceDescriptor はSourceDescriptorをimplementsして、PaseSourceDescriptorをもう一つフィールドとして持ち、メソッドをそちらに移譲するようにした方が、構造がわかりやすいでしょう。しかし、それだとコード量が増えてしまうので、わかった上で継承で代用することはありだと思ってます。

 これを動かしたところ、うまくユーザごとのMayaaファイルが存在するときはそちらを、存在しない時は、ルートのMayaaファイルを処理するようになりました。

 また、この修正の副作用として、ユーザのテンプレートが存在しない場合に、ルートのテンプレートを探すようになりました。内部的にinsertしている場合も、うまいこと処理してくれるので、Mayaa内部で賢いことをしてくれているのだと思います。

 勘違いしてました。SourceDescrptorは、mayaaファイルだけでなく、htmlテンプレートも探しに行くようです。私としては大変都合が良いことでしたが、勘違いしないように気を付けた方が良さそうですね。

2009-09-08

MayaaでGuice2.0 AOPを使うとうまく動かない件〜解決編

http://d.hatena.ne.jp/s-ishigami/20090906/1252210901 の続きです。

MLにてsugaさんに回答いただき、無事解決することができました。感謝です。

解決方法

Mayaa Blank Warにバンドルされているrhino-1.7r.jarを使用せず、下記URLよりRhino最新版を入手して、その中のjs.jarを使用する。

http://www.mozilla-japan.org/rhino/download.html

解説

Rhinoには、js.jarとjs-14.jarの2種類のjarファイルが存在し、前者はJava5以上、後者はJava1.4でも動くとのことです。

Guiceを使っているならJava5なので、Guice+Mayaaの組み合わせはこれで問題なさそうです。

2009-09-06

MayaaでGuice2.0 AOPを使うとうまく動かない件

View層にMayaaを使っているアプリケーションで、AOP的な機能が必要になり、Guice 2.0 を試したところ、はまってしまいました。

MLに質問したところ、簡単に試せるサンプルが欲しいとのことなので、作りましたが、公開する場所がないので、とりあえずここに書きます。

環境

以下の環境でテストしました。

プロジェクト作成

プロジェクトのベースとして、http://mayaa.seasar.org/downloads/index.html から、"Blank War"を使用しました。

Guiceは、http://code.google.com/p/google-guice/downloads/list からguice-2.0.zip を取得し、guice-2.0.jar と、aopalliance.jarだけをlibの中にコピーしました。

ソースコード

これに以下のコードを追加・修正します。

まず、ビーン

package example;
import java.util.Date;

public class MyBean {
	private String name;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getHello() {
		return "hello," + getName() + ". it's" + new Date();
	}
}

ビーンにアスペクトを挿入するモジュール

package example;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import com.google.inject.AbstractModule;
import com.google.inject.matcher.Matchers;

class MyModule extends AbstractModule {

	private static class MyIntercepter implements MethodInterceptor {
		public Object invoke(MethodInvocation invocation) throws Throwable {
			System.out.println(invocation.getThis().getClass().getName() + "#" + invocation.getMethod().getName() + "start");
			try {
				return invocation.proceed();
			} finally {
				System.out.println(invocation.getThis().getClass().getName() + "#" + invocation.getMethod().getName() + "end");
			}
		}
	}

	@Override
	protected void configure() {
		bindInterceptor(
				Matchers.subclassesOf(MyBean.class),
				Matchers.any(),
				new MyIntercepter());
	}
}

ビーンを生成してリクエストに格納するサーブレット

package example;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.inject.Guice;
import com.google.inject.Injector;

public class MyServlet extends HttpServlet{
	
	private static Injector injector = Guice.createInjector(new MyModule());
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		MyBean bean;
		if ("true".equals(req.getParameter("aop"))) {
			bean = injector.getInstance(MyBean.class);
		} else {
			bean = new MyBean();
		}
		
		bean.setName(req.getParameter("name"));
		req.setAttribute("bean", bean);
		req.getRequestDispatcher("/view.html").forward(req, resp);
	}
}

結果を表示するview.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=UTF-8">
		<title>Hello</title>
	</head>
	<body>
		message:<span id="hello">HELLO</span>
	</body>
</html>

view.mayaa

<?xml version="1.0" encoding="UTF-8"?>
<m:mayaa xmlns:m="http://mayaa.seasar.org">
	<m:write m:id="hello" value="${request.bean.getHello();}" />
</m:mayaa>

最後にweb.xml

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE web-app
	PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
	"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

	<servlet>
		<servlet-name>MayaaServlet</servlet-name>
		<servlet-class>org.seasar.mayaa.impl.MayaaServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet>
		<servlet-name>MyServlet</servlet-name>
		<servlet-class>example.MyServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>MayaaServlet</servlet-name>
		<url-pattern>*.html</url-pattern>
	</servlet-mapping>
	
	<servlet-mapping>
		<servlet-name>MyServlet</servlet-name>
		<url-pattern>/myservlet</url-pattern>
	</servlet-mapping>

</web-app>

実行結果:

message:hello,hoge. it'sSun Sep 06 12:33:40 JST 2009

  • ttp://localhost:8080/mayaa-guice/myservlet?name=hoge&aop=true

こちらは画面はTomcatエラーが表示され、以下のログメッセージが出力されていました。

example.MyBean$$EnhancerByGuice$$c8e25a70#setNamestart

example.MyBean$$EnhancerByGuice$$c8e25a70#setNameend

2009/09/06 12:34:25 org.seasar.mayaa.impl.engine.error.TemplateErrorHandler doErrorHandle

情報: error template not found, /java.lang.NullPointerException

2009/09/06 12:34:25 org.seasar.mayaa.impl.engine.error.TemplateErrorHandler doErrorHandle

情報: error template not found, /java.lang.RuntimeException

2009/09/06 12:34:25 org.seasar.mayaa.impl.engine.error.TemplateErrorHandler doErrorHandle

情報: error template not found, /java.lang.Exception

java.lang.NullPointerException

at org.mozilla.javascript.net.sf.retrotranslator.runtime.impl.MethodDescriptor.getInstance(MethodDescriptor.java:137)

at org.mozilla.javascript.net.sf.retrotranslator.runtime.java.lang.reflect._Constructor.isVarArgs(_Constructor.java:83)

at org.mozilla.javascript.jdk15.VMBridge_jdk15.isVarArgs(VMBridge_jdk15.java:66)

at org.mozilla.javascript.MemberBox.init(MemberBox.java:86)

at org.mozilla.javascript.MemberBox.<init>(MemberBox.java:72)

at org.mozilla.javascript.JavaMembers.reflect(JavaMembers.java:667)

at org.mozilla.javascript.JavaMembers.<init>(JavaMembers.java:76)

at org.mozilla.javascript.JavaMembers.lookupClass(JavaMembers.java:838)

at org.mozilla.javascript.NativeJavaObject.initMembers(NativeJavaObject.java:90)

at org.mozilla.javascript.NativeJavaObject.<init>(NativeJavaObject.java:80)

at org.mozilla.javascript.NativeJavaObject.<init>(NativeJavaObject.java:70)

at org.mozilla.javascript.WrapFactory.wrapAsJavaObject(WrapFactory.java:149)

at org.seasar.mayaa.impl.cycle.script.rhino.WrapFactoryImpl.wrapAsJavaObject(WrapFactoryImpl.java:53)

at org.mozilla.javascript.WrapFactory.wrap(WrapFactory.java:105)

at org.mozilla.javascript.ScriptRuntime.toObject(ScriptRuntime.java:962)

at org.mozilla.javascript.ScriptRuntime.toObjectOrNull(ScriptRuntime.java:918)

at org.mozilla.javascript.ScriptRuntime.getPropFunctionAndThis(ScriptRuntime.java:2213)

at org.mozilla.javascript.optimizer.OptRuntime.callProp0(OptRuntime.java:117)

at org.mozilla.javascript.gen.c1._c0(/view.mayaa#write:3)

at org.mozilla.javascript.gen.c1.call(/view.mayaa#write)

at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:398)

at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3065)

at org.mozilla.javascript.gen.c1.call(/view.mayaa#write)

at org.mozilla.javascript.gen.c1.exec(/view.mayaa#write)

at org.seasar.mayaa.impl.cycle.script.rhino.TextCompiledScriptImpl.normalExecute(TextCompiledScriptImpl.java:126)

at org.seasar.mayaa.impl.cycle.script.rhino.TextCompiledScriptImpl.execute(TextCompiledScriptImpl.java:166)

at org.seasar.mayaa.impl.engine.processor.WriteProcessor.writeValue(WriteProcessor.java:109)

at org.seasar.mayaa.impl.engine.processor.WriteProcessor.writeStartElement(WriteProcessor.java:161)

at org.seasar.mayaa.impl.engine.processor.AbstractAttributableProcessor.processStart(AbstractAttributableProcessor.java:185)

at org.seasar.mayaa.impl.engine.processor.AbstractAttributableProcessor.doStartProcess(AbstractAttributableProcessor.java:169)

at org.seasar.mayaa.impl.engine.RenderUtil.renderTemplateProcessor(RenderUtil.java:134)

at org.seasar.mayaa.impl.engine.RenderUtil.renderProcessorTree(RenderUtil.java:264)

at org.seasar.mayaa.impl.engine.TemplateImpl.doTemplateRender(TemplateImpl.java:200)

at org.seasar.mayaa.impl.engine.PageImpl.renderTemplate(PageImpl.java:241)

at org.seasar.mayaa.impl.engine.RenderUtil.renderPage(RenderUtil.java:349)

at org.seasar.mayaa.impl.engine.PageImpl.doPageRender(PageImpl.java:189)

at org.seasar.mayaa.impl.engine.EngineImpl.doPageService(EngineImpl.java:371)

at org.seasar.mayaa.impl.engine.EngineImpl.doService(EngineImpl.java:493)

at org.seasar.mayaa.impl.MayaaServlet.doService(MayaaServlet.java:97)

at org.seasar.mayaa.impl.MayaaServlet.doGet(MayaaServlet.java:80)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:627)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)

at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:679)

at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:461)

at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:399)

at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)

at example.MyServlet.doGet(MyServlet.java:31)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:627)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)

at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:875)

at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)

at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)

at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)

at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)

at java.lang.Thread.run(Thread.java:595)

注目点

ログの

example.MyBean$$EnhancerByGuice$$c8e25a70#setNamestart

example.MyBean$$EnhancerByGuice$$c8e25a70#setNameend

という箇所に注目していただくと、Guiceによる、AOPの挿入は成功していることがわかります。

また、

2009/09/06 12:34:25 org.seasar.mayaa.impl.engine.error.TemplateErrorHandler doErrorHandle

の箇所から、MayaaServletにフォワードされていることもわかります。

スタックトレースを読むと、

java.lang.NullPointerException

at org.mozilla.javascript.net.sf.retrotranslator.runtime.impl.MethodDescriptor.getInstance(MethodDescriptor.java:137)

at org.mozilla.javascript.net.sf.retrotranslator.runtime.java.lang.reflect._Constructor.isVarArgs(_Constructor.java:83)

at org.mozilla.javascript.jdk15.VMBridge_jdk15.isVarArgs(VMBridge_jdk15.java:66)

at org.mozilla.javascript.MemberBox.init(MemberBox.java:86)

JavaScriptエンジン内で問題が発生しています。

また、MyModuleのconfigure()を

@Override
	protected void configure() {
//		bindInterceptor(
//				Matchers.subclassesOf(MyBean.class),
//				Matchers.any(),
//				new MyIntercepter());
	}

のようにコメントアウトすると、エラーが出なくなりました。

私の予想では、JavaオブジェクトをJavaScriptオブジェクトに変換しようとしたタイミングで、Guiceが作成したオブジェクトのクラス情報が、クラスローダ内に何らかの理由で残っておらず(リクエストの中のMyBeanはもはやexample.MyBeanではない)、取得できず、ヌルポンで落ちていると思います。

Mayaaの問題というより、JavaScriptエンジンの問題なのですが、MayaaにバンドルされているJavaScriptエンジンは最新(rhino-1.7r2)ですし、今後GuiceとMayaaを組み合わせて使いたい人が現れるかもしれないため、報告したいと思った次第です。

ちなみに、MayaaはSeasarプロジェクトなので、AOPはS2Containerを使った方が無難だったかもしれませんね:-)

解決

解決しました。

http://d.hatena.ne.jp/s-ishigami/20090908/1252383862

2009-08-22

HTML5 Canvasを試してみた。

ちょっと前ですが、ブラウザ上で動くゲームを作るプラットフォームにならないか実験してみましたので、ソースを貼ります。

以下の通りに書いて実行すると、画面上をたくさんの"■"が飛びはね、端っこに言ったらバウンドします。

f:id:s-ishigami:20090822131117p:image:medium

html_canvas.html

<!doctype html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Canvas DEMO</title>

</head>
<body>
<canvas id="mainCanvas" width="640" height="480">
</canvas>
<script src="canvas.js" type="text/javascript"></script>
</body>
</html>

canvas.js

(function() { 
	
	var WIDTH = 300;
	var HEIGHT = 200;

	window.onload = function() {initCanvas();};
	var canvas;
	var context;
	var x, y, dx, dy;
	var balls;
	
	var Ball = function(x, y, dx, dy, color) {
		this.color = color;
		this.x = x;
		this.y = y;
		this.dx = dx;
		this.dy = dy;
		
		this.move = function() {
			this.x += this.dx;
			this.y += this.dy;
			
			if (this.x < 0 || this.x > WIDTH) {
				this.dx = -this.dx;
			}
			
			if (this.y < 0 || this.y > HEIGHT) {
				this.dy = -this.dy;
			}
		};
		
		this.draw = function() {
			context.fillStyle = color;
			context.fillRect(this.x, this.y, 10, 10);
		};
	};

	function initCanvas() {
		
		canvas = document.getElementById('mainCanvas');
		if(!canvas.getContext) {
			alert('unsupported browser');
			return;
		}
		
		context = canvas.getContext('2d');
		balls = [new Ball(100, 100, rndVelocity(), rndVelocity)];
		for (var i = 0; i < 30; i++) {
			balls[i] = new Ball(100, 100, rndVelocity(), rndVelocity(), rndColor());
		}
		setInterval(next, 50);
	}
	
	function rndVelocity() {
		return (Math.random() - 0.5) * 30;
	}
	
	function rndColor() {
		return '#' + ((Math.floor((Math.random()) * 0xFFFFFF)));
	}
	
	function move() {
		for (var i = 0; i < balls.length; i++) {
			balls[i].move();
		}
	}

	function draw() {
		context.clearRect(0,0,640,480);
  		context.beginPath();
  		for (var i = 0; i < balls.length; i++) {
			balls[i].draw();
		}
	}
	
	function next() {
		move();
		draw();
	}

})();

普段はJavaScriptオブジェクトを作ろうとは思わないのですが、

こういうゲームっぽいものを作ろうと思うと自然とオブジェクト指向

になるみたいです。

モデル化しやすいからかな。

目下の課題はこんなところですね。

  • タイマーが、setInterval(またはsetTimeout)くらいしかない
    • 本当はsleep+無限ループで動かしたい。
    • 模擬的にsleepを作っても、今度はrefreshがない(?)から再描画されない。(ループを抜けるまで何も描かれない)
  • そのため、FPS60で固定するのが難しい。
    • コマ落ちしたときの扱いとか不安
  • IEだとexcanvasを使えばできるけどゲームとしては使い物にならないくらい遅い。
  • ランダムに色を与えてるはずなのに、同じような色になる。JavaScriptのMath.random()の仕様?

contextを2Dではなく、今後実装されるであろう3Dを使えばならもっと描画速度が速いかもしれませんね。

2009-07-20

MayaaでJSPをinclude→できません!

今、既存プロジェクトにMayaaを導入しようとしています。

  • なぜMayaaなのか?
  • Wicketを勉強していたのではないのか?

いや、いろいろと経緯がありましてね。書くと長くなるので割愛します。

で、既にJSPによって、デザインが組み込まれているのですが、それだとデザインの修正が困難なので、HTMLテンプレートによって超楽にデザイン修正ができるようにしてしまおう作戦です!

さて、早速組み込みを始めてみます。

よく見ると、JSPは共通部品ごとに分割されていて、includeしている感になってます。でもこれだと、ブラウザでプレビューしたときに細切れとなってしまうため、HTMLテンプレートとしては微妙ですね。。。

そこで、とりあえずは、目で見える部品については、各ファイルに同じ内容を記述させることにします。どうせデザイナーさんはコピペするでしょうし。

しかし、よくよく見ると

JavaScriptのロードまで、JSPインクルードしてるじゃないですか!

なるほど、JavaScriptコードの中でJSPスクリプトレットを処理させてるんですね。確かに、やりたい気持ちはわかります。あと、キャッシュまわりの制御が意外と面倒なので、src属性じゃなくて、ページの中のscriptタグに出力させたい気持ちもよーくわかります。

じゃあ、こういうところだけは、JSPから持ってこようかなと思いました。

MayaaからJSPテンプレートをincludeし...あれ、できません!

http://mayaa.seasar.org/documentation/implicit_object.html#functions

をどう見ても、includeという関数はありません。

できないものは作れ!

僕はプログラマー、不可能はない!

じゃあJavaクラスを処理できるMayaaの特性を利用して、ちょっくらこしらえてしまいましょう。

まず、こんなjsを書きました。


/// グローバル関数置き場
/// @author ishigami
var httpRequest = どこかしらからhttpServletRequestを取ってくる。
var httpResponse = どこかしらからhttpServletRequestを取ってくる。
var util = new Packages.jp.my.company.util.MayaaUtil(httpRequest, httpResponse);

〜省略〜

これをdefault.mayaaに組み込みます。

<?xml version="1.0" encoding="UTF-8"?>
<m:mayaa xmlns:m="http://mayaa.seasar.org">
	<m:beforeRender>
		load('/view/mayaa_script/util.mjs');
	</m:beforeRender>
</m:mayaa>

そして、MayaaUtilを作成します。

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MayaaUtil {
	private HttpServletRequest req;
	private HttpServletResponse res;
	
	public MayaaUtil(HttpServletRequest request, HttpServletResponse response) {
		super();
		this.req = request;
		this.res = response;
	}

	public void include(String path) throws ServletException, IOException {
		req.getRequestDispatcher(path).include(req, res);
	}
}

これでどうだー!

と思って実行してみたのですが、残念!以下のようなエラーメッセージがコンソールに出力されて失敗してしまいました。orz

[INFO] TemplateErrorHandler - error template not found, /org.seasar.mayaa.impl.cycle.script.rhino.OffsetLineRhinoException
[INFO] TemplateErrorHandler - error template not found, /org.mozilla.javascript.EvaluatorException
[INFO] TemplateErrorHandler - error template not found, /org.mozilla.javascript.RhinoException
[INFO] TemplateErrorHandler - error template not found, /java.lang.RuntimeException
[INFO] TemplateErrorHandler - error template not found, /java.lang.Exception
org.seasar.mayaa.impl.cycle.script.rhino.OffsetLineRhinoException: Wrapped org.apache.jasper.JasperException: Exception in JSP: /view/topframe.jsp:30
 
27: </div>
28: </div>
29: <%-- ★カテゴリ&フリーワード検索インクルード --%>
30: <jsp:include page="/view/search.jsp" flush="true" />
 
Stacktrace: in script=
    response.getOutputStream().flush();    util.include('/view/topframe.jsp');        (/view/top/top.mayaa#exec#29)
	at org.seasar.mayaa.impl.cycle.script.rhino.TextCompiledScriptImpl.execute(TextCompiledScriptImpl.java:210)
	at org.seasar.mayaa.impl.engine.processor.ExecProcessor.doStartProcess(ExecProcessor.java:70)
	at org.seasar.mayaa.impl.engine.RenderUtil.renderTemplateProcessor(RenderUtil.java:134)

どうやら、OutputStreamを勝手にいじったのが悪かったみたいです。正しく出力できなかったみたいですね。

処理自体は走っています。Eclipse+WTPのデバッガで、ブレークポイントで止めることもできました。

調べたら以下のようにMLで質問された方がいるんですね。

http://ml.seasar.org/archives/mayaa-user/2007-October/000587.html

http://ml.seasar.org/archives/mayaa-user/2007-October/000588.html

http://ml.seasar.org/archives/mayaa-user/2007-October/000589.html

うーん。やっぱり無理なのか...残念だなぁ。


あとがき(というかぼやき)

久しぶりにエントリを書きました。さぼっていたわけではありませんよ。そもそも、書くネタがなかったんです。ネタがないのに無理矢理書こうとすると、(僕の場合は特に)与太話になってしまうので、なるべく書くことがないと書かないことに決めています。このブログはできる限り技術的な記録しか残さないつもりなので。

また、会社員という僕の立場が、結局無難で枯れた技術を好んで使いがちということも、「新しいことに挑戦しない→今更書いても仕方がない」という状況を導き出しています。

まぁ、それでも書くことが時々出てきたりするのでいいのかなーと思ってます。