Pageのpublicフィールドをどうにかしたい
またまたClickについて。
Pageのpublicフィールドしかcontrol?(model?)にセットされないのが気持ち悪い。。。
なんとかアクセサを見てくれないかなぁ・・・
ってポイント考えてたら、
この処理が実行されるのが、onRenderの後なので、
その辺で設定しても上書きされちゃうなぁ・・・
って考えてたら・・・
ClickServletの継承に行き着いた。
package sample; import java.lang.reflect.Method; import net.sf.click.Page; import org.apache.velocity.VelocityContext; public class OwnClickServlet extends net.sf.click.ClickServlet { protected VelocityContext createVelocityContext(Page page) { final VelocityContext context = super.createVelocityContext(page); Method[] methods = page.getClass().getMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getReturnType() != Void.TYPE && methods[i].getParameterTypes().length == 0) { String methodName = methods[i].getName(); try { String param = null; if (methodName.startsWith("get")) { param = createParamNameByMethodName(methodName, "get"); } else if (methodName.startsWith("is")) { param = createParamNameByMethodName(methodName, "is"); } Object object = methods[i].invoke(page, null); if(param != null) { context.put(param, object); } } catch (Exception e) { e.printStackTrace(); } } } return context; } private String createParamNameByMethodName(String methodName, String type) { String paramName = methodName.substring(type.length()); String first = paramName.substring(0, 1); paramName = paramName.replace(paramName.charAt(0), first.toLowerCase() .toCharArray()[0]); return paramName; } }
問題点は、public フィールド + getterの場合に、
二度手間なこと。
フィールド名の割り出しロジックがスマートじゃない気がすること、
pathなどのデフォルトで用意してあるプロパティを上書きしてしまう可能性のあること
(これはすでにPageでの変数命名の失敗っぽいけど)
そして何よりも、
そもそもprivateのフィールドは対象にならないんだから、
最後に上書きされることないので、onRenderとかで十分じゃないっすか。。。
Utilかなんかにしちゃえばいいじゃんか・・・
ってまたまた最後に気づくというパターン
追記
Characterの方が適切ですね