VIVO-96 Recognize language support within editing framework.

Instead of adding the same kluge in another location (and passing the necessary info through six layers of framework), modify the FreemarkerConfiguration to directly hold request info. Storing it in a ThreadLocal means that each thread sees its own request info, without confusion. There is still only one instance of FreemarkerConfiguration, so the template cache is shared as before.
This commit is contained in:
j2blake 2013-08-05 16:15:37 -04:00
parent 36a7b57fad
commit 9a0ec5a76e
7 changed files with 61 additions and 35 deletions

View file

@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -319,4 +320,54 @@ public class FreemarkerConfiguration extends Configuration {
} }
} }
// ----------------------------------------------------------------------
// Request info and overrides
// ----------------------------------------------------------------------
private ThreadLocal<FreemarkerRequestInfo> reqInfo = new ThreadLocal<>();
void setRequestInfo(HttpServletRequest req) {
reqInfo.set(new FreemarkerRequestInfo(req));
}
@Override
public Object getCustomAttribute(String name) {
if ("request".equals(name)) {
return reqInfo.get().getRequest();
} else {
return super.getCustomAttribute(name);
}
}
@Override
public String[] getCustomAttributeNames() {
String[] nameArray = super.getCustomAttributeNames();
Set<String> nameSet = new HashSet<String>(Arrays.asList(nameArray));
nameSet.add("request");
return nameSet.toArray(new String[nameSet.size()]);
}
@Override
public Locale getLocale() {
return reqInfo.get().getLocale();
}
public static class FreemarkerRequestInfo {
private final HttpServletRequest req;
public FreemarkerRequestInfo(HttpServletRequest req) {
this.req = req;
}
public HttpServletRequest getRequest() {
return req;
}
public Locale getLocale() {
return req.getLocale();
}
}
} }

View file

@ -21,7 +21,9 @@ public class FreemarkerConfigurationLoader {
public static FreemarkerConfiguration getConfig(VitroRequest vreq) { public static FreemarkerConfiguration getConfig(VitroRequest vreq) {
String themeDir = getThemeDir(vreq.getAppBean()); String themeDir = getThemeDir(vreq.getAppBean());
return getConfigForTheme(themeDir, vreq.getAppBean(), vreq.getSession().getServletContext()); FreemarkerConfiguration config = getConfigForTheme(themeDir, vreq.getAppBean(), vreq.getSession().getServletContext());
config.setRequestInfo(vreq);
return config;
} }
private static String getThemeDir(ApplicationBean appBean) { private static String getThemeDir(ApplicationBean appBean) {

View file

@ -46,14 +46,6 @@ public class TemplateProcessingHelper {
try { try {
Environment env = template.createProcessingEnvironment(map, writer); Environment env = template.createProcessingEnvironment(map, writer);
// Add request and servlet context as custom attributes of the environment, so they
// can be used in directives.
env.setCustomAttribute("request", request);
env.setCustomAttribute("context", context);
// Set the Locale from the request into the environment, so date builtins will be
// Locale-dependent
env.setLocale(request.getLocale());
// Define a setup template to be included by every page template // Define a setup template to be included by every page template
String templateType = (String) map.get("templateType"); String templateType = (String) map.get("templateType");

View file

@ -30,8 +30,6 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfiguration; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfiguration;
import edu.cornell.mannlib.vitro.webapp.web.directives.EmailDirective; import edu.cornell.mannlib.vitro.webapp.web.directives.EmailDirective;
import freemarker.core.Environment;
import freemarker.template.Template;
import freemarker.template.TemplateException; import freemarker.template.TemplateException;
/** /**
@ -144,14 +142,8 @@ public class FreemarkerEmailMessage {
bodyMap.put("email", new EmailDirective(this)); bodyMap.put("email", new EmailDirective(this));
try { try {
Template template = config.getTemplate(templateName); config.getTemplate(templateName).process(bodyMap,
Environment env = template.createProcessingEnvironment(bodyMap,
new StringWriter()); new StringWriter());
env.setCustomAttribute("request", vreq);
env.setCustomAttribute("context", vreq.getSession()
.getServletContext());
env.process();
} catch (TemplateException e) { } catch (TemplateException e) {
log.error(e, e); log.error(e, e);
} catch (IOException e) { } catch (IOException e) {

View file

@ -84,8 +84,6 @@ public class FreemarkerProcessingServiceImpl implements
// can be used in directives. // can be used in directives.
Environment env = template.createProcessingEnvironment(map, writer); Environment env = template.createProcessingEnvironment(map, writer);
env.setCustomAttribute("request", req); env.setCustomAttribute("request", req);
env.setCustomAttribute("context", req.getSession()
.getServletContext());
env.process(); env.process();
return writer.toString(); return writer.toString();
} catch (TemplateException e) { } catch (TemplateException e) {

View file

@ -77,10 +77,10 @@ public class IndividualShortViewDirective extends BaseTemplateDirectiveModel {
private void renderShortView(Individual individual, private void renderShortView(Individual individual,
ShortViewContext svContext) { ShortViewContext svContext) {
Environment env = Environment.getCurrentEnvironment(); Environment env = Environment.getCurrentEnvironment();
HttpServletRequest request = (HttpServletRequest) env
.getCustomAttribute("request");
ServletContext ctx = request.getSession().getServletContext();
ServletContext ctx = (ServletContext) env.getCustomAttribute("context");
VitroRequest vreq = new VitroRequest(
(HttpServletRequest) env.getCustomAttribute("request"));
ShortViewService svs = ShortViewServiceSetup.getService(ctx); ShortViewService svs = ShortViewServiceSetup.getService(ctx);
if (svs == null) { if (svs == null) {
log.warn("ShortViewService was not initialized properly."); log.warn("ShortViewService was not initialized properly.");
@ -88,7 +88,7 @@ public class IndividualShortViewDirective extends BaseTemplateDirectiveModel {
} }
TemplateAndSupplementalData svInfo = svs.getShortViewInfo(individual, TemplateAndSupplementalData svInfo = svs.getShortViewInfo(individual,
svContext, vreq); svContext, new VitroRequest(request));
ObjectWrapper objectWrapper = env.getConfiguration().getObjectWrapper(); ObjectWrapper objectWrapper = env.getConfiguration().getObjectWrapper();

View file

@ -10,7 +10,6 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -57,7 +56,7 @@ public abstract class Widget {
public String doMarkup(Environment env, Map params) { public String doMarkup(Environment env, Map params) {
HttpServletRequest request = (HttpServletRequest) env.getCustomAttribute("request"); HttpServletRequest request = (HttpServletRequest) env.getCustomAttribute("request");
ServletContext context = (ServletContext) env.getCustomAttribute("context"); ServletContext context = request.getSession().getServletContext();
WidgetTemplateValues values = null; WidgetTemplateValues values = null;
@ -120,15 +119,7 @@ public abstract class Widget {
// We need to give each widget macro template a unique key in the StringTemplateLoader, and check // We need to give each widget macro template a unique key in the StringTemplateLoader, and check
// if it's already there or else add it. Leave this for later. // if it's already there or else add it. Leave this for later.
Template template = new Template("widget", new StringReader(templateString), env.getConfiguration()); Template template = new Template("widget", new StringReader(templateString), env.getConfiguration());
template.process(map, out);
// JB KLUGE The widget is processed in its own environment, which doesn't include these custom attributes.
// JB KLUGE Put them in.
Environment widgetEnv = template.createProcessingEnvironment(map, out);
ServletRequest request = (ServletRequest) env.getCustomAttribute("request");
widgetEnv.setCustomAttribute("request", request);
widgetEnv.setCustomAttribute("context", env.getCustomAttribute("context"));
widgetEnv.setLocale(request.getLocale());
widgetEnv.process();
} catch (Exception e) { } catch (Exception e) {
log.error("Could not process widget " + widgetName, e); log.error("Could not process widget " + widgetName, e);
} }