-Tapestry-S2連携再考(3)
今やりかけているのは、IRequestCycle をいじって、以下のようなページオブジェクトがあるときに、デフォルトでS2Containerからコンポーネントをセットしてくれるようにしようとしてます。
package sample.org.seasar.contribute.tapestry; import org.apache.tapestry.html.BasePage; public class Home extends BasePage { private Counter counter; public Counter getCounter() { return counter; } public void setCounter(Counter counter) { this.counter = counter; } }
いつでも、getCounter()したら、S2Container上の"counter"という名前のコンポーネントを自動で取得できるようにしようと思ってます。動かないコードですが、以下をデバッグ中。
package org.seasar.contribute.tapestry; import org.apache.tapestry.IEngine; import org.apache.tapestry.IPage; import org.apache.tapestry.engine.IEngineService; import org.apache.tapestry.engine.IMonitor; import org.apache.tapestry.engine.RequestCycle; import org.apache.tapestry.request.RequestContext; import org.seasar.framework.beans.BeanDesc; import org.seasar.framework.beans.PropertyDesc; import org.seasar.framework.beans.impl.BeanDescImpl; import org.seasar.framework.container.S2Container; public class RequestCycleProxy extends RequestCycle { public RequestCycleProxy(IEngine engine, RequestContext requestContext, IEngineService service, IMonitor monitor) { super(engine, requestContext, service, monitor); } // ベタですが、フィルタです。 private Class[] filteredClasses = { java.util.Collection.class, java.util.Map.class, org.apache.tapestry.event.ChangeObserver.class, org.apache.tapestry.IBeanProvider.class, org.apache.tapestry.IComponent.class, org.apache.tapestry.IEngine.class, org.apache.tapestry.ILocation.class, org.apache.tapestry.IMessages.class, org.apache.tapestry.INamespace.class, org.apache.tapestry.IPage.class, org.apache.tapestry.IRequestCycle.class, org.apache.tapestry.spec.IComponentSpecification.class }; private boolean isFiltered(Class clazz) { for(int i = 0; i < filteredClasses.length; i++) { if(clazz.equals(filteredClasses[i])) { return true; } } return false; } private void setS2Components(IPage page) { Object global = page.getGlobal(); if(global instanceof GlobalProxy) { S2Container container = *1; for(int i = 0; i < pageDesc.getPropertyDescSize(); i++) { PropertyDesc propertyDesc = pageDesc.getPropertyDesc(i); Class propertyClass = propertyDesc.getPropertyType(); String propertyName = propertyDesc.getPropertyName(); if(propertyClass.isInterface() && !isFiltered(propertyClass)) { try { Object component = container.getComponent(propertyName); propertyDesc.setValue(page, component); } catch (RuntimeException e) {/*do nothing*/} } } } } // ここの、setS2Components(page);を呼び出すタイミングは考慮中 public IPage getPage() { IPage page = super.getPage(); setS2Components(page); return page; } public IPage getPage(String name) { IPage page = super.getPage(name); setS2Components(page); return page; } }
propertyDesc.setValue(page, component);で、IllegalArgumentExceptionがでちゃうんですよ。あと、めちゃんこ効率が悪いです。ぐるぐるループが廻ってます。またしばらく仕事したら続きをやります。
...ということで、いろいろ見ましたが、わからんです。しっかりとCounterImplとってきて、setCounter(Counter)を呼ぶとIllegalArgumentException。なにかに執り付かれたにちがいない。ひがさんのヒントも見たのですが、やってることはまったく変らない。。。ように見える。
*1:GlobalProxy)global).getS2Container(); BeanDesc pageDesc = new BeanDescImpl(page.getClass(