package ameba.mvc.template.internal;

import httl.Engine;
import httl.Template;
import org.apache.commons.lang3.StringUtils;
import org.glassfish.jersey.server.ContainerException;
import org.glassfish.jersey.server.mvc.Viewable;
import org.glassfish.jersey.server.mvc.spi.AbstractTemplateProcessor;
import org.jvnet.hk2.annotations.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.ServletContext;
import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 淘宝HTTL模板处理器
 *
 * @author: ICode
 * @since: 13-8-6 下午7:57
 */
@Singleton
public class HttlViewProcessor extends AbstractTemplateProcessor<Template> {

    public static final String CONFIG_SUFFIX = "httl";

    private static final Logger logger = LoggerFactory.getLogger(HttlViewProcessor.class);
    private Engine engine;

    static String[] getExtends(Configuration config) {
        Map<String, Object> map = config.getProperties();
        String extension = (String) map.get("template.suffix");

        if (StringUtils.isBlank(extension)) {
            return new String[]{".html"};
        }
        return extension.split(",");
    }

    /**
     * Creates an instance of {@link org.glassfish.jersey.server.mvc.internal.DefaultTemplateProcessor}.
     *
     * @param configuration {@code non-null} configuration to obtain properties from.
     */
    @Inject
    public HttlViewProcessor(final Configuration config, @Optional final ServletContext servletContext) {
        super(config, servletContext, CONFIG_SUFFIX, getExtends(config));
        Properties properties = new Properties();
        Map<String, Object> map = config.getProperties();

        properties.put("template.suffix", StringUtils.join(getExtends(config)));

        String encoding = (String) map.get("app.encoding");

        if (StringUtils.isNotBlank(encoding)) {
            properties.put("input.encoding", encoding);
            properties.put("output.encoding", encoding);
            properties.put("message.encoding", encoding);
        }

        for (String key : map.keySet()) {
            if (key.startsWith("template.")) {
                String name;
                if (key.equals("template.suffix") || key.equals("template.directory") || key.equals("template.parser")) {
                    name = key;
                } else {
                    name = key.replaceFirst("^template\\.", "");
                }
                properties.put(name, map.get(key));
            }
        }
        this.engine = Engine.getEngine(properties);
    }

    @Override
    protected Template resolve(String templatePath, Reader reader) throws Exception {
        String dir = (String) engine.getProperty("template.directory");
        if (templatePath.startsWith(dir)) {
            templatePath = templatePath.substring(dir.length());
        }
        return engine.getTemplate(templatePath);
    }

    @Override
    public void writeTo(Template template, final Viewable viewable, MediaType mediaType, MultivaluedMap<String, Object> stringObjectMultivaluedMap, OutputStream outputStream) throws IOException {
        try {
            Object model = viewable.getModel();
            if (!(model instanceof Map)) {
                model = new HashMap<String, Object>() {{
                    put("model", viewable.getModel());
                }};
            }
            template.render(model, outputStream);
        } catch (ParseException e) {
            logger.error("Parse template error", e);
            throw new ContainerException("Parse template error", e);
        }
    }
}
@@ -1131,328 +1131,8 @@
 e;%0A%0A
-    static String%5B%5D getExtends(Configuration config) %7B%0A        Map%3CString, Object%3E map = config.getProperties();%0A        String extension = (String) map.get(%22template.suffix%22);%0A%0A        if (StringUtils.isBlank(extension)) %7B%0A            return new String%5B%5D%7B%22.html%22%7D;%0A        %7D%0A        return extension.split(%22,%22);%0A    %7D%0A%0A
     
@@ -2522,32 +2522,352 @@
 erties);%0A    %7D%0A%0A
+    static String%5B%5D getExtends(Configuration config) %7B%0A        Map%3CString, Object%3E map = config.getProperties();%0A        String extension = (String) map.get(%22template.suffix%22);%0A%0A        if (StringUtils.isBlank(extension)) %7B%0A            return new String%5B%5D%7B%22.html%22%7D;%0A        %7D%0A        return extension.split(%22,%22);%0A    %7D%0A%0A
     @Override%0A  
@@ -2860,24 +2860,24 @@
   @Override%0A
-
     protecte
@@ -3335,34 +3335,19 @@
 ct%3E 
-stringObjectMultivaluedMap
+httpHeaders
 , Ou
@@ -3629,16 +3629,16 @@
     %7D%7D;%0A
-
         
@@ -3635,32 +3635,155 @@
 ;%0A            %7D%0A
+            setContentType(mediaType.equals(MediaType.WILDCARD_TYPE) ? MediaType.TEXT_HTML_TYPE : mediaType, httpHeaders);%0A
             temp

修复模板返回编码问题以及修改默认内容类型*/*为text/html