NIHVIVO-658 Reintegrate changes from dev-freemarker-new. Most necessary updates to freemarker controllers for thread-safety are complete. A couple of details remain.

This commit is contained in:
rjy7 2010-06-24 21:51:46 +00:00
parent 7bf1bffd21
commit fb0377134b
18 changed files with 370 additions and 357 deletions

View file

@ -6,6 +6,7 @@ import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@ -22,27 +23,29 @@ import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vedit.beans.LoginFormBean; import edu.cornell.mannlib.vedit.beans.LoginFormBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreeMarkerHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreeMarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.dao.jena.DependentResourceDeleteJena; import edu.cornell.mannlib.vitro.webapp.dao.jena.DependentResourceDeleteJena;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditN3Utils; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.EditN3Utils;
import freemarker.template.Configuration;
public class PrimitiveRdfEdit extends FreeMarkerHttpServlet{ public class PrimitiveRdfEdit extends FreeMarkerHttpServlet{
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Override @Override
protected String getBody() { protected String getBody(VitroRequest vreq, Map<String, Object> body, Configuration config) {
// boolean loggedIn = checkLoginStatus(request, response); // boolean loggedIn = checkLoginStatus(request, response);
// if( !loggedIn){ // if( !loggedIn){
// doError(response,"You must be logged in to use this servlet.",HttpStatus.SC_UNAUTHORIZED); // doError(response,"You must be logged in to use this servlet.",HttpStatus.SC_UNAUTHORIZED);
// return; // return;
// } // }
return mergeBodyToTemplate("primitiveRdfEdit.ftl",new HashMap()); return mergeBodyToTemplate("primitiveRdfEdit.ftl",new HashMap<String, Object>(), config);
} }
@Override @Override
protected String getTitle() { protected String getTitle(String siteName) {
return "RDF edit"; return "RDF edit";
} }
@ -50,6 +53,7 @@ public class PrimitiveRdfEdit extends FreeMarkerHttpServlet{
public void doPost(HttpServletRequest request, public void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException { HttpServletResponse response) throws ServletException, IOException {
VitroRequest vreq = new VitroRequest(request);
boolean loggedIn = checkLoginStatus(request, response); boolean loggedIn = checkLoginStatus(request, response);
if( !loggedIn){ if( !loggedIn){
doError(response,"You must be logged in to use this servlet.",HttpStatus.SC_UNAUTHORIZED); doError(response,"You must be logged in to use this servlet.",HttpStatus.SC_UNAUTHORIZED);
@ -113,7 +117,7 @@ public class PrimitiveRdfEdit extends FreeMarkerHttpServlet{
//if not okay, send error message //if not okay, send error message
doError(response,"Insufficent permissions.",HttpStatus.SC_UNAUTHORIZED); doError(response,"Insufficent permissions.",HttpStatus.SC_UNAUTHORIZED);
} }
if( hasPermission ){ if( hasPermission ){
String editorUri = EditN3Utils.getEditorUri(vreq,request.getSession(false),getServletContext()); String editorUri = EditN3Utils.getEditorUri(vreq,request.getSession(false),getServletContext());
try { try {

View file

@ -2,30 +2,33 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker; package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import freemarker.template.Configuration;
public class AboutController extends FreeMarkerHttpServlet { public class AboutController extends FreeMarkerHttpServlet {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(AboutController.class.getName()); private static final Log log = LogFactory.getLog(AboutController.class.getName());
protected String getTitle() { protected String getTitle(String siteName) {
return "About " + appName; return "About " + siteName;
} }
protected String getBody() { protected String getBody(VitroRequest vreq, Map<String, Object> body, Configuration config) {
Map<String, Object> body = new HashMap<String, Object>(); Portal portal = vreq.getPortal();
body.put("aboutText", portal.getAboutText()); body.put("aboutText", portal.getAboutText());
body.put("acknowledgeText", portal.getAcknowledgeText()); body.put("acknowledgeText", portal.getAcknowledgeText());
String bodyTemplate = "about.ftl"; String bodyTemplate = "about.ftl";
return mergeBodyToTemplate(bodyTemplate, body); return mergeBodyToTemplate(bodyTemplate, body, config);
} }

View file

@ -10,6 +10,7 @@ import com.hp.hpl.jena.vocabulary.RDF;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.beans.Portal; import edu.cornell.mannlib.vitro.webapp.beans.Portal;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
@ -18,6 +19,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilterUtils;
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters;
import edu.cornell.mannlib.vitro.webapp.flags.PortalFlag; import edu.cornell.mannlib.vitro.webapp.flags.PortalFlag;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel;
import freemarker.template.Configuration;
import freemarker.template.SimpleSequence; import freemarker.template.SimpleSequence;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -62,13 +64,12 @@ public class BrowseController extends FreeMarkerHttpServlet {
_cacheRebuildThread.informOfQueueChange(); _cacheRebuildThread.informOfQueueChange();
} }
protected String getTitle() { protected String getTitle(String siteName) {
return "Index to " + portal.getAppName() + " Contents"; return "Index to " + siteName + " Contents";
} }
protected String getBody() { protected String getBody(VitroRequest vreq, Map<String, Object> body, Configuration config) {
Map<String, Object> body = new HashMap<String, Object>();
String bodyTemplate = "classGroups.ftl"; String bodyTemplate = "classGroups.ftl";
String message = null; String message = null;
@ -77,6 +78,7 @@ public class BrowseController extends FreeMarkerHttpServlet {
//PortalFlag portalState= vreq.getPortalFlag(); //PortalFlag portalState= vreq.getPortalFlag();
int portalId = vreq.getPortal().getPortalId();
List<VClassGroup> groups = getGroups(vreq.getWebappDaoFactory().getVClassGroupDao(), portalId); List<VClassGroup> groups = getGroups(vreq.getWebappDaoFactory().getVClassGroupDao(), portalId);
if (groups == null || groups.isEmpty()) { if (groups == null || groups.isEmpty()) {
message = "There are not yet any items in the system."; message = "There are not yet any items in the system.";
@ -96,7 +98,7 @@ public class BrowseController extends FreeMarkerHttpServlet {
body.put("message", message); body.put("message", message);
} }
return mergeBodyToTemplate(bodyTemplate, body); return mergeBodyToTemplate(bodyTemplate, body, config);
} }
public void destroy(){ public void destroy(){

View file

@ -20,6 +20,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils; import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
import freemarker.template.Configuration;
/** /**
* Controller for comments ("contact us") page * Controller for comments ("contact us") page
@ -30,14 +31,14 @@ public class ContactFormController extends FreeMarkerHttpServlet {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(ContactFormController.class.getName()); private static final Log log = LogFactory.getLog(ContactFormController.class.getName());
protected String getTitle() { protected String getTitle(String siteName) {
return appName + " Feedback Form"; return siteName + " Feedback Form";
} }
protected String getBody() { protected String getBody(VitroRequest vreq, Map<String, Object> body, Configuration config) {
Map<String, Object> body = new HashMap<String, Object>();
String bodyTemplate; String bodyTemplate;
Portal portal = vreq.getPortal();
if (!ContactMailServlet.isSmtpHostConfigured()) { if (!ContactMailServlet.isSmtpHostConfigured()) {
body.put("errorMessage", body.put("errorMessage",
@ -54,9 +55,11 @@ public class ContactFormController extends FreeMarkerHttpServlet {
else { else {
ApplicationBean appBean = vreq.getAppBean(); ApplicationBean appBean = vreq.getAppBean();
String portalType = null; String portalType = null;
int portalId = portal.getPortalId();
String appName = portal.getAppName();
if ( (appBean.getMaxSharedPortalId()-appBean.getMinSharedPortalId()) > 1 if ( (appBean.getMaxSharedPortalId()-appBean.getMinSharedPortalId()) > 1
&& ( (portalId >= appBean.getMinSharedPortalId() && ( (portalId >= appBean.getMinSharedPortalId()
&& portalId <= appBean.getMaxSharedPortalId() ) && portalId <= appBean.getMaxSharedPortalId() )
@ -83,6 +86,6 @@ public class ContactFormController extends FreeMarkerHttpServlet {
bodyTemplate = "contactForm/form.ftl"; bodyTemplate = "contactForm/form.ftl";
} }
return mergeBodyToTemplate(bodyTemplate, body); return mergeBodyToTemplate(bodyTemplate, body, config);
} }
} }

View file

@ -26,6 +26,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import freemarker.template.Configuration;
public class ContactMailController extends FreeMarkerHttpServlet { public class ContactMailController extends FreeMarkerHttpServlet {
private static final Log log = LogFactory private static final Log log = LogFactory
@ -63,13 +66,13 @@ public class ContactMailController extends FreeMarkerHttpServlet {
return (host != null && host.length() > 0) ? host : null; return (host != null && host.length() > 0) ? host : null;
} }
protected String getTitle() { protected String getTitle(String siteName) {
return appName + " Feedback Form"; return siteName + " Feedback Form";
} }
protected String getBody() { protected String getBody(VitroRequest vreq, Map<String, Object> body, Configuration config) {
Map<String, Object> body = new HashMap<String, Object>(); Portal portal = vreq.getPortal();
String bodyTemplate = null; String bodyTemplate = null;
String statusMsg = null; // holds the error status String statusMsg = null; // holds the error status
@ -157,13 +160,13 @@ public class ContactMailController extends FreeMarkerHttpServlet {
} }
String msgText = composeEmail(webusername, webuseremail, comments, String msgText = composeEmail(webusername, webuseremail, comments,
deliveryfrom, originalReferer, vreq.getRemoteAddr()); deliveryfrom, originalReferer, vreq.getRemoteAddr(), config);
// Write the email to a backup file // Write the email to a backup file
try { try {
FileWriter fw = new FileWriter(context.getRealPath(EMAIL_BACKUP_FILE_PATH),true); FileWriter fw = new FileWriter(getServletContext().getRealPath(EMAIL_BACKUP_FILE_PATH),true);
PrintWriter outFile = new PrintWriter(fw); PrintWriter outFile = new PrintWriter(fw);
writeBackupCopy(outFile, msgText, spamReason); writeBackupCopy(outFile, msgText, spamReason, config);
// Set the smtp host // Set the smtp host
Properties props = System.getProperties(); Properties props = System.getProperties();
@ -209,7 +212,7 @@ public class ContactMailController extends FreeMarkerHttpServlet {
} }
} }
return mergeBodyToTemplate(bodyTemplate, body); return mergeBodyToTemplate(bodyTemplate, body, config);
} }
@ -224,7 +227,7 @@ public class ContactMailController extends FreeMarkerHttpServlet {
private String composeEmail(String webusername, String webuseremail, private String composeEmail(String webusername, String webuseremail,
String comments, String deliveryfrom, String comments, String deliveryfrom,
String originalReferer, String ipAddr) { String originalReferer, String ipAddr, Configuration config) {
Map<String, Object> email = new HashMap<String, Object>(); Map<String, Object> email = new HashMap<String, Object>();
String template = "contactForm/email.ftl"; String template = "contactForm/email.ftl";
@ -238,11 +241,11 @@ public class ContactMailController extends FreeMarkerHttpServlet {
email.put("referrer", UrlBuilder.urlDecode(originalReferer)); email.put("referrer", UrlBuilder.urlDecode(originalReferer));
} }
return mergeBodyToTemplate(template, email); return mergeBodyToTemplate(template, email, config);
} }
private void writeBackupCopy(PrintWriter outFile, String msgText, private void writeBackupCopy(PrintWriter outFile, String msgText,
String spamReason) { String spamReason, Configuration config) {
Map<String, Object> backup = new HashMap<String, Object>(); Map<String, Object> backup = new HashMap<String, Object>();
String template = "contactForm/backup.ftl"; String template = "contactForm/backup.ftl";
@ -256,7 +259,7 @@ public class ContactMailController extends FreeMarkerHttpServlet {
backup.put("msgText", msgText); backup.put("msgText", msgText);
String backupText = mergeBodyToTemplate(template, backup); String backupText = mergeBodyToTemplate(template, backup, config);
outFile.print(backupText); outFile.print(backupText);
outFile.flush(); outFile.flush();
//outFile.close(); //outFile.close();

View file

@ -2,15 +2,18 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker; package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import freemarker.template.Configuration;
/** /**
* TEMPORARY for transition from JSP to FreeMarker. Once transition * TEMPORARY for transition from JSP to FreeMarker. Once transition
* is complete and no more pages are generated in JSP, this can be removed. * is complete and no more pages are generated in JSP, this can be removed.
@ -23,30 +26,37 @@ public class FreeMarkerComponentGenerator extends FreeMarkerHttpServlet {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(FreeMarkerHttpServlet.class.getName()); private static final Log log = LogFactory.getLog(FreeMarkerHttpServlet.class.getName());
private static ServletContext context = null;
FreeMarkerComponentGenerator(HttpServletRequest request, HttpServletResponse response) { FreeMarkerComponentGenerator(HttpServletRequest request, HttpServletResponse response) {
doSetup(request, response); VitroRequest vreq = new VitroRequest(request);
setUpPage(); Configuration config = getConfig(vreq);
}
// root is the map used to create the page shell - header, footer, menus, etc.
public String getIdentity() { Map<String, Object> root = getSharedVariables(vreq);
return get("identity"); setUpRoot(vreq, root);
request.setAttribute("ftl_identity", get("identity", root, config));
request.setAttribute("ftl_menu", get("menu", root, config));
request.setAttribute("ftl_search", get("search", root, config));
request.setAttribute("ftl_footer", get("footer", root, config));
} }
public String getMenu() { private String get(String templateName, Map<String, Object> root, Configuration config) {
return get("menu");
}
public String getSearch() {
return get("search");
}
public String getFooter() {
return get("footer");
}
private String get(String templateName) {
String template = "page/partials/" + templateName + ".ftl"; String template = "page/partials/" + templateName + ".ftl";
return mergeTemplateToRoot(template); return mergeToTemplate(template, root, config).toString();
} }
// RY We need the servlet context in getConfig(). For some reason using the method inherited from
// GenericServlet bombs.
public ServletContext getServletContext() {
return context;
}
protected static void setServletContext(ServletContext sc) {
context = sc;
}
} }

View file

@ -20,6 +20,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginFormBean; import edu.cornell.mannlib.vedit.beans.LoginFormBean;
import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.beans.Portal; import edu.cornell.mannlib.vitro.webapp.beans.Portal;
import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet; import edu.cornell.mannlib.vitro.webapp.controller.ContactMailServlet;
@ -32,7 +33,6 @@ import edu.cornell.mannlib.vitro.webapp.web.PortalWebUtil;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.filelist.ScriptList; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.filelist.ScriptList;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.filelist.StylesheetList; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.filelist.StylesheetList;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.TabMenu; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.TabMenu;
import freemarker.cache.ClassTemplateLoader; import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader; import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader; import freemarker.cache.MultiTemplateLoader;
@ -51,26 +51,38 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
private static final Log log = LogFactory.getLog(FreeMarkerHttpServlet.class.getName()); private static final Log log = LogFactory.getLog(FreeMarkerHttpServlet.class.getName());
private static final int FILTER_SECURITY_LEVEL = LoginFormBean.EDITOR; private static final int FILTER_SECURITY_LEVEL = LoginFormBean.EDITOR;
protected static Configuration config = null;
protected static ServletContext context = null;
protected VitroRequest vreq;
protected HttpServletResponse response;
protected Portal portal;
protected int portalId;
protected String appName;
protected UrlBuilder urlBuilder;
private Map<String, Object> root = new HashMap<String, Object>();
public void doGet( HttpServletRequest request, HttpServletResponse response ) public void doGet( HttpServletRequest request, HttpServletResponse response )
throws IOException, ServletException { throws IOException, ServletException {
try {
super.doGet(request,response);
} catch (ServletException e) {
log.error("ServletException calling VitroHttpRequest.doGet()");
e.printStackTrace();
} catch (IOException e) {
log.error("IOException calling VitroHttpRequest.doGet()");
e.printStackTrace();
}
try { try {
doSetup(request, response); VitroRequest vreq = new VitroRequest(request);
setUpPage(); Configuration config = getConfig(vreq);
setTitleAndBody();
writePage(); // We can't use shared variables in the FreeMarker configuration to store anything
// except theme-specific data, because multiple portals or apps might share the same theme. So instead
// just put the shared variables in both root and body.
Map<String, Object> sharedVariables = getSharedVariables(vreq); // start by getting the title here
// root is the map used to create the page shell - header, footer, menus, etc.
Map<String, Object> root = new HashMap<String, Object>(sharedVariables);
// body is the map used to create the page body
Map<String, Object> body = new HashMap<String, Object>(sharedVariables);
setUpRoot(vreq, root);
root.put("body", getBody(vreq, body, config)); // need config to get and process template
writePage(root, config, response);
} catch (Throwable e) { } catch (Throwable e) {
log.error("FreeMarkerHttpServlet could not forward to view."); log.error("FreeMarkerHttpServlet could not forward to view.");
@ -78,99 +90,79 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
log.error(e.getStackTrace()); log.error(e.getStackTrace());
} }
} }
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
// Basic setup needed by all FreeMarker controllers public void doPost(HttpServletRequest request, HttpServletResponse response)
protected void doSetup(HttpServletRequest request, HttpServletResponse response) { throws ServletException, IOException {
doGet(request, response);
}
protected Configuration getConfig(VitroRequest vreq) {
if ( !(this instanceof FreeMarkerComponentGenerator) ) { String themeDir = getThemeDir(vreq.getPortal());
try { return getConfigForTheme(themeDir);
super.doGet(request,response); }
} catch (ServletException e) {
log.error("ServletException calling VitroHttpRequest.doGet()"); @SuppressWarnings("unchecked")
e.printStackTrace(); protected Configuration getConfigForTheme(String themeDir) {
} catch (IOException e) {
log.error("IOException calling VitroHttpRequest.doGet()"); Map<String, Configuration> themeToConfigMap = (Map<String, Configuration>) (getServletContext().getAttribute("themeToConfigMap"));
e.printStackTrace();
} if (themeToConfigMap.containsKey(themeDir)) {
return themeToConfigMap.get(themeDir);
} else {
Configuration config = getNewConfig(themeDir);
themeToConfigMap.put(themeDir, config);
return config;
} }
vreq = new VitroRequest(request);
this.response = response;
portal = vreq.getPortal();
setTemplateLoader();
} }
// Setup needed by all controllers that display a full page. private Configuration getNewConfig(String themeDir) {
// Controllers that display parts of a page, respond to an Ajax request, etc., do not use this.
protected void setUpPage() {
urlBuilder = new UrlBuilder(portal); Configuration config = new Configuration();
// RY Can this be removed? Do templates need it? Ideally, they should not. String buildEnv = ConfigurationProperties.getProperty("Environment.build");
// Only needed for some weird stuff in search box that I think is only used in old default theme. if (buildEnv != null && buildEnv.equals("development")) {
// Some forms need it also, in which case it should get set in the getBody() method and passed to that config.setTemplateUpdateDelay(0); // no template caching in development
// body template. }
portalId = portal.getPortalId();
root.put("portalId", portalId);
appName = portal.getAppName();
setSharedVariable("siteName", appName);
TabMenu menu = getTabMenu();
root.put("tabMenu", menu);
ApplicationBean appBean = vreq.getAppBean(); // Specify how templates will see the data-model.
PortalWebUtil.populateSearchOptions(portal, appBean, vreq.getWebappDaoFactory().getPortalDao()); // The default wrapper exposes set methods unless exposure level is set.
PortalWebUtil.populateNavigationChoices(portal, vreq, appBean, vreq.getWebappDaoFactory().getPortalDao()); // By default we want to block exposure of set methods.
// config.setObjectWrapper(new DefaultObjectWrapper());
root.put("tagline", portal.getShortHand());
root.put("breadcrumbs", BreadCrumbsUtil.getBreadCrumbsDiv(vreq));
String themeDir = getThemeDir();
setUrls(themeDir);
setLoginInfo();
setCopyrightInfo();
setThemeInfo(themeDir);
setScriptAndStylesheetObjects(themeDir);
setSharedVariable("dump", new edu.cornell.mannlib.vitro.webapp.web.directives.DumpDirective());
setSharedVariable("dumpDataModel", new edu.cornell.mannlib.vitro.webapp.web.directives.DumpDataModelDirective());
}
private void setScriptAndStylesheetObjects(String themeDir) {
// Use an object wrapper that exposes write methods, instead of the
// configuration's object wrapper, which doesn't, so the templates can
// add stylesheets and scripts to the lists by calling their add() methods.
BeansWrapper wrapper = new DefaultObjectWrapper(); BeansWrapper wrapper = new DefaultObjectWrapper();
wrapper.setExposureLevel(BeansWrapper.EXPOSE_PROPERTIES_ONLY);
config.setObjectWrapper(wrapper);
// Set some formatting defaults. These can be overridden at the template
// or environment (template-processing) level, or for an individual
// instance by using built-ins.
config.setLocale(java.util.Locale.US);
String dateFormat = "M/d/yyyy";
config.setDateFormat(dateFormat);
String timeFormat = "hh:mm a";
config.setTimeFormat(timeFormat);
config.setDateTimeFormat(dateFormat + " " + timeFormat);
//config.setNumberFormat("#,##0.##");
try { try {
// Here themeDir SHOULD NOT have the context path already added to it. config.setSetting("url_escaping_charset", "ISO-8859-1");
TemplateModel stylesheets = wrapper.wrap(new StylesheetList(themeDir)); } catch (TemplateException e) {
setSharedVariable("stylesheets", stylesheets); log.error("Error setting value for url_escaping_charset.");
TemplateModel scripts = wrapper.wrap(new ScriptList());
setSharedVariable("scripts", scripts);
} catch (TemplateModelException e) {
log.error("Error creating stylesheet and script TemplateModels");
} }
config.setTemplateLoader(getTemplateLoader(config, themeDir));
return config;
} }
// Define template locations. Template loader will look first in the theme-specific // Define template locations. Template loader will look first in the theme-specific
// location, then in the vitro location. // location, then in the vitro location.
// RY We cannot do this in FreeMarkerSetup because (a) the theme depends on the portal, protected final TemplateLoader getTemplateLoader(Configuration config, String themeDir) {
// and we have multi-portal installations, and (b) we need to support theme-switching on the fly.
// To make more efficient, we could do this once, and then have a listener that does it again
// when theme is switched. BUT this doesn't support (a), only (b), so we have to do it on every request.
protected final void setTemplateLoader() {
String themeTemplateDir = context.getRealPath(getThemeDir()) + "/templates"; ServletContext context = getServletContext();
String themeTemplateDir = context.getRealPath(themeDir) + "/templates";
String vitroTemplateDir = context.getRealPath("/templates/freemarker"); String vitroTemplateDir = context.getRealPath("/templates/freemarker");
try { try {
@ -179,24 +171,55 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), ""); ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), "");
TemplateLoader[] loaders = new TemplateLoader[] { themeFtl, vitroFtl, ctl }; TemplateLoader[] loaders = new TemplateLoader[] { themeFtl, vitroFtl, ctl };
MultiTemplateLoader mtl = new MultiTemplateLoader(loaders); MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);
config.setTemplateLoader(mtl); return mtl;
} catch (IOException e) { } catch (IOException e) {
log.error("Error loading templates"); log.error("Error loading templates");
return null;
} }
} }
private TabMenu getTabMenu() { // We can't use shared variables in the FreeMarker configuration to store anything
return new TabMenu(vreq, portalId); // except theme-specific data, because multiple portals or apps might share the same theme. So instead
// we'll get all the shared variables here, and put them in both root and body maps.
protected Map<String, Object> getSharedVariables(VitroRequest vreq) {
Map<String, Object> map = new HashMap<String, Object>();
Portal portal = vreq.getPortal();
// Ideally, templates wouldn't need portal id. Currently used as a hidden input value
// in the site search box, so needed for now.
map.put("portalId", portal.getPortalId());
String siteName = portal.getAppName();
map.put("siteName", siteName);
map.put("title", getTitle(siteName));
String themeDir = getThemeDir(portal);
UrlBuilder urlBuilder = new UrlBuilder(portal);
map.put("urls", getUrls(themeDir, urlBuilder));
// This value will be available to any template as a path for adding a new stylesheet.
// It does not contain the context path, because the methods to generate the href
// attribute from the string passed in by the template automatically add the context path.
map.put("stylesheetDir", themeDir + "/css");
map.put("stylesheets", getStylesheetList(themeDir));
map.put("scripts", getScriptList());
addDirectives(map);
return map;
} }
public String getThemeDir() { public String getThemeDir(Portal portal) {
return portal.getThemeDir().replaceAll("/$", ""); return portal.getThemeDir().replaceAll("/$", "");
} }
// Define the URLs that are accessible to the templates. Note that we do not create menus here, // Define the URLs that are accessible to the templates. Note that we do not create menus here,
// because we want the templates to be free to define the link text and where the links are displayed. // because we want the templates to be free to define the link text and where the links are displayed.
private final void setUrls(String themeDir) { private final Map<String, String> getUrls(String themeDir, UrlBuilder urlBuilder) {
// The urls that are accessible to the templates. // The urls that are accessible to the templates.
// NB We are not using our menu object mechanism to build menus here, because we want the // NB We are not using our menu object mechanism to build menus here, because we want the
// view to control which links go where, and the link text and title. // view to control which links go where, and the link text and title.
@ -204,11 +227,6 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
urls.put("home", urlBuilder.getHomeUrl()); urls.put("home", urlBuilder.getHomeUrl());
String bannerImage = portal.getBannerImage();
if ( ! StringUtils.isEmpty(bannerImage)) {
root.put("bannerImage", UrlBuilder.getUrl(themeDir + "site_icons/" + bannerImage));
}
urls.put("about", urlBuilder.getPortalUrl(Route.ABOUT)); urls.put("about", urlBuilder.getPortalUrl(Route.ABOUT));
if (ContactMailServlet.getSmtpHostFromProperties() != null) { if (ContactMailServlet.getSmtpHostFromProperties() != null) {
urls.put("contact", urlBuilder.getPortalUrl(Route.CONTACT)); urls.put("contact", urlBuilder.getPortalUrl(Route.CONTACT));
@ -218,11 +236,86 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
urls.put("login", urlBuilder.getPortalUrl(Route.LOGIN)); urls.put("login", urlBuilder.getPortalUrl(Route.LOGIN));
urls.put("logout", urlBuilder.getLogoutUrl()); urls.put("logout", urlBuilder.getLogoutUrl());
urls.put("siteAdmin", urlBuilder.getPortalUrl(Route.LOGIN)); urls.put("siteAdmin", urlBuilder.getPortalUrl(Route.LOGIN));
urls.put("siteIcons", urlBuilder.getPortalUrl(themeDir + "/site_icons"));
return urls;
}
private TemplateModel getStylesheetList(String themeDir) {
setSharedVariable("urls", urls); // For script and stylesheet lists, use an object wrapper that exposes write methods,
// instead of the configuration's object wrapper, which doesn't. The templates can
// add stylesheets and scripts to the lists by calling their add() methods.
BeansWrapper wrapper = new DefaultObjectWrapper();
try {
// Here themeDir SHOULD NOT have the context path already added to it.
return wrapper.wrap(new StylesheetList(themeDir));
} catch (TemplateModelException e) {
log.error("Error creating stylesheet TemplateModel");
return null;
}
}
private TemplateModel getScriptList() {
// For script and stylesheet lists, use an object wrapper that exposes write methods,
// instead of the configuration's object wrapper, which doesn't. The templates can
// add stylesheets and scripts to the lists by calling their add() methods.
BeansWrapper wrapper = new DefaultObjectWrapper();
try {
return wrapper.wrap(new ScriptList());
} catch (TemplateModelException e) {
log.error("Error creating script TemplateModel");
return null;
}
}
// Add any Java directives the templates should have access to
private void addDirectives(Map<String, Object> map) {
map.put("dump", new edu.cornell.mannlib.vitro.webapp.web.directives.DumpDirective());
map.put("dumpDataModel", new edu.cornell.mannlib.vitro.webapp.web.directives.DumpDataModelDirective());
}
// Add variables that should be available only to the page's root map, not to the body.
// RY This is protected instead of private so FreeMarkerComponentGenerator can access.
// Once we don't need that (i.e., jsps have been eliminated) we can make it private.
protected void setUpRoot(VitroRequest vreq, Map<String, Object> root) {
root.put("tabMenu", getTabMenu(vreq));
Portal portal = vreq.getPortal();
ApplicationBean appBean = vreq.getAppBean();
PortalWebUtil.populateSearchOptions(portal, appBean, vreq.getWebappDaoFactory().getPortalDao());
PortalWebUtil.populateNavigationChoices(portal, vreq, appBean, vreq.getWebappDaoFactory().getPortalDao());
addLoginInfo(vreq, root);
root.put("copyright", getCopyrightInfo(portal));
root.put("siteTagline", portal.getShortHand());
root.put("breadcrumbs", BreadCrumbsUtil.getBreadCrumbsDiv(vreq));
String themeDir = getThemeDir(portal);
// This value is used only in stylesheets.ftl and already contains the context path.
root.put("stylesheetPath", UrlBuilder.getUrl(themeDir + "/css"));
String bannerImage = portal.getBannerImage();
if ( ! StringUtils.isEmpty(bannerImage)) {
root.put("bannerImage", UrlBuilder.getUrl(themeDir + "site_icons/" + bannerImage));
}
}
private TabMenu getTabMenu(VitroRequest vreq) {
// RY There's a vreq.getPortalId() method, but not sure if it returns
// same value as this.
int portalId = vreq.getPortal().getPortalId();
return new TabMenu(vreq, portalId);
} }
private final void setLoginInfo() { private final void addLoginInfo(VitroRequest vreq, Map<String, Object> root) {
String loginName = null; String loginName = null;
int securityLevel; int securityLevel;
@ -246,79 +339,43 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
} }
} }
private final void setCopyrightInfo() { private final Map<String, Object> getCopyrightInfo(Portal portal) {
Map<String, Object> copyright = null;
String copyrightText = portal.getCopyrightAnchor(); String copyrightText = portal.getCopyrightAnchor();
if ( ! StringUtils.isEmpty(copyrightText) ) { if ( ! StringUtils.isEmpty(copyrightText) ) {
Map<String, Object> copyright = new HashMap<String, Object>(); copyright = new HashMap<String, Object>();
copyright.put("text", copyrightText); copyright.put("text", copyrightText);
int thisYear = Calendar.getInstance().get(Calendar.YEAR); // use ${copyrightYear?c} in template int thisYear = Calendar.getInstance().get(Calendar.YEAR); // use ${copyrightYear?c} in template
//String thisYear = ((Integer)Calendar.getInstance().get(Calendar.YEAR)).toString(); // use ${copyrightYear} in template //String thisYear = ((Integer)Calendar.getInstance().get(Calendar.YEAR)).toString(); // use ${copyrightYear} in template
//SimpleDate thisYear = new SimpleDate(Calendar.getInstance().getTime(), TemplateDateModel.DATE); // use ${copyrightYear?string("yyyy")} in template //SimpleDate thisYear = new SimpleDate(Calendar.getInstance().getTime(), TemplateDateModel.DATE); // use ${copyrightYear?string("yyyy")} in template
copyright.put("year", thisYear); copyright.put("year", thisYear);
copyright.put("url", portal.getCopyrightURL()); copyright.put("url", portal.getCopyrightURL());
root.put("copyright", copyright);
} }
return copyright;
} }
private final void setThemeInfo(String themeDir) {
// This value will be available to any template as a path for adding a new stylesheet.
// It does not contain the context path, because the methods to generate the href
// attribute from the string passed in by the template automatically add the context path.
setSharedVariable("stylesheetDir", themeDir + "/css");
String themeDirWithContext = UrlBuilder.getUrl(themeDir);
// This value is used only in stylesheets.ftl and already contains the context path.
root.put("stylesheetPath", themeDirWithContext + "/css");
setSharedVariable("siteIconPath", themeDirWithContext + "/site_icons");
}
// Default case is to set title first, because it's used in the body. However, in some cases // Default case is to set title first, because it's used in the body. However, in some cases
// the title is based on values computed during compilation of the body (e.g., IndividualListController). // the title is based on values computed during compilation of the body (e.g., IndividualListController).
// Individual controllers can override this method to set title and body together. End result must be: // Individual controllers can override this method to set title and body together. End result must be:
// body is added to root with key "body" // body is added to root with key "body"
// title is set as a shared variable with key "title" // title is set as a shared variable with key "title"
// This can be achieved by making sure setBody() and setTitle() are called. // This can be achieved by making sure setBody() and setTitle() are called.
protected void setTitleAndBody() { // protected void setTitleAndBody() {
setTitle(); // setTitle();
setBody(); // setBody();
} // }
protected void setBody() { // Subclasses will override. This serves as a default.
root.put("body", getBody()); protected String getTitle(String siteName) {
} return siteName;
protected String getBody() {
return ""; // body should never be null
} }
protected void setTitle() { protected String getBody(VitroRequest vreq, Map<String, Object> body, Configuration config) {
String title = getTitle(); return "";
// If the individual controller fails to assign a non-null, non-empty title
if (StringUtils.isEmpty(title)) {
title = appName;
}
// Title is a shared variable because it's used in both body and head elements.
setSharedVariable("title", title);
}
protected String getTitle() {
return "";
} }
protected void setSharedVariable(String key, Object value) { protected StringWriter mergeToTemplate(String templateName, Map<String, Object> map, Configuration config) {
try {
config.setSharedVariable(key, value);
} catch (TemplateModelException e) {
log.error("Can't set shared variable '" + key + "'.");
}
}
protected StringWriter mergeToTemplate(String templateName, Map<String, Object> map) {
Template template = null; Template template = null;
try { try {
@ -341,28 +398,28 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
return sw; return sw;
} }
protected String mergeBodyToTemplate(String templateName, Map<String, Object> map) { protected String mergeBodyToTemplate(String templateName, Map<String, Object> map, Configuration config) {
templateName = "body/" + templateName; templateName = "body/" + templateName;
String body = mergeToTemplate(templateName, map).toString(); String body = mergeToTemplate(templateName, map, config).toString();
return body; return body;
} }
protected void writePage() { protected void writePage(Map<String, Object> root, Configuration config, HttpServletResponse response) {
String templateName = "page/" + getPageTemplateName(); String templateName = "page/" + getPageTemplateName();
writeTemplate(templateName, root); writeTemplate(templateName, root, config, response);
} }
protected void ajaxWrite(String templateName, Map<String, Object> map) { protected void ajaxWrite(String templateName, Map<String, Object> map, Configuration config, HttpServletResponse response) {
templateName = "ajax/" + templateName; templateName = "ajax/" + templateName;
writeTemplate(templateName, map); writeTemplate(templateName, map, config, response);
} }
protected void writeTemplate(String templateName, Map<String, Object> map) { protected void writeTemplate(String templateName, Map<String, Object> map, Configuration config, HttpServletResponse response) {
StringWriter sw = mergeToTemplate(templateName, map); StringWriter sw = mergeToTemplate(templateName, map, config);
write(sw); write(sw, response);
} }
protected void write(StringWriter sw) { protected void write(StringWriter sw, HttpServletResponse response) {
try { try {
PrintWriter out = response.getWriter(); PrintWriter out = response.getWriter();
@ -378,27 +435,12 @@ public class FreeMarkerHttpServlet extends VitroHttpServlet {
return "default.ftl"; return "default.ftl";
} }
// TEMPORARY method for transition from JSP to FreeMarker.
public static boolean isConfigured() {
return config != null;
}
// TEMPORARY methods for transition from JSP to FreeMarker. Once transition
// is complete and no more pages are generated in JSP, this can be removed.
// Do this if FreeMarker is configured (i.e., not Datastar) and if we are not in
// a FreeMarkerHttpServlet, which will generate identity, menu, and footer from the page template.
// It's a static method because it needs to be called from JSPs that don't go through a servlet. // It's a static method because it needs to be called from JSPs that don't go through a servlet.
public static void getFreeMarkerComponentsForJsp(HttpServletRequest request, HttpServletResponse response) { public static void getFreeMarkerComponentsForJsp(HttpServletRequest request, HttpServletResponse response) {
FreeMarkerComponentGenerator fcg = new FreeMarkerComponentGenerator(request, response); // We need to create a FreeMarkerHttpServlet object in order to call the instance methods
request.setAttribute("ftl_identity", fcg.getIdentity()); // to set up the data model.
request.setAttribute("ftl_menu", fcg.getMenu()); new FreeMarkerComponentGenerator(request, response);
request.setAttribute("ftl_search", fcg.getSearch());
request.setAttribute("ftl_footer", fcg.getFooter());
}
// This method is called by FreeMarkerComponentGenerator, since root is private.
// Don't want to make root protected because other controllers shouldn't add to it.
protected String mergeTemplateToRoot(String template) {
return mergeToTemplate(template, root).toString();
} }
} }

View file

@ -2,6 +2,8 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker; package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.util.HashMap;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; import javax.servlet.ServletContextListener;
@ -9,12 +11,8 @@ import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration; import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.TemplateException;
public class FreeMarkerSetup implements ServletContextListener { public class FreeMarkerSetup implements ServletContextListener {
@ -23,55 +21,10 @@ public class FreeMarkerSetup implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) { public void contextInitialized(ServletContextEvent event) {
ServletContext sc = event.getServletContext(); ServletContext sc = event.getServletContext();
sc.setAttribute("themeToConfigMap", new HashMap<String, Configuration>());
Configuration cfg = new Configuration();
// Specify the data source where the template files come from.
// RY Now being done for each request, in order to support multi-portal apps
// and dynamic theme-loading.
// try {
// cfg.setDirectoryForTemplateLoading(new File(templatePath));
// } catch (IOException e) {
// log.error("Error specifying template directory.");
// }
String buildEnv = ConfigurationProperties.getProperty("Environment.build");
if (buildEnv != null && buildEnv.equals("development")) {
cfg.setTemplateUpdateDelay(0); // no template caching in development
}
// Specify how templates will see the data-model.
// The default wrapper exposes set methods unless exposure level is set.
// By default we want to block exposure of set methods.
// cfg.setObjectWrapper(new DefaultObjectWrapper());
BeansWrapper wrapper = new DefaultObjectWrapper();
wrapper.setExposureLevel(BeansWrapper.EXPOSE_PROPERTIES_ONLY);
cfg.setObjectWrapper(wrapper);
// Set some formatting defaults. These can be overridden at the template
// or environment (template-processing) level, or for an individual
// instance by using built-ins.
cfg.setLocale(java.util.Locale.US);
String dateFormat = "M/d/yyyy";
cfg.setDateFormat(dateFormat);
String timeFormat = "hh:mm a";
cfg.setTimeFormat(timeFormat);
cfg.setDateTimeFormat(dateFormat + " " + timeFormat);
//cfg.setNumberFormat("#,##0.##");
try {
cfg.setSetting("url_escaping_charset", "ISO-8859-1");
} catch (TemplateException e) {
log.error("Error setting value for url_escaping_charset.");
}
FreeMarkerHttpServlet.config = cfg;
FreeMarkerHttpServlet.context = sc;
BaseTemplateModel.context = sc; BaseTemplateModel.context = sc;
FreeMarkerComponentGenerator.setServletContext(sc);
UrlBuilder.contextPath = sc.getContextPath(); UrlBuilder.contextPath = sc.getContextPath();
} }
public void contextDestroyed(ServletContextEvent event) { public void contextDestroyed(ServletContextEvent event) {

View file

@ -13,8 +13,10 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils; import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.IndividualTemplateModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.IndividualTemplateModel;
import freemarker.template.Configuration;
/** /**
* Generates a list of individuals for display in a template * Generates a list of individuals for display in a template
@ -23,23 +25,18 @@ public class IndividualListController extends FreeMarkerHttpServlet {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(IndividualListController.class.getName()); private static final Log log = LogFactory.getLog(IndividualListController.class.getName());
private VClass vclass = null; // private VClass vclass = null;
private String title = null; // private String title = null;
protected void setTitleAndBody() {
setBody();
}
protected String getBody() { protected String getBody(VitroRequest vreq, Map<String, Object> body, Configuration config) {
Map<String, Object> body = new HashMap<String, Object>();
String bodyTemplate = "individualList.ftl"; String bodyTemplate = "individualList.ftl";
String errorMessage = null; String errorMessage = null;
String message = null; String message = null;
try { try {
Object obj = vreq.getAttribute("vclass"); Object obj = vreq.getAttribute("vclass");
vclass = null; VClass vclass = null;
if ( obj == null ) { // look for vitroclass id parameter if ( obj == null ) { // look for vitroclass id parameter
String vitroClassIdStr = vreq.getParameter("vclassId"); String vitroClassIdStr = vreq.getParameter("vclassId");
if ( !StringUtils.isEmpty(vitroClassIdStr)) { if ( !StringUtils.isEmpty(vitroClassIdStr)) {
@ -77,13 +74,15 @@ public class IndividualListController extends FreeMarkerHttpServlet {
} }
// Set title and subtitle. Title will be retrieved later in getTitle(). // Set title and subtitle. Title will be retrieved later in getTitle().
VClassGroup classGroup = vclass.getGroup(); VClassGroup classGroup = vclass.getGroup();
String title;
if (classGroup == null) { if (classGroup == null) {
title = vclass.getName(); title = vclass.getName();
} else { } else {
title = classGroup.getPublicName(); title = classGroup.getPublicName();
body.put("subtitle", vclass.getName()); body.put("subtitle", vclass.getName());
} }
body.put("title", title);
body.put("individuals", individuals); body.put("individuals", individuals);
} }
@ -100,16 +99,8 @@ public class IndividualListController extends FreeMarkerHttpServlet {
} else if (message != null) { } else if (message != null) {
body.put("message", message); body.put("message", message);
} }
setTitle();
return mergeBodyToTemplate(bodyTemplate, body); return mergeBodyToTemplate(bodyTemplate, body, config);
}
protected String getTitle() {
// The title is determined during compilation of the body, so we put it in an instance variable
// to be retrieved later.
return title;
} }
private class HelpException extends Throwable { private class HelpException extends Throwable {

View file

@ -27,7 +27,9 @@ import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.rdf.model.StmtIterator;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.web.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.web.DisplayVocabulary;
import freemarker.template.Configuration;
public class NavigationController extends FreeMarkerHttpServlet { public class NavigationController extends FreeMarkerHttpServlet {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -45,7 +47,7 @@ public class NavigationController extends FreeMarkerHttpServlet {
} }
@Override @Override
protected String getBody() { protected String getBody(VitroRequest vreq, Map<String, Object> body, Configuration config) {
OntModel displayOntModel = (OntModel)getServletContext().getAttribute("displayOntModel"); OntModel displayOntModel = (OntModel)getServletContext().getAttribute("displayOntModel");
OntModel jenaOntModel = (OntModel)getServletContext().getAttribute("jenaOntModel"); OntModel jenaOntModel = (OntModel)getServletContext().getAttribute("jenaOntModel");
@ -54,7 +56,7 @@ public class NavigationController extends FreeMarkerHttpServlet {
Map<String,Object> values = getValues(ind, displayOntModel,jenaOntModel, getValuesFromRequest(/*?*/) ); Map<String,Object> values = getValues(ind, displayOntModel,jenaOntModel, getValuesFromRequest(/*?*/) );
String template = getTemplate(ind, displayOntModel); String template = getTemplate(ind, displayOntModel);
return mergeBodyToTemplate(template, values); return mergeBodyToTemplate(template, values, config);
} }
private Map<String,Object>getValuesFromRequest(){ private Map<String,Object>getValuesFromRequest(){
@ -158,12 +160,6 @@ public class NavigationController extends FreeMarkerHttpServlet {
void configure( Map<String,String> config); void configure( Map<String,String> config);
Map<String,Object> getValues(OntModel model, Map<String,Object> values); Map<String,Object> getValues(OntModel model, Map<String,Object> values);
} }
@Override
protected String getTitle() {
// TODO Auto-generated method stub
return super.getTitle();
}
private class NavigationURLPatternListener extends StatementListener { private class NavigationURLPatternListener extends StatementListener {
private Map<Pattern,String> urlPatternToURI; private Map<Pattern,String> urlPatternToURI;

View file

@ -8,28 +8,31 @@ import java.util.Map;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.utils.StringUtils; import edu.cornell.mannlib.vitro.webapp.utils.StringUtils;
import freemarker.template.Configuration;
public class TermsOfUseController extends FreeMarkerHttpServlet { public class TermsOfUseController extends FreeMarkerHttpServlet {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(TermsOfUseController.class.getName()); private static final Log log = LogFactory.getLog(TermsOfUseController.class.getName());
protected String getTitle() { protected String getTitle(String siteName) {
return appName + " Terms of Use"; return siteName + " Terms of Use";
} }
protected String getBody() { protected String getBody(VitroRequest vreq, Map<String, Object> body, Configuration config) {
Map<String, Object> body = new HashMap<String, Object>(); Portal portal = vreq.getPortal();
String rootBreadCrumbAnchor = portal.getRootBreadCrumbAnchor(); String rootBreadCrumbAnchor = portal.getRootBreadCrumbAnchor();
String websiteName = StringUtils.isEmpty(rootBreadCrumbAnchor) ? appName : rootBreadCrumbAnchor; String websiteName = StringUtils.isEmpty(rootBreadCrumbAnchor) ? portal.getAppName() : rootBreadCrumbAnchor;
body.put("websiteName", websiteName); body.put("websiteName", websiteName);
body.put("copyrightAnchor", portal.getCopyrightAnchor()); body.put("copyrightAnchor", portal.getCopyrightAnchor());
String bodyTemplate = "termsOfUse.ftl"; String bodyTemplate = "termsOfUse.ftl";
return mergeBodyToTemplate(bodyTemplate, body); return mergeBodyToTemplate(bodyTemplate, body, config);
} }
} }

View file

@ -9,6 +9,9 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import freemarker.template.Configuration;
/** /**
* A place for storing test cases. * A place for storing test cases.
* @author rjy7 * @author rjy7
@ -22,9 +25,7 @@ public class TestController extends FreeMarkerHttpServlet {
return "Test"; return "Test";
} }
protected String getBody() { protected String getBody(VitroRequest vreq, Map<String, Object> body, Configuration config) {
Map<String, Object> body = new HashMap<String, Object>();
// Test of #list directive in template on undefined, null, and empty values. // Test of #list directive in template on undefined, null, and empty values.
// Basic idea: empty list okay, null or undefined value not okay. // Basic idea: empty list okay, null or undefined value not okay.
@ -68,7 +69,7 @@ public class TestController extends FreeMarkerHttpServlet {
// Create the template to see the examples live. // Create the template to see the examples live.
String bodyTemplate = "test.ftl"; String bodyTemplate = "test.ftl";
return mergeBodyToTemplate(bodyTemplate, body); return mergeBodyToTemplate(bodyTemplate, body, config);
} }

View file

@ -47,6 +47,7 @@ import edu.cornell.mannlib.vitro.webapp.search.lucene.Entity2LuceneDoc;
import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneIndexer; import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneIndexer;
import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneSetup; import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneSetup;
import edu.cornell.mannlib.vitro.webapp.utils.FlagMathUtils; import edu.cornell.mannlib.vitro.webapp.utils.FlagMathUtils;
import freemarker.template.Configuration;
/** /**
* AutocompleteController is used to generate autocomplete and select element content * AutocompleteController is used to generate autocomplete and select element content
@ -93,17 +94,18 @@ public class AutocompleteController extends FreeMarkerHttpServlet implements Sea
String templateName = request.getServletPath().equals("/autocomplete") ? "autocompleteResults.ftl" : "selectResults.ftl"; String templateName = request.getServletPath().equals("/autocomplete") ? "autocompleteResults.ftl" : "selectResults.ftl";
Map<String, Object> map = new HashMap<String, Object>(); Map<String, Object> map = new HashMap<String, Object>();
VitroRequest vreq = new VitroRequest(request);
Configuration config = getConfig(vreq);
PortalFlag portalFlag = vreq.getPortalFlag();
try { try {
doSetup(request, response);
PortalFlag portalFlag = vreq.getPortalFlag();
// make sure an IndividualDao is available // make sure an IndividualDao is available
if( vreq.getWebappDaoFactory() == null if( vreq.getWebappDaoFactory() == null
|| vreq.getWebappDaoFactory().getIndividualDao() == null ){ || vreq.getWebappDaoFactory().getIndividualDao() == null ){
log.error("makeUsableBeans() could not get IndividualDao "); log.error("makeUsableBeans() could not get IndividualDao ");
doSearchError(templateName, map); doSearchError(templateName, map, config, response);
return; return;
} }
IndividualDao iDao = vreq.getWebappDaoFactory().getIndividualDao(); IndividualDao iDao = vreq.getWebappDaoFactory().getIndividualDao();
@ -121,7 +123,7 @@ public class AutocompleteController extends FreeMarkerHttpServlet implements Sea
List<String> urisToExclude = Arrays.asList(vreq.getParameterValues("filter")); List<String> urisToExclude = Arrays.asList(vreq.getParameterValues("filter"));
if (query == null ) { if (query == null ) {
doNoQuery(templateName, map); doNoQuery(templateName, map, config, response);
return; return;
} }
@ -138,20 +140,20 @@ public class AutocompleteController extends FreeMarkerHttpServlet implements Sea
topDocs = searcherForRequest.search(query,null,maxHitSize); topDocs = searcherForRequest.search(query,null,maxHitSize);
}catch (Exception ex){ }catch (Exception ex){
log.error(ex); log.error(ex);
doFailedSearch(templateName, map); doFailedSearch(templateName, map, config, response);
return; return;
} }
} }
if( topDocs == null || topDocs.scoreDocs == null){ if( topDocs == null || topDocs.scoreDocs == null){
log.error("topDocs for a search was null"); log.error("topDocs for a search was null");
doFailedSearch(templateName, map); doFailedSearch(templateName, map, config, response);
return; return;
} }
int hitsLength = topDocs.scoreDocs.length; int hitsLength = topDocs.scoreDocs.length;
if ( hitsLength < 1 ){ if ( hitsLength < 1 ){
doFailedSearch(templateName, map); doFailedSearch(templateName, map, config, response);
return; return;
} }
log.debug("found "+hitsLength+" hits"); log.debug("found "+hitsLength+" hits");
@ -178,11 +180,11 @@ public class AutocompleteController extends FreeMarkerHttpServlet implements Sea
Collections.sort(results); Collections.sort(results);
map.put("results", results); map.put("results", results);
ajaxWrite(templateName, map); ajaxWrite(templateName, map, config, response);
} catch (Throwable e) { } catch (Throwable e) {
log.error("AutocompleteController(): " + e); log.error("AutocompleteController(): " + e);
doSearchError(templateName, map); doSearchError(templateName, map, config, response);
return; return;
} }
} }
@ -333,16 +335,16 @@ public class AutocompleteController extends FreeMarkerHttpServlet implements Sea
} }
private void doNoQuery(String templateName, Map<String, Object> map) { private void doNoQuery(String templateName, Map<String, Object> map, Configuration config, HttpServletResponse response) {
ajaxWrite(templateName, map); ajaxWrite(templateName, map, config, response);
} }
private void doFailedSearch(String templateName, Map<String, Object> map) { private void doFailedSearch(String templateName, Map<String, Object> map, Configuration config, HttpServletResponse response) {
ajaxWrite(templateName, map); ajaxWrite(templateName, map, config, response);
} }
private void doSearchError(String templateName, Map<String, Object> map) { private void doSearchError(String templateName, Map<String, Object> map, Configuration config, HttpServletResponse response) {
ajaxWrite(templateName, map); ajaxWrite(templateName, map, config, response);
} }
public static final int MAX_QUERY_LENGTH = 500; public static final int MAX_QUERY_LENGTH = 500;

View file

@ -3,7 +3,7 @@
<#-- Contact form submission confirmation page --> <#-- Contact form submission confirmation page -->
<h2>Thank you for your feedback</h2> <h2>Thank you for your feedback</h2>
<img src="${siteIconPath}/mail.gif" alt="mailbox"/><br/> <img src="${urls.siteIcons}/mail.gif" alt="mailbox"/><br/>
<p>Thank you for contacting our curation and development team. We will respond to your inquiry as soon as possible.</p> <p>Thank you for contacting our curation and development team. We will respond to your inquiry as soon as possible.</p>
<p>Return to the <a href="${urls.home}">home page</a>.</p> <p>Return to the <a href="${urls.home}">home page</a>.</p>

View file

@ -4,7 +4,7 @@
<h2>${title}</h2> <h2>${title}</h2>
<img src="${siteIconPath}/bomb.gif" alt="email error"/> <img src="${urls.siteIcons}/bomb.gif" alt="email error"/>
<p class="normal">An error occurred during the processing of your request.<br /> <p class="normal">An error occurred during the processing of your request.<br />
<#if errorMessage?has_content> <#if errorMessage?has_content>

View file

@ -4,8 +4,8 @@
<div id="footer"> <div id="footer">
<#if bannerImageUrl??> <#if urls.bannerImage??>
<img class="footerLogo" src="${urls.bannerImage}" alt="${tagline!}" /> <img class="footerLogo" src="${urls.bannerImage}" alt="${siteTagline!}" />
</#if> </#if>
<div class="footerLinks"> <div class="footerLinks">

View file

@ -6,8 +6,8 @@
<h1><a title="Home" href="${urls.home}">${siteName}</a></h1> <h1><a title="Home" href="${urls.home}">${siteName}</a></h1>
<#if tagline.has_content> <#if siteTagline.has_content>
<em>${tagline}</em> <em>${siteTagline}</em>
</#if> </#if>
<ul id="otherMenu"> <ul id="otherMenu">

View file

@ -7,7 +7,7 @@
<#if showFlag1SearchField??> <#if showFlag1SearchField??>
<select id="search-form-modifier" name="flag1" class="form-item" > <select id="search-form-modifier" name="flag1" class="form-item" >
<option value="nofiltering" selected="selected">entire database (${loginName})</option> <option value="nofiltering" selected="selected">entire database (${loginName})</option>
<option value="${portalId}">${tagline!}</option> <option value="${portalId}">${siteTagline!}</option>
</select> </select>
<#else> <#else>
<input type="hidden" name="flag1" value="${portalId}" /> <input type="hidden" name="flag1" value="${portalId}" />