FileDocCategorySizeDatePackage
FreemarkerManager.javaAPI DocExample14686Mon Jul 23 13:26:42 BST 2007org.apache.struts2.views.freemarker

FreemarkerManager

public class FreemarkerManager extends Object
Static Configuration Manager for the FreemarkerResult's configuration

Possible extension points are :-

  • createConfiguration method
  • loadSettings method
  • getTemplateLoader method
  • populateContext method

createConfiguration method
Create a freemarker Configuration.

loadSettings method
Load freemarker settings, default to freemarker.properties (if found in classpath)

getTemplateLoader method
create a freemarker TemplateLoader that loads freemarker template in the following order :-

  1. path defined in ServletContext init parameter named 'templatePath' or 'TemplatePath' (must be an absolute path)
  2. webapp classpath
  3. struts's static folder (under [STRUT2_SOURCE]/org/apache/struts2/static/

populateContext method
populate the created model.

Fields Summary
private static final Log
log
public static final String
CONFIG_SERVLET_CONTEXT_KEY
public static final String
KEY_EXCEPTION
private static final String
ATTR_APPLICATION_MODEL
private static final String
ATTR_JSP_TAGLIBS_MODEL
private static final String
ATTR_REQUEST_MODEL
private static final String
ATTR_REQUEST_PARAMETERS_MODEL
public static final String
KEY_APPLICATION
public static final String
KEY_REQUEST_MODEL
public static final String
KEY_SESSION_MODEL
public static final String
KEY_JSP_TAGLIBS
public static final String
KEY_REQUEST_PARAMETER_MODEL
private String
encoding
private boolean
altMapWrapper
private Map
tagLibraries
Constructors Summary
Methods Summary
protected ScopesHashModelbuildScopesHashModel(javax.servlet.ServletContext servletContext, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, freemarker.template.ObjectWrapper wrapper, com.opensymphony.xwork2.util.ValueStack stack)

        ScopesHashModel model = new ScopesHashModel(wrapper, servletContext, request, stack);

        // Create hash model wrapper for servlet context (the application)
        // only need one thread to do this once, per servlet context
        synchronized (servletContext) {
            ServletContextHashModel servletContextModel = (ServletContextHashModel) servletContext.getAttribute(ATTR_APPLICATION_MODEL);

            if (servletContextModel == null) {

                GenericServlet servlet = JspSupportServlet.jspSupportServlet;
                // TODO if the jsp support  servlet isn't load-on-startup then it won't exist
                // if it hasn't been accessed, and a JSP page is accessed
                if (servlet != null) {
                    servletContextModel = new ServletContextHashModel(servlet, wrapper);
                    servletContext.setAttribute(ATTR_APPLICATION_MODEL, servletContextModel);
                    TaglibFactory taglibs = new TaglibFactory(servletContext);
                    servletContext.setAttribute(ATTR_JSP_TAGLIBS_MODEL, taglibs);
                }

            }

            model.put(KEY_APPLICATION, servletContextModel);
            model.put(KEY_JSP_TAGLIBS, (TemplateModel) servletContext.getAttribute(ATTR_JSP_TAGLIBS_MODEL));
        }

        // Create hash model wrapper for session
        HttpSession session = request.getSession(false);
        if (session != null) {
            model.put(KEY_SESSION_MODEL, new HttpSessionHashModel(session, wrapper));
        } else {
            // no session means no attributes ???
            //            model.put(KEY_SESSION_MODEL, new SimpleHash());
        }

        // Create hash model wrapper for the request attributes
        HttpRequestHashModel requestModel = (HttpRequestHashModel) request.getAttribute(ATTR_REQUEST_MODEL);

        if ((requestModel == null) || (requestModel.getRequest() != request)) {
            requestModel = new HttpRequestHashModel(request, response, wrapper);
            request.setAttribute(ATTR_REQUEST_MODEL, requestModel);
        }

        model.put(KEY_REQUEST_MODEL, requestModel);


        // Create hash model wrapper for request parameters
        HttpRequestParametersHashModel reqParametersModel = (HttpRequestParametersHashModel) request.getAttribute(ATTR_REQUEST_PARAMETERS_MODEL);
        if (reqParametersModel == null || requestModel.getRequest() != request) {
            reqParametersModel = new HttpRequestParametersHashModel(request);
            request.setAttribute(ATTR_REQUEST_PARAMETERS_MODEL, reqParametersModel);
        }
        model.put(KEY_REQUEST_PARAMETER_MODEL, reqParametersModel);

        return model;
    
public freemarker.template.SimpleHashbuildTemplateModel(com.opensymphony.xwork2.util.ValueStack stack, java.lang.Object action, javax.servlet.ServletContext servletContext, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, freemarker.template.ObjectWrapper wrapper)

        ScopesHashModel model = buildScopesHashModel(servletContext, request, response, wrapper, stack);
        populateContext(model, stack, action, request, response);
        for (String prefix : tagLibraries.keySet()) {
            model.put(prefix, tagLibraries.get(prefix).getFreemarkerModels(stack, request, response));
        }
        return model;
    
protected freemarker.template.ConfigurationcreateConfiguration(javax.servlet.ServletContext servletContext)
Create the instance of the freemarker Configuration object.

this implementation

  • obtains the default configuration from Configuration.getDefaultConfiguration()
  • sets up template loading from a ClassTemplateLoader and a WebappTemplateLoader
  • sets up the object wrapper to be the BeansWrapper
  • loads settings from the classpath file /freemarker.properties

param
servletContext

        freemarker.template.Configuration configuration = new freemarker.template.Configuration();

        configuration.setTemplateLoader(getTemplateLoader(servletContext));

        configuration.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);

        configuration.setObjectWrapper(getObjectWrapper());

        if (encoding != null) {
            configuration.setDefaultEncoding(encoding);
        }

        loadSettings(servletContext, configuration);

        return configuration;
    
public final synchronized freemarker.template.ConfigurationgetConfiguration(javax.servlet.ServletContext servletContext)

        freemarker.template.Configuration config = (freemarker.template.Configuration) servletContext.getAttribute(CONFIG_SERVLET_CONTEXT_KEY);

        if (config == null) {
            config = createConfiguration(servletContext);

            // store this configuration in the servlet context
            servletContext.setAttribute(CONFIG_SERVLET_CONTEXT_KEY, config);
        }
        
        config.setWhitespaceStripping(true);

        return config;
    
protected freemarker.ext.beans.BeansWrappergetObjectWrapper()

        return new StrutsBeanWrapper(altMapWrapper);
    
protected freemarker.cache.TemplateLoadergetTemplateLoader(javax.servlet.ServletContext servletContext)
The default template loader is a MultiTemplateLoader which includes a ClassTemplateLoader and a WebappTemplateLoader (and a FileTemplateLoader depending on the init-parameter 'TemplatePath').

The ClassTemplateLoader will resolve fully qualified template includes that begin with a slash. for example /com/company/template/common.ftl

The WebappTemplateLoader attempts to resolve templates relative to the web root folder

        // construct a FileTemplateLoader for the init-param 'TemplatePath'
        FileTemplateLoader templatePathLoader = null;

        String templatePath = servletContext.getInitParameter("TemplatePath");
        if (templatePath == null) {
            templatePath = servletContext.getInitParameter("templatePath");
        }

        if (templatePath != null) {
            try {
                templatePathLoader = new FileTemplateLoader(new File(templatePath));
            } catch (IOException e) {
                log.error("Invalid template path specified: " + e.getMessage(), e);
            }
        }

        // presume that most apps will require the class and webapp template loader
        // if people wish to
        return templatePathLoader != null ?
                new MultiTemplateLoader(new TemplateLoader[]{
                        templatePathLoader,
                        new WebappTemplateLoader(servletContext),
                        new StrutsClassTemplateLoader()
                })
                : new MultiTemplateLoader(new TemplateLoader[]{
                new WebappTemplateLoader(servletContext),
                new StrutsClassTemplateLoader()
        });
    
protected voidloadSettings(javax.servlet.ServletContext servletContext, freemarker.template.Configuration configuration)
Load the settings from the /freemarker.properties file on the classpath

see
freemarker.template.Configuration#setSettings for the definition of valid settings

        try {
            InputStream in = FileManager.loadFile("freemarker.properties", FreemarkerManager.class);

            if (in != null) {
                Properties p = new Properties();
                p.load(in);
                configuration.setSettings(p);
            }
        } catch (IOException e) {
            log.error("Error while loading freemarker settings from /freemarker.properties", e);
        } catch (TemplateException e) {
            log.error("Error while loading freemarker settings from /freemarker.properties", e);
        }
    
protected voidpopulateContext(ScopesHashModel model, com.opensymphony.xwork2.util.ValueStack stack, java.lang.Object action, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)

        // put the same objects into the context that the velocity result uses
        Map standard = ContextUtil.getStandardContext(stack, request, response);
        model.putAll(standard);

        // support for JSP exception pages, exposing the servlet or JSP exception
        Throwable exception = (Throwable) request.getAttribute("javax.servlet.error.exception");

        if (exception == null) {
            exception = (Throwable) request.getAttribute("javax.servlet.error.JspException");
        }

        if (exception != null) {
            model.put(KEY_EXCEPTION, exception);
        }
    
public voidsetContainer(com.opensymphony.xwork2.inject.Container container)

        Map<String,TagLibrary> map = new HashMap<String,TagLibrary>();
        Set<String> prefixes = container.getInstanceNames(TagLibrary.class);
        for (String prefix : prefixes) {
            map.put(prefix, container.getInstance(TagLibrary.class, prefix));
        }
        this.tagLibraries = Collections.unmodifiableMap(map);
    
public voidsetEncoding(java.lang.String encoding)

    
    
        
        this.encoding = encoding;
    
public voidsetWrapperAltMap(java.lang.String val)

        altMapWrapper = "true".equals(val);