Package org.expressme.webwind.template

Source Code of org.expressme.webwind.template.VelocityTemplateFactory

package org.expressme.webwind.template;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.RuntimeInstance;
import org.expressme.webwind.Config;

/**
* Template factory using Velocity.
*
* @author Michael Liao (askxuefeng@gmail.com)
*/
public class VelocityTemplateFactory extends TemplateFactory {

    private final Log log = LogFactory.getLog(getClass());

    // velocity runtime instance as singleton:
    private RuntimeInstance rtInstance;

    private String inputEncoding = "UTF-8";
    private String outputEncoding = "UTF-8";

    /**
     * Get input encoding of template. Default to UTF-8, can be specified by
     * 'input.encoding' in velocity.properties.
     */
    public String getInputEncoding() {
        return inputEncoding;
    }

    /**
     * Get output encoding of template. Default to UTF-8, can be specified by
     * 'output.encoding' in velocity.properties.
     */
    public String getOutputEncoding() {
        return outputEncoding;
    }

    public Template loadTemplate(String path) throws Exception {
        if (log.isDebugEnabled())
            log.debug("Load Velocity template '" + path + "'.");
        return new VelocityTemplate(
                rtInstance.getTemplate(path, inputEncoding),
                null,
                outputEncoding
        );
    }

    public void init(Config config) {
        String webAppPath = config.getServletContext().getRealPath("/");
        if (webAppPath==null) {
            String err = "Cannot get web application path. Are you deploy the application as a .war file?";
            log.warn(err);
            throw new ExceptionInInitializerError(err);
        }
        if (!webAppPath.endsWith("/") && !webAppPath.endsWith("\\"))
            webAppPath = webAppPath + File.separator;
        log.info("Detect web application path: " + webAppPath);
        log.info("init VelocityTemplateFactory...");
        rtInstance = new RuntimeInstance();
        // read property file:
        Properties props = readProperties(webAppPath + "/WEB-INF/velocity.properties");
        checkProperty(props);
        Set<?> keys = props.keySet();
        for(Object key : keys) {
            if(key instanceof String) {
                Object value = props.get(key);
                rtInstance.addProperty((String)key, value);
            }
        }
        try {
            if(rtInstance.getProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH)==null) {
                rtInstance.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, webAppPath);
                log.info("Using web application context path as velocity template root path: " + webAppPath);
            }
            else {
                log.info("Velocity property \"" + RuntimeConstants.FILE_RESOURCE_LOADER_PATH + "\" has been specified in \"/WEB-INF/velocity.properties\".");
                log.info("To using web application context path, remove property \"" + RuntimeConstants.FILE_RESOURCE_LOADER_PATH + "\" from configuration file.");
            }
            rtInstance.init();
            afterVelocityEngineInit(rtInstance);
        }
        catch(Exception e) {
            log.error("VelocityTemplateFactory init failed.", e);
            throw new ExceptionInInitializerError(e);
        }
    }

    void checkProperty(Properties props) {
        this.inputEncoding = setDefaultPropertyIfNotExist(props, "input.encoding", "UTF-8");
        this.outputEncoding = setDefaultPropertyIfNotExist(props, "output.encoding", "UTF-8");
    }

    String setDefaultPropertyIfNotExist(Properties props, String key, String defaultValue) {
        String value = props.getProperty(key);
        if (value==null || value.length()==0) {
            props.setProperty(key, defaultValue);
        }
        return props.getProperty(key);
    }

    protected void afterVelocityEngineInit(RuntimeInstance instance) {
        // let subclass do some work
    }

    /**
     * Read velocity properties from file.
     *
     * @param file Velocity configuration file.
     * @return Velocity Properties.
     */
    protected Properties readProperties(String file) {
        Properties props = new Properties();
        InputStream input = null;
        try {
            input = new BufferedInputStream(new FileInputStream(file));
            props.load(input);
        }
        catch(IOException ioe) {
            log.warn("Read properties file failed.", ioe);
        }
        finally {
            if(input!=null) {
                try {
                    input.close();
                }
                catch(IOException e) {}
            }
        }
        return props;
    }
}
TOP

Related Classes of org.expressme.webwind.template.VelocityTemplateFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.