Blog

Freemarker で uriFor する

いわゆるひとつの uriFor 的なものを freemarker 用に実装してみるという。

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;

import freemarker.template.TemplateCollectionModel;
import freemarker.template.TemplateHashModelEx;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateModelIterator;

/**
* {@code uriFor("/path/", {"query":"value"})}
*/
public class URIForFunction implements TemplateMethodModelEx {
    private final String encoding = "UTF-8";

    @Override
    public Object exec(final List arguments) throws TemplateModelException {
        String path = arguments.get(0).toString();
        TemplateHashModelEx params = (TemplateHashModelEx)arguments.get(1);

        StringBuilder buf = new StringBuilder();
        buf.append(path).append("?");

        try {
            TemplateCollectionModel entries = params.keys();
            long size = params.size();
            int n = 1;
            TemplateModelIterator iterator = params.keys().iterator();
            while (iterator.hasNext()) {
                TemplateModel key = iterator.next();
                buf.append(URLEncoder.encode(key.toString(), encoding))
                    .append("=")
                    .append(URLEncoder.encode(params.get(key.toString()).toString(), encoding));
                if (n != size) {
                    buf.append("&");
                }
                ++n;
            }
            return buf.toString();
        } catch (UnsupportedEncodingException e) {
            // Normally, this shouldn't happen.
            throw new RuntimeException(e);
        }
    }
}