image

  • フォト Amazonギフト券
    ※この時計の時刻は、閲覧しているパソコンのものであり、必ずしも正確な時間とは限りません

検索

最近のトラックバック

無料ブログはココログ

« xfy の言語リソース切り替え | トップページ | xfy をリモート操作できるか? »

2007-07-01

xfy の xpath 関数のコーディングの工夫案

xfy/xvcd で java ファンクションを1つ追加するための作業が面倒だ。
そこでこんな方法を思いついた。
 my:eval(functionname, arg0, arg1, ...)形式で eval() という関数を1つだけ定義することにする というものだ。
第一引数を関数名とすることにして、eval 関数の call() メソッド中で分岐させるのだ。
これなら、新しい関数を追加するときは、 call() 中での分岐を増やしていくだけで済む。
その分岐も 実際には if ... elseif ... の羅列でなく、hash で管理すれば分岐数増加にも対応しやすくなる。

実際のコード例はこんな感じになる。ここでは
eval('setLocale', lang), eval('getLocale') として、Locale を set/get する関数を作ってみている。

/** example:eval(funcname, p0, p1...) */
public class EvalFunction implements Function {

    private static final Map<String, Function> funcSet = init();

    private static final Map<String, Function> init() {
        final Map<String, Function> map = new HashMap<String, Function>();

        map.put("list", new ListFunction());

        map.put("setLocale", new SetLocaleLanguageFunction());
        map.put("getLocale", new GetLocaleLanguageFunction());

        return map;
    }

    private Function getInstance(final Arguments args) {
        final Value v = args.getArgument(0);
        final String funcName = v.getAsString();
        Function func = funcSet.get(funcName);
        assert func != null;
        return func;
    }

    public Value call(final Arguments args, final Context context)
            throws ValueException {
        final Value val = this.getInstance(args).call(args, context);
        return val;
    }

    /* ============================================ */
    /**
     * 処理できる関数一覧を返す。
     */
    static class ListFunction implements Function {
        public Value call(final Arguments args, final Context context)
                throws ValueException {
            final StringBuilder sb = new StringBuilder();
            for (final Map.Entry<String, Function> e : funcSet.entrySet()) {
                sb.append(e + " ");
            }
            return new StringValue(sb.toString());
        }
    }

    /**
     */
    static class GetLocaleLanguageFunction implements Function {
        public Value call(final Arguments args, final Context context)
                throws ValueException {

            FunctionUtility.checkCount(context, args, 1);

            final Locale locale = Locale.getDefault();
            return new StringValue(locale.getLanguage());
        }
    }

    /**
     */
    static class SetLocaleLanguageFunction implements Function {
        public Value call(final Arguments args, final Context context)
                throws ValueException {
  .. 省略 ...
        }
    }
}

呼び出し側の xvcd はこんな感じ。
        <td>
          Current Locate:
          <xvcd:value-of select="xvcd:user-data('locale')" />
        </td>
        <td>
          <ctrl:trigger>
            <ctrl:label>set Locale:en</ctrl:label>
            <xvcd:action event="ctrl:triggered">
              <instruction:message-box>
                Change locale from
                <xvcd:value-of select="example:eval('setLocale', 'en')" />
              </instruction:message-box>
              <xvcd:set-user-data name="locale"
                value="{example:eval('getLocale')}" />
            </xvcd:action>
          </ctrl:trigger>
        </td>
    ... 省略 ...

Arguments のなかの最初の要素を取り除く方法があれば、既存の方法で書いたFunction の call メソッドをそのまま呼び出すようにもできるのだが。

この関数名自体を argument にしてしまう方法は、xfy/xvcd の instructionを書く場合にも流用できると思う。

« xfy の言語リソース切り替え | トップページ | xfy をリモート操作できるか? »

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/184434/15616324

この記事へのトラックバック一覧です: xfy の xpath 関数のコーディングの工夫案:

« xfy の言語リソース切り替え | トップページ | xfy をリモート操作できるか? »

mokuji

2013年12月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

google

  • twitter
  • __
  • _
    Googleボットチェッカー

合わせて読む

  • 合わせて読む
    フィードメーター - katoy: cocolog あわせて読みたい

リンク