merging develop to issue-vivo-101-sparqlupdate

This commit is contained in:
Brian Caruso 2013-08-19 16:21:16 -04:00
commit e6a7ad34d3
41 changed files with 1076 additions and 1640 deletions

View file

@ -74,6 +74,15 @@ public class SimplePermission extends Permission {
"SeeVerbosePropertyInformation");
public static final SimplePermission USE_ADVANCED_DATA_TOOLS_PAGES = new SimplePermission(
"UseAdvancedDataToolsPages");
public static final SimplePermission USE_SPARQL_QUERY_PAGE = new SimplePermission(
"UseSparqlQueryPage");
// ----------------------------------------------------------------------
// These instances are "catch all" permissions to cover poorly defined
// groups of actions until better definitions were found. Don't add usages
// of these, and remove existing usages where possible.
// ----------------------------------------------------------------------
public static final SimplePermission USE_BASIC_AJAX_CONTROLLERS = new SimplePermission(
"UseBasicAjaxControllers");
public static final SimplePermission USE_MISCELLANEOUS_ADMIN_PAGES = new SimplePermission(
@ -84,8 +93,6 @@ public class SimplePermission extends Permission {
"UseMiscellaneousEditorPages");
public static final SimplePermission USE_MISCELLANEOUS_PAGES = new SimplePermission(
"UseMiscellaneousPages");
public static final SimplePermission USE_SPARQL_QUERY_PAGE = new SimplePermission(
"UseSparqlQueryPage");
public static List<SimplePermission> getAllInstances() {
return new ArrayList<SimplePermission>(allInstances.values());

View file

@ -17,7 +17,7 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfigurationLoader;
import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration;
import freemarker.template.Configuration;
import freemarker.template.Template;
@ -73,8 +73,8 @@ public abstract class VitroAjaxController extends HttpServlet {
* Process data through a Freemarker template and output the result.
*/
protected void writeTemplate(String templateName, Map<String, Object> map,
VitroRequest vreq, HttpServletResponse response) {
Configuration config = FreemarkerConfigurationLoader.getConfig(vreq);
HttpServletRequest req, HttpServletResponse response) {
Configuration config = FreemarkerConfiguration.getConfig(req);
try {
Template template = config.getTemplate(templateName);
PrintWriter out = response.getWriter();

View file

@ -61,6 +61,8 @@ public class FreemarkerComponentGenerator extends FreemarkerHttpServlet {
return get(templateName, root, request);
}
// JB Because this is pretending to be a servlet, but the init method has not been called, providing the context.
// Do that in the constructor, and we should be fine. VIVO-251
// RY We need the servlet context in getConfig(). For some reason using the method inherited from
// GenericServlet bombs.
@Override

View file

@ -1,322 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfigurationConstants;
import edu.cornell.mannlib.vitro.webapp.i18n.freemarker.I18nMethodModel;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetterUtils;
import edu.cornell.mannlib.vitro.webapp.web.directives.IndividualShortViewDirective;
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualLocalNameMethod;
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualPlaceholderImageUrlMethod;
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualProfileUrlMethod;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.core.Environment;
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModelException;
import freemarker.template.utility.DeepUnwrap;
public class FreemarkerConfiguration extends Configuration {
private static final Log log = LogFactory.getLog(FreemarkerConfiguration.class);
private static final String PROPERTY_DEVELOPER_DEFEAT_CACHE = "developer.defeatFreemarkerCache";
private static final String PROPERTY_DEVELOPER_INSERT_DELIMITERS = "developer.insertFreemarkerDelimiters";
private final String themeDir;
private final ServletContext context;
private final ApplicationBean appBean;
private final ConfigurationProperties props;
FreemarkerConfiguration(String themeDir, ApplicationBean appBean, ServletContext context) {
this.themeDir = themeDir;
this.context = context;
this.appBean = appBean;
this.props = ConfigurationProperties.getBean(context);
String flag = props.getProperty(PROPERTY_DEVELOPER_DEFEAT_CACHE, "false");
if (Boolean.valueOf(flag.trim())) {
log.debug("Disabling Freemarker template caching in development build.");
setTemplateUpdateDelay(0); // no template caching in development
} else {
int delay = 60;
log.debug("Setting Freemarker template cache update delay to " + delay + ".");
setTemplateUpdateDelay(delay); // in seconds; Freemarker default is 5
}
// Specify how templates will see the data model.
// The Freemarker default wrapper exposes set methods and get methods that take
// arguments. We block exposure to these methods by default.
BeansWrapper wrapper = new DefaultObjectWrapper();
wrapper.setExposureLevel(BeansWrapper.EXPOSE_PROPERTIES_ONLY);
setObjectWrapper(wrapper);
// Set some formatting defaults. These can be overridden at the template
// or environment (template-processing) level, or for an individual
// token by using built-ins.
setLocale(java.util.Locale.US);
String dateFormat = "M/d/yyyy";
setDateFormat(dateFormat);
String timeFormat = "h:mm a";
setTimeFormat(timeFormat);
setDateTimeFormat(dateFormat + " " + timeFormat);
//config.setNumberFormat("#,##0.##");
try {
setSetting("url_escaping_charset", "ISO-8859-1");
} catch (TemplateException e) {
log.error("Error setting value for url_escaping_charset.");
}
setTemplateLoader(createTemplateLoader());
setSharedVariables();
}
/**
* These are values that are accessible to all
* templates loaded by the Configuration's TemplateLoader. They
* should be application- rather than request-specific.
*/
private void setSharedVariables() {
Map<String, Object> sharedVariables = new HashMap<String, Object>();
sharedVariables.put("siteName", appBean.getApplicationName());
sharedVariables.put("version", getRevisionInfo());
sharedVariables.put("urls", getSiteUrls());
sharedVariables.put("themeDir", themeDir);
sharedVariables.put("currentTheme", themeDir.substring(themeDir.lastIndexOf('/')+1));
sharedVariables.putAll(getDirectives());
sharedVariables.putAll(getMethods());
sharedVariables.put("siteTagline", appBean.getShortHand());
//Put in edit configuration constants - useful for freemarker templates/editing
sharedVariables.put("editConfigurationConstants", EditConfigurationConstants.exportConstants());
for ( Map.Entry<String, Object> variable : sharedVariables.entrySet() ) {
try {
setSharedVariable(variable.getKey(), variable.getValue());
} catch (TemplateModelException e) {
log.error("Could not set shared variable '" + variable.getKey() + "' in Freemarker configuration");
}
}
}
private final Map<String, Object> getRevisionInfo() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("label", RevisionInfoBean.getBean(context)
.getReleaseLabel());
map.put("moreInfoUrl", UrlBuilder.getUrl("/revisionInfo"));
return map;
}
private final Map<String, String> getSiteUrls() {
Map<String, String> urls = new HashMap<String, String>();
// Templates use this to construct urls.
urls.put("base", context.getContextPath());
urls.put("home", UrlBuilder.getHomeUrl());
urls.put("about", UrlBuilder.getUrl(Route.ABOUT));
urls.put("search", UrlBuilder.getUrl(Route.SEARCH));
urls.put("termsOfUse", UrlBuilder.getUrl(Route.TERMS_OF_USE));
urls.put("login", UrlBuilder.getLoginUrl());
urls.put("logout", UrlBuilder.getLogoutUrl());
urls.put("siteAdmin", UrlBuilder.getUrl(Route.SITE_ADMIN));
urls.put("themeImages", UrlBuilder.getUrl(themeDir + "/images"));
urls.put("images", UrlBuilder.getUrl("/images"));
urls.put("theme", UrlBuilder.getUrl(themeDir));
urls.put("index", UrlBuilder.getUrl("/browse"));
return urls;
}
public static Map<String, Object> getDirectives() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("dump", new freemarker.ext.dump.DumpDirective());
map.put("dumpAll", new freemarker.ext.dump.DumpAllDirective());
map.put("help", new freemarker.ext.dump.HelpDirective());
map.put("shortView", new IndividualShortViewDirective());
return map;
}
public static Map<String, Object> getMethods() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("profileUrl", new IndividualProfileUrlMethod());
map.put("localName", new IndividualLocalNameMethod());
map.put("placeholderImageUrl", new IndividualPlaceholderImageUrlMethod());
map.put("i18n", new I18nMethodModel());
return map;
}
// Define template locations. Template loader will look first in the theme-specific
// location, then in the vitro location.
protected final TemplateLoader createTemplateLoader() {
List<TemplateLoader> loaders = new ArrayList<TemplateLoader>();
MultiTemplateLoader mtl = null;
try {
// Theme template loader
String themeTemplatePath = context.getRealPath(themeDir) + "/templates";
File themeTemplateDir = new File(themeTemplatePath);
// Handle the case where there's no theme template directory gracefully
if (themeTemplateDir.exists()) {
FileTemplateLoader themeFtl = new FileTemplateLoader(themeTemplateDir);
loaders.add(themeFtl);
}
// Vitro template loader
String vitroTemplatePath = context.getRealPath("/templates/freemarker");
loaders.add(new FlatteningTemplateLoader(new File(vitroTemplatePath)));
loaders.add(new ClassTemplateLoader(getClass(), ""));
TemplateLoader[] loaderArray = loaders.toArray(new TemplateLoader[loaders.size()]);
mtl = new MultiTemplateLoader(loaderArray);
} catch (IOException e) {
log.error("Error creating template loaders");
}
// Add the ability to add delimiters to the templates, based on
// settings.
if (Boolean.valueOf(props.getProperty(PROPERTY_DEVELOPER_INSERT_DELIMITERS))) {
return new DelimitingTemplateLoader(mtl);
} else {
return mtl;
}
}
/**
* Override getTemplate(), so we can apply DataGetters to all included
* templates.
*
* This won't work for top-level Templates, since the Environment hasn't
* been created yet. When TemplateProcessingHelper creates the Environment,
* it must call retrieveAndRunDataGetters() for the top-level Template.
*/
@Override
public Template getTemplate(String name, Locale locale, String encoding,
boolean parse) throws IOException {
Template template = super.getTemplate(name, locale, encoding, parse);
if (template == null) {
log.debug("Template '" + name + "' not found for locale '" + locale + "'.");
return template;
}
Environment env = getEnvironment();
if (env == null) {
log.debug("Not fetching data getters for template '" + template.getName() + "'. No environment.");
return template;
}
retrieveAndRunDataGetters(env, template.getName());
return template;
}
/**
* Find the DataGetters for this template, and apply them to the Freemarker
* environment.
*/
public static void retrieveAndRunDataGetters(Environment env, String templateName) {
HttpServletRequest req = (HttpServletRequest) env.getCustomAttribute("request");
VitroRequest vreq = new VitroRequest(req);
if (dataGettersAlreadyApplied(env, templateName)) {
log.debug("DataGetters for '" + templateName+"' have already been applied");
return;
}
try {
List<DataGetter> dgList = DataGetterUtils.getDataGettersForTemplate(
vreq, vreq.getDisplayModel(), templateName);
log.debug("Retrieved " + dgList.size() + " data getters for template '" + templateName + "'");
@SuppressWarnings("unchecked")
Map<String, Object> dataMap = (Map<String, Object>) DeepUnwrap.permissiveUnwrap(env.getDataModel());
for (DataGetter dg : dgList) {
applyDataGetter(dg, env, dataMap);
}
} catch (Exception e) {
log.warn(e, e);
}
}
/**
* Have the DataGetters for this template already been applied to this environment?
* If not, record that they are being applied now.
*/
@SuppressWarnings("unchecked")
private static boolean dataGettersAlreadyApplied(Environment env, String templateName) {
Set<String> names;
Object o = env.getCustomAttribute("dataGettersApplied");
if (o instanceof Set) {
names = (Set<String>) o;
} else {
names = new HashSet<String>();
}
boolean added = names.add(templateName);
if (added) {
env.setCustomAttribute("dataGettersApplied", names);
return false;
} else {
return true;
}
}
/**
* Get the data from a DataGetter, and store it in global variables in the
* Freemarker environment.
*/
private static void applyDataGetter(DataGetter dg, Environment env,
Map<String, Object> dataMap) throws TemplateModelException {
Map<String, Object> moreData = dg.getData(dataMap);
ObjectWrapper wrapper = env.getObjectWrapper();
if (moreData != null) {
for (String key : moreData.keySet()) {
Object value = moreData.get(key);
env.setGlobalVariable(key, wrapper.wrap(value));
log.debug("Stored in environment: '" + key + "' = '" + value + "'");
}
}
}
}

View file

@ -1,64 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
public class FreemarkerConfigurationLoader {
private static final Log log = LogFactory
.getLog(FreemarkerConfigurationLoader.class);
private static final Map<String, FreemarkerConfiguration> themeToConfigMap = new HashMap<String, FreemarkerConfiguration>();
public static FreemarkerConfiguration getConfig(VitroRequest vreq) {
String themeDir = getThemeDir(vreq.getAppBean());
return getConfigForTheme(themeDir, vreq.getAppBean(), vreq.getSession().getServletContext());
}
private static String getThemeDir(ApplicationBean appBean) {
if (appBean == null) {
log.error("Cannot get themeDir from null application bean");
return null;
}
String themeDir = appBean.getThemeDir();
if (themeDir == null) {
log.error("themeDir is null");
return null;
}
return themeDir.replaceAll("/$", "");
}
/**
* The Configuration is theme-specific because:
*
* 1. The template loader is theme-specific, since it specifies a theme
* directory to load templates from.
*
* 2. Some shared variables are theme-specific.
*/
private static FreemarkerConfiguration getConfigForTheme(String themeDir,
ApplicationBean appBean, ServletContext context) {
synchronized (themeToConfigMap) {
if (themeToConfigMap.containsKey(themeDir)) {
return themeToConfigMap.get(themeDir);
} else {
FreemarkerConfiguration config = new FreemarkerConfiguration(
themeDir, appBean, context);
themeToConfigMap.put(themeDir, config);
return config;
}
}
}
}

View file

@ -37,10 +37,12 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Res
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory;
import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailMessage;
import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.User;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu;
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
@ -336,7 +338,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
private Map<String, Object> buildRequestUrls(VitroRequest vreq) {
Map<String, Object> requestUrls = new HashMap<String, Object>();
FreemarkerConfiguration config = FreemarkerConfigurationLoader.getConfig(vreq);
Configuration config = FreemarkerConfiguration.getConfig(vreq);
TemplateModel urlModel = config.getSharedVariable("urls");
try {
@ -427,10 +429,6 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
// the copyright text can be viewed with having to restart Tomcat
map.put("copyright", getCopyrightInfo(appBean));
map.put("url", new edu.cornell.mannlib.vitro.webapp.web.directives.UrlDirective());
map.put("widget", new edu.cornell.mannlib.vitro.webapp.web.directives.WidgetDirective());
map.putAll( FreemarkerConfiguration.getDirectives() );
// Add these accumulator objects. They will collect tags so the template can write them
// at the appropriate location.
map.put("stylesheets", new Tags().wrap());

View file

@ -13,7 +13,8 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration;
import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfigurationImpl;
import freemarker.core.Environment;
import freemarker.template.Configuration;
import freemarker.template.Template;
@ -24,13 +25,9 @@ public class TemplateProcessingHelper {
private static final Log log = LogFactory.getLog(TemplateProcessingHelper.class);
private Configuration config = null;
private HttpServletRequest request = null;
private ServletContext context = null;
public TemplateProcessingHelper(HttpServletRequest request, ServletContext context) {
this.config = FreemarkerConfigurationLoader.getConfig(new VitroRequest(request));
this.request = request;
this.context = context;
this.config = FreemarkerConfiguration.getConfig(request);
}
public StringWriter processTemplate(String templateName, Map<String, Object> map)
@ -46,14 +43,6 @@ public class TemplateProcessingHelper {
try {
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
String templateType = (String) map.get("templateType");
@ -62,7 +51,8 @@ public class TemplateProcessingHelper {
}
// Apply any data-getters that are associated with this template.
FreemarkerConfiguration.retrieveAndRunDataGetters(env, template.getName());
// TODO clean this up VIVO-249
FreemarkerConfigurationImpl.retrieveAndRunDataGetters(env, template.getName());
// Now process it.
env.process();

View file

@ -1,39 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.json;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetterUtils;
/**
* Gets data based on data getter for page uri and returns in the form of Json objects
*/
public class GetDataForPage extends JsonObjectProducer {
private static final Log log = LogFactory.getLog(GetDataForPage.class);
protected GetDataForPage(VitroRequest vreq) {
super(vreq);
}
@Override
protected JSONObject process() throws Exception {
JSONObject rObj = null;
String pageUri = vreq.getParameter("pageUri");
if(pageUri != null && !pageUri.isEmpty()) {
Map<String,Object> data = PageDataGetterUtils.getDataForPage(pageUri, vreq, ctx);
//Convert to json version based on type of page
if(data != null) {
//Convert to json version based on type of page
rObj = PageDataGetterUtils.covertDataToJSONForPage(pageUri, data, vreq, ctx);
}
}
return rObj;
}
}

View file

@ -3,8 +3,11 @@
package edu.cornell.mannlib.vitro.webapp.controller.json;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
@ -15,17 +18,21 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.PageRecord;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.utils.log.LogUtils;
import edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.PageDataGetterUtils;
/**
* This servlet is for servicing requests for JSON objects/data.
@ -69,7 +76,9 @@ public class JsonServlet extends VitroHttpServlet {
log.debug("AJAX request to retrieve individuals by vclasses");
new GetSolrIndividualsByVClasses(vreq).process(resp);
} else if( vreq.getParameter("getDataForPage") != null ){
new GetDataForPage(vreq).process(resp);
throw new IllegalArgumentException("The call invoked deprecated classes " +
"and the parameter for this call appeared nowhere in the code base, " +
"so it was removed in Aug 5th 2013.");
}else if( vreq.getParameter("getRenderedSolrIndividualsByVClass") != null ){
new GetRenderedSolrIndividualsByVClass(vreq).process(resp);
}else if( vreq.getParameter("getRandomSolrIndividualsByVClass") != null ){
@ -85,7 +94,7 @@ public class JsonServlet extends VitroHttpServlet {
Map<String, Object> map = getSolrVClassIntersectionResults(vclassURIs, vreq, context);
//last parameter indicates single vclass instead of multiple vclasses
return processVClassResults(map, vreq, context, false);
return processVclassResultsJSON(map, vreq, false);
}
public static JSONObject getSolrIndividualsByVClasses(List<String> vclassURIs, HttpServletRequest req, ServletContext context) throws Exception {
@ -93,8 +102,8 @@ public class JsonServlet extends VitroHttpServlet {
log.debug("Retrieve solr results for vclasses" + vclassURIs.toString());
Map<String, Object> map = getSolrVClassIntersectionResults(vclassURIs, vreq, context);
log.debug("Results returned from Solr for " + vclassURIs.toString() + " are of size " + map.size());
JSONObject rObj = processVClassResults(map, vreq, context, true);
return rObj;
return processVclassResultsJSON(map, vreq, true);
}
//Including version for Solr query for Vclass Intersections
@ -119,10 +128,10 @@ public class JsonServlet extends VitroHttpServlet {
}
// Map given to process method includes the actual individuals returned from the search
public static JSONObject processVClassResults(Map<String, Object> map, VitroRequest vreq, ServletContext context, boolean multipleVclasses) throws Exception{
JSONObject rObj = PageDataGetterUtils.processVclassResultsJSON(map, vreq, multipleVclasses);
return rObj;
}
// public static JSONObject processVClassResults(Map<String, Object> map, VitroRequest vreq, ServletContext context, boolean multipleVclasses) throws Exception{
// JSONObject rObj = processVclassResultsJSON(map, vreq, multipleVclasses);
// return rObj;
// }
public static Collection<String> getMostSpecificTypes(Individual individual, WebappDaoFactory wdf) {
ObjectPropertyStatementDao opsDao = wdf.getObjectPropertyStatementDao();
@ -143,7 +152,7 @@ public class JsonServlet extends VitroHttpServlet {
Map<String, Object> map = getRandomSolrVClassResults(vclassURI, vreq, context);
//last parameter indicates single vclass instead of multiple vclasses
return processVClassResults(map, vreq, context, false);
return processVclassResultsJSON(map, vreq, false);
}
//Including version for Random Solr query for Vclass Intersections
@ -169,4 +178,120 @@ public class JsonServlet extends VitroHttpServlet {
}
/**
* Process results related to VClass or vclasses. Handles both single and multiple vclasses being sent.
*/
public static JSONObject processVclassResultsJSON(Map<String, Object> map, VitroRequest vreq, boolean multipleVclasses) {
JSONObject rObj = new JSONObject();
VClass vclass=null;
try {
// Properties from ontologies used by VIVO - should not be in vitro
DataProperty fNameDp = (new DataProperty());
fNameDp.setURI("http://xmlns.com/foaf/0.1/firstName");
DataProperty lNameDp = (new DataProperty());
lNameDp.setURI("http://xmlns.com/foaf/0.1/lastName");
DataProperty preferredTitleDp = (new DataProperty());
preferredTitleDp.setURI("http://vivoweb.org/ontology/core#preferredTitle");
if( log.isDebugEnabled() ){
@SuppressWarnings("unchecked")
Enumeration<String> e = vreq.getParameterNames();
while(e.hasMoreElements()){
String name = e.nextElement();
log.debug("parameter: " + name);
for( String value : vreq.getParameterValues(name) ){
log.debug("value for " + name + ": '" + value + "'");
}
}
}
//need an unfiltered dao to get firstnames and lastnames
WebappDaoFactory fullWdf = vreq.getUnfilteredWebappDaoFactory();
String[] vitroClassIdStr = vreq.getParameterValues("vclassId");
if ( vitroClassIdStr != null && vitroClassIdStr.length > 0){
for(String vclassId: vitroClassIdStr) {
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassId);
if (vclass == null) {
log.error("Couldn't retrieve vclass ");
throw new Exception ("Class " + vclassId + " not found");
}
}
}else{
log.error("parameter vclassId URI parameter expected ");
throw new Exception("parameter vclassId URI parameter expected ");
}
List<String> vclassIds = Arrays.asList(vitroClassIdStr);
//if single vclass expected, then include vclass. This relates to what the expected behavior is, not size of list
if(!multipleVclasses) {
//currently used for ClassGroupPage
rObj.put("vclass",
new JSONObject().put("URI",vclass.getURI())
.put("name",vclass.getName()));
} else {
//For now, utilize very last VClass (assume that that is the one to be employed)
//TODO: Find more general way of dealing with this
//put multiple ones in?
if(vclassIds.size() > 0) {
int numberVClasses = vclassIds.size();
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassIds.get(numberVClasses - 1));
rObj.put("vclass", new JSONObject().put("URI",vclass.getURI())
.put("name",vclass.getName()));
}
// rObj.put("vclasses", new JSONObject().put("URIs",vitroClassIdStr)
// .put("name",vclass.getName()));
}
if (vclass != null) {
rObj.put("totalCount", map.get("totalCount"));
rObj.put("alpha", map.get("alpha"));
List<Individual> inds = (List<Individual>)map.get("entities");
log.debug("Number of individuals returned from request: " + inds.size());
JSONArray jInds = new JSONArray();
for(Individual ind : inds ){
JSONObject jo = new JSONObject();
jo.put("URI", ind.getURI());
jo.put("label",ind.getRdfsLabel());
jo.put("name",ind.getName());
jo.put("thumbUrl", ind.getThumbUrl());
jo.put("imageUrl", ind.getImageUrl());
jo.put("profileUrl", UrlBuilder.getIndividualProfileUrl(ind, vreq));
jo.put("mostSpecificTypes", JsonServlet.getMostSpecificTypes(ind,fullWdf));
jo.put("preferredTitle", JsonServlet.getDataPropertyValue(ind, preferredTitleDp, fullWdf));
jInds.put(jo);
}
rObj.put("individuals", jInds);
JSONArray wpages = new JSONArray();
//Made sure that PageRecord here is SolrIndividualListController not IndividualListController
List<PageRecord> pages = (List<PageRecord>)map.get("pages");
for( PageRecord pr: pages ){
JSONObject p = new JSONObject();
p.put("text", pr.text);
p.put("param", pr.param);
p.put("index", pr.index);
wpages.put( p );
}
rObj.put("pages",wpages);
JSONArray jletters = new JSONArray();
List<String> letters = Controllers.getLetters();
for( String s : letters){
JSONObject jo = new JSONObject();
jo.put("text", s);
jo.put("param", "alpha=" + URLEncoder.encode(s, "UTF-8"));
jletters.put( jo );
}
rObj.put("letters", jletters);
}
} catch(Exception ex) {
log.error("Error occurred in processing JSON object", ex);
}
return rObj;
}
}

View file

@ -23,11 +23,11 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfigurationLoader;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo;
import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration;
import freemarker.template.Configuration;
public class EditConfigurationUtils {
@ -272,7 +272,7 @@ public class EditConfigurationUtils {
//Generate HTML for a specific field name given
public static String generateHTMLForElement(VitroRequest vreq, String fieldName, EditConfigurationVTwo editConfig) {
String html = "";
Configuration fmConfig = FreemarkerConfigurationLoader.getConfig(vreq);
Configuration fmConfig = FreemarkerConfiguration.getConfig(vreq);
FieldVTwo field = editConfig == null ? null : editConfig.getField(fieldName);
MultiValueEditSubmission editSub = EditSubmissionUtils.getEditSubmissionFromSession(vreq.getSession(), editConfig);

View file

@ -25,9 +25,9 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
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.FreemarkerConfigurationLoader;
import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
import freemarker.template.Configuration;
/**
* A factory that creates Freemarker-based email messages.
@ -59,8 +59,7 @@ public class FreemarkerEmailFactory {
}
FreemarkerEmailFactory factory = getFactory(vreq);
FreemarkerConfiguration fConfig = FreemarkerConfigurationLoader
.getConfig(vreq);
Configuration fConfig = FreemarkerConfiguration.getConfig(vreq);
return new FreemarkerEmailMessage(vreq, fConfig,
factory.getEmailSession(), factory.getReplyToAddress());
}

View file

@ -28,10 +28,8 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfiguration;
import edu.cornell.mannlib.vitro.webapp.web.directives.EmailDirective;
import freemarker.core.Environment;
import freemarker.template.Template;
import freemarker.template.Configuration;
import freemarker.template.TemplateException;
/**
@ -51,7 +49,7 @@ public class FreemarkerEmailMessage {
private final VitroRequest vreq;
private final Session mailSession;
private final FreemarkerConfiguration config;
private final Configuration config;
private final List<Recipient> recipients = new ArrayList<Recipient>();
private final InternetAddress replyToAddress;
@ -66,7 +64,7 @@ public class FreemarkerEmailMessage {
/**
* Package access - should only be created by the factory.
*/
FreemarkerEmailMessage(VitroRequest vreq, FreemarkerConfiguration fConfig,
FreemarkerEmailMessage(VitroRequest vreq, Configuration fConfig,
Session mailSession, InternetAddress replyToAddress) {
this.vreq = vreq;
this.mailSession = mailSession;
@ -144,14 +142,8 @@ public class FreemarkerEmailMessage {
bodyMap.put("email", new EmailDirective(this));
try {
Template template = config.getTemplate(templateName);
Environment env = template.createProcessingEnvironment(bodyMap,
config.getTemplate(templateName).process(bodyMap,
new StringWriter());
env.setCustomAttribute("request", vreq);
env.setCustomAttribute("context", vreq.getSession()
.getServletContext());
env.process();
} catch (TemplateException e) {
log.error(e, e);
} catch (IOException e) {

View file

@ -1,13 +1,9 @@
package edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest;
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
import java.io.IOException;
import java.util.List;
import java.util.Map;
package edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
@ -26,8 +22,7 @@ public class StreamingMultipartHttpServletRequest extends
* to deal with inputs of very large sizes.
*
*/
public StreamingMultipartHttpServletRequest(HttpServletRequest request)
throws IOException{
public StreamingMultipartHttpServletRequest(HttpServletRequest request) {
super(request);
//use a file uploader that does not save the files to a temporary directory.

View file

@ -0,0 +1,293 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.freemarker.config;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.DelimitingTemplateLoader;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FlatteningTemplateLoader;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfigurationConstants;
import edu.cornell.mannlib.vitro.webapp.i18n.freemarker.I18nMethodModel;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
import edu.cornell.mannlib.vitro.webapp.web.directives.IndividualShortViewDirective;
import edu.cornell.mannlib.vitro.webapp.web.directives.UrlDirective;
import edu.cornell.mannlib.vitro.webapp.web.directives.WidgetDirective;
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualLocalNameMethod;
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualPlaceholderImageUrlMethod;
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualProfileUrlMethod;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModelException;
/**
* Access point for a singleton Configuration instance.
*
* The instance is created at system startup, so we can fail early if there are
* any problems.
*
* The Configuration is slightly extended to hold request-based information in a
* ThreadLocal. The net result is although there is only one configuration (and
* hence only one template cache), each request gets a customization with its
* own locale, etc.
*
* Each time a request asks for the configuration, check to see whether the
* cache is still valid, and whether the theme has changed (needs a new
* TemplateLoader). Store the request info to the ThreadLocal.
*/
public abstract class FreemarkerConfiguration {
private static final Log log = LogFactory
.getLog(FreemarkerConfiguration.class);
private static final String PROPERTY_DEFEAT_CACHE = "developer.defeatFreemarkerCache";
private static final String PROPERTY_INSERT_DELIMITERS = "developer.insertFreemarkerDelimiters";
private static volatile FreemarkerConfigurationImpl instance;
private static volatile String previousThemeDir;
public static Configuration getConfig(HttpServletRequest req) {
confirmInstanceIsSet();
synchronized (instance) {
clearTemplateCacheIfRequested(req);
keepTemplateLoaderCurrentWithThemeDirectory(req);
setThreadLocalsForRequest(req);
return instance;
}
}
private static void confirmInstanceIsSet() {
if (instance == null) {
throw new IllegalStateException(
"VitroFreemarkerConfiguration has not been set.");
}
}
private static void clearTemplateCacheIfRequested(HttpServletRequest req) {
if (isTemplateCacheInvalid(req)) {
instance.clearTemplateCache();
}
}
private static boolean isTemplateCacheInvalid(HttpServletRequest req) {
ConfigurationProperties props = ConfigurationProperties.getBean(req);
// If the developer doesn't want the cache, it's invalid.
if (Boolean.valueOf(props.getProperty(PROPERTY_DEFEAT_CACHE))) {
return true;
}
return false;
}
/**
* Keep track of the theme directory. If it changes, create an appropriate
* new TemplateLoader.
*
* Note that setting a new TemplateLoader on the context Configuration also
* creates a new, empty TemplateCache.
*/
private static void keepTemplateLoaderCurrentWithThemeDirectory(
HttpServletRequest req) {
String themeDir = getThemeDirectory(req);
if (hasThemeDirectoryChanged(themeDir)) {
TemplateLoader tl = createTemplateLoader(req, themeDir);
instance.setTemplateLoader(tl);
}
}
private static String getThemeDirectory(HttpServletRequest req) {
return new VitroRequest(req).getAppBean().getThemeDir();
}
private static boolean hasThemeDirectoryChanged(String themeDir) {
synchronized (instance) {
if (StringUtils.equals(themeDir, previousThemeDir)) {
return false;
} else {
previousThemeDir = themeDir;
return true;
}
}
}
private static TemplateLoader createTemplateLoader(HttpServletRequest req,
String themeDir) {
ServletContext ctx = req.getSession().getServletContext();
ConfigurationProperties props = ConfigurationProperties.getBean(ctx);
List<TemplateLoader> loaders = new ArrayList<TemplateLoader>();
// Theme template loader
String themeTemplatePath = ctx.getRealPath(themeDir) + "/templates";
File themeTemplateDir = new File(themeTemplatePath);
// A theme need not contain a template directory.
if (themeTemplateDir.exists()) {
try {
FileTemplateLoader themeFtl = new FileTemplateLoader(
themeTemplateDir);
loaders.add(themeFtl);
} catch (IOException e) {
log.error("Error creating theme template loader", e);
}
}
// Vitro template loader
String vitroTemplatePath = ctx.getRealPath("/templates/freemarker");
loaders.add(new FlatteningTemplateLoader(new File(vitroTemplatePath)));
// TODO VIVO-243 Why is this here?
loaders.add(new ClassTemplateLoader(FreemarkerConfiguration.class, ""));
TemplateLoader[] loaderArray = loaders
.toArray(new TemplateLoader[loaders.size()]);
MultiTemplateLoader mtl = new MultiTemplateLoader(loaderArray);
// If requested, add delimiters to the templates.
if (Boolean.valueOf(props.getProperty(PROPERTY_INSERT_DELIMITERS))) {
return new DelimitingTemplateLoader(mtl);
} else {
return mtl;
}
}
private static void setThreadLocalsForRequest(HttpServletRequest req) {
instance.setRequestInfo(req);
}
// ----------------------------------------------------------------------
// Setup class
// ----------------------------------------------------------------------
public static class Setup implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
StartupStatus ss = StartupStatus.getBean(ctx);
try {
instance = createConfiguration(ctx);
ss.info(this, "Initialized the Freemarker configuration.");
} catch (Exception e) {
ss.fatal(this,
"Failed to initialize the Freemarker configuration.", e);
}
}
private FreemarkerConfigurationImpl createConfiguration(
ServletContext ctx) throws TemplateModelException {
FreemarkerConfigurationImpl c = new FreemarkerConfigurationImpl();
setMiscellaneousProperties(c);
setSharedVariables(c, ctx);
addDirectives(c);
addMethods(c);
return c;
}
private void setMiscellaneousProperties(FreemarkerConfigurationImpl c) {
/*
* Lengthen the cache time.
*/
c.setTemplateUpdateDelay(60); // increase from the 5-second default
/*
* On most template models, hide the getters and setters that take
* arguments.
*/
BeansWrapper wrapper = new DefaultObjectWrapper();
wrapper.setExposureLevel(BeansWrapper.EXPOSE_PROPERTIES_ONLY);
c.setObjectWrapper(wrapper);
/*
* Set a default Locale, but expect it to be overridden by the
* request.
*/
c.setLocale(java.util.Locale.US);
/*
* This is how we like our date and time strings to look.
*/
String dateFormat = "M/d/yyyy";
c.setDateFormat(dateFormat);
String timeFormat = "h:mm a";
c.setTimeFormat(timeFormat);
c.setDateTimeFormat(dateFormat + " " + timeFormat);
/*
* What character set is used when escaping special characters in a
* URL?
*/
try {
c.setSetting("url_escaping_charset", "ISO-8859-1");
} catch (TemplateException e) {
log.error("Error setting value for url_escaping_charset.");
}
}
private void setSharedVariables(FreemarkerConfigurationImpl c,
ServletContext ctx) throws TemplateModelException {
c.setSharedVariable("version", getRevisionInfo(ctx));
/*
* Put in edit configuration constants - useful for freemarker
* templates/editing
*/
c.setSharedVariable("editConfigurationConstants",
EditConfigurationConstants.exportConstants());
}
private void addDirectives(FreemarkerConfigurationImpl c) {
c.setSharedVariable("dump", new freemarker.ext.dump.DumpDirective());
c.setSharedVariable("dumpAll",
new freemarker.ext.dump.DumpAllDirective());
c.setSharedVariable("help", new freemarker.ext.dump.HelpDirective());
c.setSharedVariable("shortView", new IndividualShortViewDirective());
c.setSharedVariable("url", new UrlDirective());
c.setSharedVariable("widget", new WidgetDirective());
}
private void addMethods(FreemarkerConfigurationImpl c) {
c.setSharedVariable("profileUrl", new IndividualProfileUrlMethod());
c.setSharedVariable("localName", new IndividualLocalNameMethod());
c.setSharedVariable("placeholderImageUrl",
new IndividualPlaceholderImageUrlMethod());
c.setSharedVariable("i18n", new I18nMethodModel());
}
private Map<String, Object> getRevisionInfo(ServletContext ctx) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("label", RevisionInfoBean.getBean(ctx).getReleaseLabel());
map.put("moreInfoUrl", UrlBuilder.getUrl("/revisionInfo"));
return map;
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
instance = null;
}
}
}

View file

@ -0,0 +1,309 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.freemarker.config;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetterUtils;
import freemarker.core.Environment;
import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.SimpleScalar;
import freemarker.template.Template;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.utility.DeepUnwrap;
/**
* Extend the Freemarker Configuration class to include some information that is
* particular to the current request.
*
* Takes advantage of the fact that each servlet request runs in a separate
* thread. Stores the request-based information in a ThreadLocal. Override any
* methods that should return that information instead of (or in addition to)
* the common info.
*
* Only the getters are overridden, not the setters. So if you call
* setAllSharedVariables(), for example, it will have no effect on the
* request-based information.
*/
public class FreemarkerConfigurationImpl extends Configuration {
private static final Log log = LogFactory
.getLog(FreemarkerConfigurationImpl.class);
private final ThreadLocal<RequestBasedInformation> rbiRef = new ThreadLocal<>();
void setRequestInfo(HttpServletRequest req) {
rbiRef.set(new RequestBasedInformation(req, this));
}
@Override
public Object getCustomAttribute(String name) {
Map<String, Object> attribs = rbiRef.get().getCustomAttributes();
if (attribs.containsKey(name)) {
return attribs.get(name);
} else {
return super.getCustomAttribute(name);
}
}
@Override
public String[] getCustomAttributeNames() {
Set<String> rbiNames = rbiRef.get().getCustomAttributes().keySet();
return joinNames(rbiNames, super.getCustomAttributeNames());
}
@Override
public TemplateModel getSharedVariable(String name) {
Map<String, TemplateModel> vars = rbiRef.get().getSharedVariables();
if (vars.containsKey(name)) {
return vars.get(name);
} else {
return super.getSharedVariable(name);
}
}
@Override
public Set<String> getSharedVariableNames() {
Set<String> rbiNames = rbiRef.get().getSharedVariables().keySet();
@SuppressWarnings("unchecked")
Set<String> superNames = super.getSharedVariableNames();
Set<String> allNames = new HashSet<>(superNames);
allNames.addAll(rbiNames);
return allNames;
}
@Override
public Locale getLocale() {
return rbiRef.get().getReq().getLocale();
}
private String[] joinNames(Set<String> nameSet, String[] nameArray) {
Set<String> allNames = new HashSet<>(nameSet);
for (String n : nameArray) {
allNames.add(n);
}
return (String[]) allNames.toArray();
}
// ----------------------------------------------------------------------
// Apply DataGetters to templates when loading.
//
// TODO Clean this up VIVO-249
// ----------------------------------------------------------------------
/**
* Override getTemplate(), so we can apply DataGetters to all included
* templates.
*
* This won't work for top-level Templates, since the Environment hasn't
* been created yet. When TemplateProcessingHelper creates the Environment,
* it must call retrieveAndRunDataGetters() for the top-level Template.
*/
@Override
public Template getTemplate(String name, Locale locale, String encoding,
boolean parse) throws IOException {
Template template = super.getTemplate(name, locale, encoding, parse);
if (template == null) {
log.debug("Template '" + name + "' not found for locale '" + locale
+ "'.");
return template;
}
Environment env = getEnvironment();
if (env == null) {
log.debug("Not fetching data getters for template '"
+ template.getName() + "'. No environment.");
return template;
}
retrieveAndRunDataGetters(env, template.getName());
return template;
}
/**
* Find the DataGetters for this template, and apply them to the Freemarker
* environment.
*/
public static void retrieveAndRunDataGetters(Environment env,
String templateName) {
HttpServletRequest req = (HttpServletRequest) env
.getCustomAttribute("request");
VitroRequest vreq = new VitroRequest(req);
if (dataGettersAlreadyApplied(env, templateName)) {
log.debug("DataGetters for '" + templateName
+ "' have already been applied");
return;
}
try {
List<DataGetter> dgList = DataGetterUtils
.getDataGettersForTemplate(vreq, vreq.getDisplayModel(),
templateName);
log.debug("Retrieved " + dgList.size()
+ " data getters for template '" + templateName + "'");
@SuppressWarnings("unchecked")
Map<String, Object> dataMap = (Map<String, Object>) DeepUnwrap
.permissiveUnwrap(env.getDataModel());
for (DataGetter dg : dgList) {
applyDataGetter(dg, env, dataMap);
}
} catch (Exception e) {
log.warn(e, e);
}
}
/**
* Have the DataGetters for this template already been applied to this
* environment? If not, record that they are being applied now.
*/
@SuppressWarnings("unchecked")
private static boolean dataGettersAlreadyApplied(Environment env,
String templateName) {
Set<String> names;
Object o = env.getCustomAttribute("dataGettersApplied");
if (o instanceof Set) {
names = (Set<String>) o;
} else {
names = new HashSet<String>();
}
boolean added = names.add(templateName);
if (added) {
env.setCustomAttribute("dataGettersApplied", names);
return false;
} else {
return true;
}
}
/**
* Get the data from a DataGetter, and store it in global variables in the
* Freemarker environment.
*/
private static void applyDataGetter(DataGetter dg, Environment env,
Map<String, Object> dataMap) throws TemplateModelException {
Map<String, Object> moreData = dg.getData(dataMap);
ObjectWrapper wrapper = env.getObjectWrapper();
if (moreData != null) {
for (String key : moreData.keySet()) {
Object value = moreData.get(key);
env.setGlobalVariable(key, wrapper.wrap(value));
log.debug("Stored in environment: '" + key + "' = '" + value
+ "'");
}
}
}
// ----------------------------------------------------------------------
// Helper class
// ----------------------------------------------------------------------
/**
* Holds the request-based information. Currently, it's shared variables, a
* custom attribute, and the locale. In the future, it could be more.
*/
private static class RequestBasedInformation {
private final HttpServletRequest req;
private final Configuration c;
private final Map<String, Object> customAttributes = new HashMap<>();
private final Map<String, TemplateModel> sharedVariables = new HashMap<>();
public RequestBasedInformation(HttpServletRequest req, Configuration c) {
this.req = req;
this.c = c;
setSharedVariables(req);
setCustomAttributes(req);
}
public HttpServletRequest getReq() {
return req;
}
public Map<String, Object> getCustomAttributes() {
return customAttributes;
}
public Map<String, TemplateModel> getSharedVariables() {
return sharedVariables;
}
private void setSharedVariables(HttpServletRequest req) {
ServletContext ctx = req.getSession().getServletContext();
VitroRequest vreq = new VitroRequest(req);
ApplicationBean appBean = vreq.getAppBean();
String siteName = appBean.getApplicationName();
String tagLine = appBean.getShortHand();
String themeDir = appBean.getThemeDir().replaceAll("/$", "");
String currentTheme = themeDir
.substring(themeDir.lastIndexOf('/') + 1);
Map<String, String> siteUrls = getSiteUrls(ctx, themeDir);
sharedVariables.put("siteName", wrap(siteName));
sharedVariables.put("themeDir", wrap(themeDir));
sharedVariables.put("currentTheme", wrap(currentTheme));
sharedVariables.put("siteTagline", wrap(tagLine));
sharedVariables.put("urls", wrap(siteUrls));
}
private Map<String, String> getSiteUrls(ServletContext ctx,
String themeDir) {
Map<String, String> urls = new HashMap<String, String>();
// Templates use this to construct urls.
urls.put("base", ctx.getContextPath());
urls.put("home", UrlBuilder.getHomeUrl());
urls.put("about", UrlBuilder.getUrl(Route.ABOUT));
urls.put("search", UrlBuilder.getUrl(Route.SEARCH));
urls.put("termsOfUse", UrlBuilder.getUrl(Route.TERMS_OF_USE));
urls.put("login", UrlBuilder.getLoginUrl());
urls.put("logout", UrlBuilder.getLogoutUrl());
urls.put("siteAdmin", UrlBuilder.getUrl(Route.SITE_ADMIN));
urls.put("themeImages", UrlBuilder.getUrl(themeDir + "/images"));
urls.put("images", UrlBuilder.getUrl("/images"));
urls.put("theme", UrlBuilder.getUrl(themeDir));
urls.put("index", UrlBuilder.getUrl("/browse"));
return urls;
}
private TemplateModel wrap(Object o) {
try {
return c.getObjectWrapper().wrap(o);
} catch (TemplateModelException e) {
log.error("Failed to wrap this "
+ "for the Freemarker configuration: " + o, e);
return new SimpleScalar(String.valueOf(o));
}
}
private void setCustomAttributes(HttpServletRequest req) {
customAttributes.put("request", req);
}
}
}

View file

@ -33,7 +33,7 @@ import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup;
/**
* AutocompleteController generates autocomplete content
* via the search index.
* via the search index.
*/
public class AutocompleteController extends VitroAjaxController {
@ -49,7 +49,7 @@ public class AutocompleteController extends VitroAjaxController {
String NORESULT_MSG = "";
private static final int DEFAULT_MAX_HIT_COUNT = 1000;
private static final int DEFAULT_MAX_HIT_COUNT = 1000;
public static final int MAX_QUERY_LENGTH = 500;
@ -57,50 +57,50 @@ public class AutocompleteController extends VitroAjaxController {
protected Actions requiredActions(VitroRequest vreq) {
return SimplePermission.USE_BASIC_AJAX_CONTROLLERS.ACTIONS;
}
@Override
protected void doRequest(VitroRequest vreq, HttpServletResponse response)
throws IOException, ServletException {
try {
String qtxt = vreq.getParameter(PARAM_QUERY);
SolrQuery query = getQuery(qtxt, vreq);
SolrQuery query = getQuery(qtxt, vreq);
if (query == null ) {
log.debug("query for '" + qtxt +"' is null.");
doNoQuery(response);
return;
}
log.debug("query for '" + qtxt +"' is " + query.toString());
SolrServer solr = SolrSetup.getSolrServer(getServletContext());
QueryResponse queryResponse = solr.query(query);
if ( queryResponse == null) {
log.error("Query response for a search was null");
log.error("Query response for a search was null");
doNoSearchResults(response);
return;
}
SolrDocumentList docs = queryResponse.getResults();
if ( docs == null) {
log.error("Docs for a search was null");
log.error("Docs for a search was null");
doNoSearchResults(response);
return;
}
long hitCount = docs.getNumFound();
log.debug("Total number of hits = " + hitCount);
if ( hitCount < 1 ) {
if ( hitCount < 1 ) {
doNoSearchResults(response);
return;
}
}
List<SearchResult> results = new ArrayList<SearchResult>();
for (SolrDocument doc : docs) {
try {
try {
String uri = doc.get(VitroSearchTermNames.URI).toString();
// RY 7/1/2011
// Comment was: VitroSearchTermNames.NAME_RAW is a multivalued field, so doc.get() returns a list.
@ -116,61 +116,71 @@ public class AutocompleteController extends VitroAjaxController {
} else {
name = (String) nameRaw;
}
SearchResult result = new SearchResult(name, uri);
Object mostSpecificType = doc.get(VitroSearchTermNames.MOST_SPECIFIC_TYPE_URIS);
String mst = null;
if (mostSpecificType instanceof List<?>) {
@SuppressWarnings("unchecked")
List<String> mstList = (List<String>) mostSpecificType;
mst = mstList.get(0);
} else {
mst = (String) mostSpecificType;
}
SearchResult result = new SearchResult(name, uri, mst);
results.add(result);
log.debug("results = " + results.toString());
} catch(Exception e){
log.error("problem getting usable individuals from search " +
"hits" + e.getMessage());
}
}
}
Collections.sort(results);
JSONArray jsonArray = new JSONArray();
for (SearchResult result : results) {
jsonArray.put(result.toMap());
}
response.getWriter().write(jsonArray.toString());
} catch (Throwable e) {
log.error(e, e);
log.error(e, e);
doSearchError(response);
}
}
private SolrQuery getQuery(String queryStr, VitroRequest vreq) {
if ( queryStr == null) {
log.error("There was no parameter '"+ PARAM_QUERY
+"' in the request.");
log.error("There was no parameter '"+ PARAM_QUERY
+"' in the request.");
return null;
} else if( queryStr.length() > MAX_QUERY_LENGTH ) {
log.debug("The search was too long. The maximum " +
"query length is " + MAX_QUERY_LENGTH );
return null;
}
SolrQuery query = new SolrQuery();
query.setStart(0)
.setRows(DEFAULT_MAX_HIT_COUNT);
.setRows(DEFAULT_MAX_HIT_COUNT);
setNameQuery(query, queryStr, vreq);
// Filter by type
String typeParam = (String) vreq.getParameter(PARAM_RDFTYPE);
String multipleTypesParam = (String) vreq.getParameter(PARAM_MULTIPLE_RDFTYPE);
if (typeParam != null) {
addFilterQuery(query, typeParam, multipleTypesParam);
}
query.setFields(VitroSearchTermNames.NAME_RAW, VitroSearchTermNames.URI); // fields to retrieve
}
query.setFields(VitroSearchTermNames.NAME_RAW, VitroSearchTermNames.URI, VitroSearchTermNames.MOST_SPECIFIC_TYPE_URIS); // fields to retrieve
// Can't sort on multivalued field, so we sort the results in Java when we get them.
// query.setSortField(VitroSearchTermNames.NAME_LOWERCASE, SolrQuery.ORDER.asc);
return query;
}
private void addFilterQuery(SolrQuery query, String typeParam, String multipleTypesParam) {
if(multipleTypesParam == null || multipleTypesParam.equals("null") || multipleTypesParam.isEmpty()) {
//Single type parameter, process as usual
@ -181,15 +191,13 @@ public class AutocompleteController extends VitroAjaxController {
int len = typeParams.length;
int i;
List<String> filterQueries = new ArrayList<String>();
for(i = 0; i < len; i++) {
filterQueries.add(VitroSearchTermNames.RDFTYPE + ":\"" + typeParams[i] + "\" ");
}
String filterQuery = StringUtils.join(filterQueries, " OR ");
query.addFilterQuery(filterQuery);
}
}
private void setNameQuery(SolrQuery query, String queryStr, HttpServletRequest request) {
@ -197,10 +205,9 @@ public class AutocompleteController extends VitroAjaxController {
if (StringUtils.isBlank(queryStr)) {
log.error("No query string");
}
String tokenizeParam = (String) request.getParameter("tokenize");
String tokenizeParam = (String) request.getParameter("tokenize");
boolean tokenize = "true".equals(tokenizeParam);
// Note: Stemming is only relevant if we are tokenizing: an untokenized name
// query will not be stemmed. So we don't look at the stem parameter until we get to
// setTokenizedNameQuery().
@ -210,43 +217,43 @@ public class AutocompleteController extends VitroAjaxController {
setUntokenizedNameQuery(query, queryStr);
}
}
private void setTokenizedNameQuery(SolrQuery query, String queryStr, HttpServletRequest request) {
/* We currently have no use case for a tokenized, unstemmed autocomplete search field, so the option
* has been disabled. If needed in the future, will need to add a new field and field type which
* is like AC_NAME_STEMMED but doesn't include the stemmer.
String stemParam = (String) request.getParameter("stem");
String stemParam = (String) request.getParameter("stem");
boolean stem = "true".equals(stemParam);
if (stem) {
String acTermName = VitroSearchTermNames.AC_NAME_STEMMED;
String nonAcTermName = VitroSearchTermNames.NAME_STEMMED;
} else {
String acTermName = VitroSearchTermNames.AC_NAME_UNSTEMMED;
String nonAcTermName = VitroSearchTermNames.NAME_UNSTEMMED;
String nonAcTermName = VitroSearchTermNames.NAME_UNSTEMMED;
}
*/
String acTermName = VitroSearchTermNames.AC_NAME_STEMMED;
String nonAcTermName = VitroSearchTermNames.NAME_STEMMED;
String acQueryStr;
if (queryStr.endsWith(" ")) {
acQueryStr = makeTermQuery(nonAcTermName, queryStr, true);
acQueryStr = makeTermQuery(nonAcTermName, queryStr, true);
} else {
int indexOfLastWord = queryStr.lastIndexOf(" ") + 1;
List<String> terms = new ArrayList<String>(2);
String allButLastWord = queryStr.substring(0, indexOfLastWord);
if (StringUtils.isNotBlank(allButLastWord)) {
terms.add(makeTermQuery(nonAcTermName, allButLastWord, true));
}
String lastWord = queryStr.substring(indexOfLastWord);
if (StringUtils.isNotBlank(lastWord)) {
terms.add(makeTermQuery(acTermName, lastWord, false));
}
acQueryStr = StringUtils.join(terms, " AND ");
}
@ -255,26 +262,26 @@ public class AutocompleteController extends VitroAjaxController {
}
private void setUntokenizedNameQuery(SolrQuery query, String queryStr) {
queryStr = queryStr.trim();
private void setUntokenizedNameQuery(SolrQuery query, String queryStr) {
queryStr = queryStr.trim();
queryStr = makeTermQuery(VitroSearchTermNames.AC_NAME_UNTOKENIZED, queryStr, true);
query.setQuery(queryStr);
}
private String makeTermQuery(String term, String queryStr, boolean mayContainWhitespace) {
if (mayContainWhitespace) {
queryStr = "\"" + escapeWhitespaceInQueryString(queryStr) + "\"";
}
return term + ":" + queryStr;
}
private String escapeWhitespaceInQueryString(String queryStr) {
// Solr wants whitespace to be escaped with a backslash
return queryStr.replaceAll("\\s+", "\\\\ ");
}
private void doNoQuery(HttpServletResponse response) throws IOException {
// For now, we are not sending an error message back to the client because
// For now, we are not sending an error message back to the client because
// with the default autocomplete configuration it chokes.
doNoSearchResults(response);
}
@ -288,36 +295,46 @@ public class AutocompleteController extends VitroAjaxController {
private void doNoSearchResults(HttpServletResponse response) throws IOException {
response.getWriter().write("[]");
}
public class SearchResult implements Comparable<Object> {
private String label;
private String uri;
SearchResult(String label, String uri) {
private String msType;
SearchResult(String label, String uri, String msType) {
this.label = label;
this.uri = uri;
this.msType = msType;
}
public String getLabel() {
return label;
}
public String getJsonLabel() {
return JSONObject.quote(label);
}
public String getUri() {
return uri;
}
public String getJsonUri() {
return JSONObject.quote(uri);
}
public String getMsType() {
return msType;
}
public String getJsonMsType() {
return JSONObject.quote(msType);
}
Map<String, String> toMap() {
Map<String, String> map = new HashMap<String, String>();
map.put("label", label);
map.put("uri", uri);
map.put("msType", msType);
return map;
}

View file

@ -12,11 +12,8 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.FreemarkerConfigurationLoader;
import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration;
import edu.cornell.mannlib.vitro.webapp.utils.log.LogUtils;
import freemarker.core.Environment;
import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.Template;
@ -53,8 +50,7 @@ public class FreemarkerProcessingServiceImpl implements
throws TemplateProcessingException {
Template template = null;
try {
Configuration config = FreemarkerConfigurationLoader
.getConfig(new VitroRequest(req));
Configuration config = FreemarkerConfiguration.getConfig(req);
template = config.getTemplate(templateName);
} catch (ParseException e) {
log.warn("Failed to parse the template at '" + templateName + "'"
@ -75,18 +71,7 @@ public class FreemarkerProcessingServiceImpl implements
StringWriter writer = new StringWriter();
try {
// Add directives to the map. For some reason, having them in the
// configuration is not enough.
map.putAll(FreemarkerConfiguration.getDirectives());
// Add request and servlet context as custom attributes of the
// environment, so they
// can be used in directives.
Environment env = template.createProcessingEnvironment(map, writer);
env.setCustomAttribute("request", req);
env.setCustomAttribute("context", req.getSession()
.getServletContext());
env.process();
template.process(map, writer);
return writer.toString();
} catch (TemplateException e) {
throw new TemplateProcessingException(

View file

@ -5,7 +5,11 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
@ -31,11 +35,13 @@ import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater;
import edu.cornell.mannlib.vitro.webapp.ontology.update.UpdateSettings;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
* Invokes process to test whether the knowledge base needs any updating
@ -44,21 +50,10 @@ import edu.cornell.mannlib.vitro.webapp.ontology.update.UpdateSettings;
*
*/
public class UpdateKnowledgeBase implements ServletContextListener {
public static final String KBM_REQURIED_AT_STARTUP = "KNOWLEDGE_BASE_MIGRATION_REQUIRED_AT_STARTUP";
private final static Log log = LogFactory.getLog(UpdateKnowledgeBase.class);
private static final String DATA_DIR = "/WEB-INF/ontologies/update/";
private static final String LOG_DIR = "logs/";
private static final String CHANGED_DATA_DIR = "changedData/";
private static final String ASK_QUERY_FILE = DATA_DIR + "askUpdated.sparql";
private static final String SUCCESS_ASSERTIONS_FILE = DATA_DIR + "success.n3";
private static final String SUCCESS_RDF_FORMAT = "N3";
private static final String DIFF_FILE = DATA_DIR + "diff.tab.txt";
private static final String REMOVED_DATA_FILE = DATA_DIR + CHANGED_DATA_DIR + "removedData.n3";
private static final String ADDED_DATA_FILE = DATA_DIR + CHANGED_DATA_DIR + "addedData.n3";
private static final String SPARQL_CONSTRUCT_ADDITIONS_DIR = DATA_DIR + "sparqlConstructs/additions/";
private static final String SPARQL_CONSTRUCT_DELETIONS_DIR = DATA_DIR + "sparqlConstructs/deletions/";
private static final String OLD_TBOX_MODEL_DIR = DATA_DIR + "oldVersion/";
private static final String NEW_TBOX_MODEL_DIR = "/WEB-INF/filegraph/tbox/";
private static final String OLD_TBOX_ANNOTATIONS_DIR = DATA_DIR + "oldAnnotations/";
@ -72,33 +67,15 @@ public class UpdateKnowledgeBase implements ServletContextListener {
private static final String LOADED_STARTUPT_DISPLAYMODEL_DIR = "/WEB-INF/ontologies/app/loadedAtStartup/";
private static final String OLD_DISPLAYMODEL_VIVOLISTVIEW_PATH = DATA_DIR + "oldDisplayModel/vivoListViewConfig.rdf";
@Override
public void contextInitialized(ServletContextEvent sce) {
try {
ServletContext ctx = sce.getServletContext();
// If the DATA_DIR directory doesn't exist no migration check will be done.
// This is a normal situation for Vitro.
File updateDirectory = new File(ctx.getRealPath(DATA_DIR));
if (!updateDirectory.exists()) {
log.debug("Directory " + ctx.getRealPath(DATA_DIR) + " does not exist, no migration check will be attempted.");
return;
}
ServletContext ctx = sce.getServletContext();
StartupStatus ss = StartupStatus.getBean(ctx);
String logFileName = DATA_DIR + LOG_DIR + timestampedFileName("knowledgeBaseUpdate", "log");
String errorLogFileName = DATA_DIR + LOG_DIR + timestampedFileName("knowledgeBaseUpdate.error", "log");
try {
UpdateSettings settings = new UpdateSettings();
settings.setAskUpdatedQueryFile(getAskUpdatedQueryPath(ctx));
settings.setDataDir(ctx.getRealPath(DATA_DIR));
settings.setSparqlConstructAdditionsDir(ctx.getRealPath(SPARQL_CONSTRUCT_ADDITIONS_DIR));
settings.setSparqlConstructDeletionsDir(ctx.getRealPath(SPARQL_CONSTRUCT_DELETIONS_DIR));
settings.setDiffFile(ctx.getRealPath(DIFF_FILE));
settings.setSuccessAssertionsFile(ctx.getRealPath(SUCCESS_ASSERTIONS_FILE));
settings.setSuccessRDFFormat(SUCCESS_RDF_FORMAT);
settings.setLogFile(ctx.getRealPath(logFileName));
settings.setErrorLogFile(ctx.getRealPath(errorLogFileName));
settings.setAddedDataFile(ctx.getRealPath(ADDED_DATA_FILE));
settings.setRemovedDataFile(ctx.getRealPath(REMOVED_DATA_FILE));
putReportingPathsIntoSettings(ctx, settings);
WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory();
settings.setDefaultNamespace(wadf.getDefaultNamespace());
settings.setAssertionOntModelSelector(ModelAccess.on(ctx).getBaseOntModelSelector());
@ -157,21 +134,54 @@ public class UpdateKnowledgeBase implements ServletContextListener {
}
}
} catch (Exception ioe) {
String errMsg = "Exception updating knowledge base " +
"for ontology changes: ";
// Tomcat doesn't always seem to print exceptions thrown from
// context listeners
System.out.println(errMsg);
ioe.printStackTrace();
throw new RuntimeException(errMsg, ioe);
ss.fatal(this, "Exception updating knowledge base for ontology changes: ", ioe);
}
} catch (Throwable t){
log.warn("warning", t);
ss.fatal(this, "Exception updating knowledge base for ontology changes: ", t);
}
} catch (Throwable t) {
t.printStackTrace();
ss.fatal(this, "Exception updating knowledge base for ontology changes: ", t);
}
}
/**
* Create the directories where we will report on the update.
* Put the paths for the directories and files into the settings object.
*/
private void putReportingPathsIntoSettings(ServletContext ctx, UpdateSettings settings) throws IOException {
ConfigurationProperties props = ConfigurationProperties.getBean(ctx);
Path homeDir = Paths.get(props.getProperty("vitro.home"));
Path dataDir = createDirectory(homeDir, "upgrade", "knowledgeBase");
settings.setDataDir(dataDir.toString());
StartupStatus.getBean(ctx).info(this, "Updating knowledge base: reports are in '" + dataDir + "'");
settings.setAskUpdatedQueryFile(dataDir.resolve("askUpdated.sparql").toString());
settings.setDiffFile(dataDir.resolve("diff.tab.txt").toString());
settings.setSuccessAssertionsFile(dataDir.resolve("success.n3").toString());
settings.setSuccessRDFFormat("N3");
settings.setSparqlConstructAdditionsDir(createDirectory(dataDir, "sparqlConstructs", "additions").toString());
settings.setSparqlConstructDeletionsDir(createDirectory(dataDir, "sparqlConstructs", "deletions").toString());
Path changedDir = createDirectory(dataDir, "changedData");
settings.setAddedDataFile(changedDir.resolve("addedData.n3").toString());
settings.setRemovedDataFile(changedDir.resolve("removedData.n3").toString());
Path logDir = createDirectory(dataDir, "logs");
settings.setLogFile(logDir.resolve(timestampedFileName("knowledgeBaseUpdate", "log")).toString());
settings.setErrorLogFile(logDir.resolve(timestampedFileName("knowledgeBaseUpdate.error", "log")).toString());
}
private Path createDirectory(Path parent, String... children) throws IOException {
Path dir = parent;
for (String child : children) {
dir = dir.resolve(child);
}
Files.createDirectories(dir);
return dir;
}
//Multiple changes from 1.4 to 1.5 will occur
//update migration model
@ -473,15 +483,11 @@ public class UpdateKnowledgeBase implements ServletContextListener {
}
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// nothing to do
}
public static String getAskUpdatedQueryPath(ServletContext ctx) {
return ctx.getRealPath(ASK_QUERY_FILE);
}
private static String timestampedFileName(String prefix, String suffix) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-sss");
return prefix + "." + sdf.format(new Date()) + "." + suffix;

View file

@ -190,7 +190,7 @@ public class UpdatePermissionSetUris implements ServletContextListener {
File homeDirectory = new File(homeDirectoryPath);
confirmIsDirectory(homeDirectory);
File upgradeDirectory = createDirectory(homeDirectory, "upgrade");
File upgradeDirectory = createDirectory(homeDirectory, "upgrade/permissions");
String filename = timestampedFilename("UpgradePermissionSetUris",
".txt");
this.file = new File(upgradeDirectory, filename);

View file

@ -1,155 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest;
import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel;
/**
* This will pass these variables to the template:
* classGroupUri: uri of the classgroup associated with this page.
* vClassGroup: a data structure that is the classgroup associated with this page.
*/
public class ClassGroupPageData implements PageDataGetter{
private static final Log log = LogFactory.getLog(ClassGroupPageData.class);
@Override
public Map<String,Object> getData(ServletContext context, VitroRequest vreq, String pageUri, Map<String, Object> page ){
HashMap<String, Object> data = new HashMap<String,Object>();
String classGroupUri = vreq.getWebappDaoFactory().getPageDao().getClassGroupPage(pageUri);
data.put("classGroupUri", classGroupUri);
VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq);
List<VClassGroup> vcgList = vcgc.getGroups();
VClassGroup group = null;
for( VClassGroup vcg : vcgList){
if( vcg.getURI() != null && vcg.getURI().equals(classGroupUri)){
group = vcg;
break;
}
}
if( classGroupUri != null && !classGroupUri.isEmpty() && group == null ){
/*This could be for two reasons: one is that the classgroup doesn't exist
* The other is that there are no individuals in any of the classgroup's classes */
group = vreq.getWebappDaoFactory().getVClassGroupDao().getGroupByURI(classGroupUri);
if( group != null ){
List<VClassGroup> vcgFullList = vreq.getWebappDaoFactory().getVClassGroupDao()
.getPublicGroupsWithVClasses(false, true, false);
for( VClassGroup vcg : vcgFullList ){
if( classGroupUri.equals(vcg.getURI()) ){
group = vcg;
break;
}
}
if( group == null ){
log.error("Cannot get classgroup '" + classGroupUri + "' for page '" + pageUri + "'");
}else{
setAllClassCountsToZero(group);
}
}else{
log.error("classgroup " + classGroupUri + " does not exist in the system");
}
}
log.debug("Retrieved class group " + group.getURI() + " and returning to template");
//if debug enabled, print out the number of entities within each class in the class gorup
if(log.isDebugEnabled()){
List<VClass> groupClasses = group.getVitroClassList();
for(VClass v: groupClasses) {
log.debug("Class " + v.getName() + " - " + v.getURI() + " has " + v.getEntityCount() + " entities");
}
}
data.put("vClassGroup", group); //may put null
//This page level data getters tries to set its own template,
// not all of the data getters need to do this.
data.put("bodyTemplate", "page-classgroup.ftl");
//Also add data service url
//Hardcoding for now, need a more dynamic way of doing this
data.put("dataServiceUrlIndividualsByVClass", this.getDataServiceUrl());
return data;
}
public static VClassGroupTemplateModel getClassGroup(String classGroupUri, ServletContext context, VitroRequest vreq){
VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq);
List<VClassGroup> vcgList = vcgc.getGroups();
VClassGroup group = null;
for( VClassGroup vcg : vcgList){
if( vcg.getURI() != null && vcg.getURI().equals(classGroupUri)){
group = vcg;
break;
}
}
if( classGroupUri != null && !classGroupUri.isEmpty() && group == null ){
/*This could be for two reasons: one is that the classgroup doesn't exist
* The other is that there are no individuals in any of the classgroup's classes */
group = vreq.getWebappDaoFactory().getVClassGroupDao().getGroupByURI(classGroupUri);
if( group != null ){
List<VClassGroup> vcgFullList = vreq.getWebappDaoFactory().getVClassGroupDao()
.getPublicGroupsWithVClasses(false, true, false);
for( VClassGroup vcg : vcgFullList ){
if( classGroupUri.equals(vcg.getURI()) ){
group = vcg;
break;
}
}
if( group == null ){
log.error("Cannot get classgroup '" + classGroupUri + "'");
return null;
}else{
setAllClassCountsToZero(group);
}
}else{
log.error("classgroup " + classGroupUri + " does not exist in the system");
return null;
}
}
return new VClassGroupTemplateModel(group);
}
@Override
public String getType(){
return PageDataGetterUtils.generateDataGetterTypeURI(ClassGroupPageData.class.getName());
}
//Get data servuice
@Override
public String getDataServiceUrl() {
return UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClass=1&vclassId=");
}
/**
* For processing of JSONObject
*/
//Currently empty, TODO: Review requirements
@Override
public JSONObject convertToJSON(Map<String, Object> dataMap, VitroRequest vreq) {
JSONObject rObj = null;
return rObj;
}
protected static void setAllClassCountsToZero(VClassGroup vcg){
for(VClass vc : vcg){
vc.setEntityCount(0);
}
}
}

View file

@ -1,316 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.dao.PageDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest;
import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel;
/**
* This will pass these variables to the template:
* classGroupUri: uri of the classgroup associated with this page.
* vClassGroup: a data structure that is the classgroup associated with this page.
*/
public class IndividualsForClassesDataGetter implements PageDataGetter{
private static final Log log = LogFactory.getLog(IndividualsForClassesDataGetter.class);
protected static String restrictClassesTemplateName = null;
@Override
public Map<String,Object> getData(ServletContext context, VitroRequest vreq, String pageUri, Map<String, Object> page ){
this.setTemplateName();
HashMap<String, Object> data = new HashMap<String,Object>();
//This is the old technique of getting class intersections
PageDao pageDao = vreq.getWebappDaoFactory().getPageDao();
Map<String, Object> classIntersectionsMap = getClassIntersectionsMap(pageDao, pageUri);
try{
List<String> classes = retrieveClasses(context, classIntersectionsMap);
List<String> restrictClasses = retrieveRestrictClasses(context, classIntersectionsMap);
log.debug("Retrieving classes for " + classes.toString() + " and restricting by " + restrictClasses.toString());
processClassesAndRestrictions(vreq, context, data, classes, restrictClasses);
//Also add data service url
//Hardcoding for now, need a more dynamic way of doing this
data.put("dataServiceUrlIndividualsByVClass", this.getDataServiceUrl());
//this is the class group associated with the data getter utilized for display on menu editing, not the custom one created
data.put("classGroupUri", pageDao.getClassGroupPage(pageUri));
} catch(Exception ex) {
log.error("An error occurred retrieving Vclass Intersection individuals", ex);
}
return data;
}
protected void setTemplateName() {
this.restrictClassesTemplateName = "restricted";
}
protected Map<String, Object> getClassIntersectionsMap(PageDao pageDao,
String pageUri) {
// TODO Auto-generated method stub
return pageDao.getClassesAndRestrictionsForPage(pageUri);
}
protected List<String> retrieveClasses(
ServletContext context, Map<String, Object> classIntersectionsMap) {
List<String> restrictClasses = (List<String>) classIntersectionsMap.get("classes");
return restrictClasses;
}
protected List<String> retrieveRestrictClasses(
ServletContext context, Map<String, Object> classIntersectionsMap) {
List<String> restrictClasses = (List<String>) classIntersectionsMap.get("restrictClasses");
return restrictClasses;
}
protected void processClassesAndRestrictions(VitroRequest vreq, ServletContext context,
HashMap<String, Object> data, List<String> classes, List<String> restrictClasses ) {
processClassesForDisplay(vreq, context, data, classes);
processRestrictionClasses(vreq, context, data, restrictClasses);
processIntersections(vreq, context, data);
}
//At this point, data specifices whether or not intersections included
private void processIntersections(VitroRequest vreq,
ServletContext context, HashMap<String, Object> data) {
VClassGroup classesGroup = (VClassGroup) data.get("vClassGroup");
List<VClass> vclassList = classesGroup.getVitroClassList();
List<VClass> restrictClasses = (List<VClass>) data.get("restrictVClasses");
//if there are restrict classes, then update counts
if(restrictClasses.size() > 0) {
log.debug("Restriction classes exist");
List<VClass> newVClassList = new ArrayList<VClass>();
//Iterate through vclasses and get updated counts, iterated and saved in same order as initially included
for(VClass v: vclassList) {
int oldCount = v.getEntityCount();
//Making a copy so as to ensure we don't touch the values in the cache
VClass copyVClass = makeCopyVClass(v);
int count = retrieveCount(vreq, context, v, restrictClasses);
if(oldCount != count) {
log.debug("Old count was " + v.getEntityCount() + " and New count for " + v.getURI() + " is " + count);
copyVClass.setEntityCount(count);
}
newVClassList.add(copyVClass);
}
classesGroup.setVitroClassList(newVClassList);
//TODO: Do we need to do this again or will this already be reset?
data.put("vClassGroup", classesGroup);
}
}
private VClass makeCopyVClass(VClass v) {
VClass copyVClass = new VClass(v.getURI());
copyVClass.setLocalName(copyVClass.getLocalName());
copyVClass.setDisplayRank(v.getDisplayRank());
copyVClass.setName(v.getName());
copyVClass.setNamespace(v.getNamespace());
copyVClass.setEntityCount(v.getEntityCount());
return copyVClass;
}
//update class count based on restrict classes
private int retrieveCount(VitroRequest vreq, ServletContext context, VClass v, List<VClass> restrictClasses) {
//Execute solr query that returns only count of individuals
log.debug("Entity count is " + v.getEntityCount());
List<String> classUris = new ArrayList<String>();
classUris.add(v.getURI());
for(VClass r: restrictClasses) {
classUris.add(r.getURI());
}
long count = PageDataGetterUtils.getIndividualCountForIntersection(vreq, context, classUris);
return new Long(count).intValue();
}
private void processClassesForDisplay(VitroRequest vreq, ServletContext context, HashMap<String, Object> data, List<String> classes) {
VClassGroup classesGroup = new VClassGroup();
classesGroup.setURI("displayClasses");
log.debug("Processing classes that will be displayed");
List<VClass> vClasses = new ArrayList<VClass>();
VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq);
for(String classUri: classes) {
//Retrieve vclass from cache to get the count
VClass vclass = vcgc.getCachedVClass(classUri);
//if not found in cache, possibly due to not being in any class group
if(vclass == null) {
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(classUri);
}
if(vclass != null) {
log.debug("VClass does exist for " + classUri + " and entity count is " + vclass.getEntityCount());
vClasses.add(vclass);
} else {
log.debug("Vclass " + classUri + " does not exist in the cache");
log.error("Error occurred, vclass does not exist for this uri " + classUri);
//Throw exception here
}
}
//Sort these classes
Collections.sort(vClasses);
log.debug("Sorting complete for V Classes");
classesGroup.setVitroClassList(vClasses);
log.debug("Returning vitro class list in data for template");
//Set vclass group
data.put("vClassGroup", classesGroup);
}
private void processRestrictionClasses(VitroRequest vreq, ServletContext context,
HashMap<String, Object> data, List<String> restrictClasses) {
try {
VClassGroup restrictClassesGroup = new VClassGroup();
restrictClassesGroup.setURI("restrictClasses");
List<VClass> restrictVClasses = new ArrayList<VClass>();
List<String> urlEncodedRestrictClasses = new ArrayList<String>();
VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq);
if(restrictClasses.size() > 0) {
//classes for restriction are not displayed so don't need to include their class individual counts
for(String restrictClassUri: restrictClasses) {
//Also uses cache to remain consistent with process classes and also allow
//vclasses to be returned even if switched to display model, although
//uris used within display model editing and not vclass objects
VClass vclass = vcgc.getCachedVClass(restrictClassUri);
//if not found in cache, possibly due to not being in any class group
if(vclass == null) {
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(restrictClassUri);
}
if(vclass != null) {
log.debug("Found restrict class and adding to list " + restrictClassUri);
restrictVClasses.add(vclass);
} else {
log.error("Error occurred, vclass does not exist for this uri " + restrictClassUri);
}
//Assuming utf-8?
urlEncodedRestrictClasses.add(URLEncoder.encode(restrictClassUri, "UTF-8"));
}
restrictClassesGroup.setVitroClassList(restrictVClasses);
restrictClassesGroup.setIndividualCount(restrictVClasses.size());
} else {
}
String[] restrictClassesArray = new String[urlEncodedRestrictClasses.size()];
restrictClassesArray = urlEncodedRestrictClasses.toArray(restrictClassesArray);
//In case just want uris
log.debug("Variable name for including restriction classes " + getRestrictClassesTemplateName());
data.put(getRestrictClassesTemplateName(), StringUtils.join(restrictClassesArray, ","));
data.put("restrictVClasses", restrictVClasses);
//not sure if this is useful
data.put("restrictVClassGroup", restrictClassesGroup);
} catch(Exception ex) {
log.error("An error occurred in processing restriction classes ", ex);
}
}
public static VClassGroupTemplateModel getClassGroup(String classGroupUri, ServletContext context, VitroRequest vreq){
VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq);
List<VClassGroup> vcgList = vcgc.getGroups();
VClassGroup group = null;
for( VClassGroup vcg : vcgList){
if( vcg.getURI() != null && vcg.getURI().equals(classGroupUri)){
group = vcg;
break;
}
}
if( classGroupUri != null && !classGroupUri.isEmpty() && group == null ){
/*This could be for two reasons: one is that the classgroup doesn't exist
* The other is that there are no individuals in any of the classgroup's classes */
group = vreq.getWebappDaoFactory().getVClassGroupDao().getGroupByURI(classGroupUri);
if( group != null ){
List<VClassGroup> vcgFullList = vreq.getWebappDaoFactory().getVClassGroupDao()
.getPublicGroupsWithVClasses(false, true, false);
for( VClassGroup vcg : vcgFullList ){
if( classGroupUri.equals(vcg.getURI()) ){
group = vcg;
break;
}
}
if( group == null ){
log.error("Cannot get classgroup '" + classGroupUri + "'");
return null;
}else{
setAllClassCountsToZero(group);
}
}else{
log.error("classgroup " + classGroupUri + " does not exist in the system");
return null;
}
}
return new VClassGroupTemplateModel(group);
}
@Override
public String getType(){
return PageDataGetterUtils.generateDataGetterTypeURI(IndividualsForClassesDataGetter.class.getName());
}
//Get data servuice
@Override
public String getDataServiceUrl() {
return UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClasses=1&vclassId=");
}
/**
* For processig of JSONObject
*/
@Override
public JSONObject convertToJSON(Map<String, Object> map, VitroRequest vreq) {
JSONObject rObj = PageDataGetterUtils.processVclassResultsJSON(map, vreq, true);
return rObj;
}
protected static void setAllClassCountsToZero(VClassGroup vcg){
for(VClass vc : vcg){
vc.setEntityCount(0);
}
}
protected static String getAlphaParameter(VitroRequest request){
return request.getParameter("alpha");
}
protected static int getPageParameter(VitroRequest request) {
String pageStr = request.getParameter("page");
if( pageStr != null ){
try{
return Integer.parseInt(pageStr);
}catch(NumberFormatException nfe){
log.debug("could not parse page parameter");
return 1;
}
}else{
return 1;
}
}
//Get template parameter
private static String getRestrictClassesTemplateName() {
return restrictClassesTemplateName;
}
}

View file

@ -1,27 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter;
import java.util.Map;
import javax.servlet.ServletContext;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import org.json.JSONObject;
public interface PageDataGetter{
Map<String,Object> getData(ServletContext contect, VitroRequest vreq, String pageUri, Map<String, Object> page );
/** Gets the type that this class applies to */
//This has been changed to return the class name for data getter used in menu management
String getType();
//get data service url based on data getter requirements
//Get data servuice
String getDataServiceUrl();
/**Convert data to JSONObject based on what's required for the data processing**/
JSONObject convertToJSON(Map<String, Object> map, VitroRequest vreq);
}

View file

@ -1,339 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONObject;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.PageRecord;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.json.JsonServlet;
import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache;
public class PageDataGetterUtils {
protected static final String DATA_GETTER_MAP = "pageTypeToDataGetterMap";
private static final Log log = LogFactory.getLog(PageDataGetterUtils.class);
public static Map<String,Object> getDataForPage(String pageUri, VitroRequest vreq, ServletContext context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
//Based on page type get the appropriate data getter
Map<String, Object> page = vreq.getWebappDaoFactory().getPageDao().getPage(pageUri);
Map<String,Object> data = new HashMap<String,Object>();
List<PageDataGetter> dataGetters = getPageDataGetterObjects(vreq, pageUri);
for(PageDataGetter getter: dataGetters) {
try{
Map<String,Object> moreData = null;
moreData = getAdditionalData(pageUri, getter.getType(), page, vreq, getter, context);
if( moreData != null)
data.putAll(moreData);
}catch(Throwable th){
log.error(th,th);
}
}
return data;
}
/**
*
* Convert data to JSON for page uri based on type and related datagetters
* TODO: How to handle different data getters? Will this replace json fields or add to them?
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static JSONObject covertDataToJSONForPage(String pageUri, Map<String, Object> data, VitroRequest vreq, ServletContext context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
//Get PageDataGetter types associated with pageUri
JSONObject rObj = null;
List<PageDataGetter> dataGetters = getPageDataGetterObjects(vreq, pageUri);
for(PageDataGetter getter: dataGetters) {
JSONObject typeObj = null;
try{
typeObj = getter.convertToJSON(data, vreq);
if( typeObj != null) {
//Copy over everything from this type Obj to
//TODO: Review how to handle duplicate keys, etc.
if(rObj != null) {
//For now, just nests as separate entry
rObj.put(getter.getType(), typeObj);
} else {
rObj = typeObj;
}
}
} catch(Throwable th){
log.error(th,th);
}
}
return rObj;
}
public static Map<String,Object> getAdditionalData(
String pageUri, String dataGetterName, Map<String, Object> page, VitroRequest vreq, PageDataGetter getter, ServletContext context) {
if(dataGetterName == null || dataGetterName.isEmpty())
return Collections.emptyMap();
if( getter != null ){
try{
log.debug("Retrieve data for this data getter for " + pageUri);
return getter.getData(context, vreq, pageUri, page);
}catch(Throwable th){
log.error(th,th);
return Collections.emptyMap();
}
} else {
return Collections.emptyMap();
}
}
/***
* For the page, get the actual Data Getters to be employed.
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static List<PageDataGetter> getPageDataGetterObjects(VitroRequest vreq, String pageUri) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
List<PageDataGetter> dataGetterObjects = new ArrayList<PageDataGetter>();
List<String> dataGetterClassNames = vreq.getWebappDaoFactory().getPageDao().getDataGetterClass(pageUri);
if( dataGetterClassNames == null )
return Collections.emptyList();
for(String dgClassName: dataGetterClassNames) {
String className = getClassNameFromUri(dgClassName);
Class<?> clz = Class.forName(className);
if( PageDataGetter.class.isAssignableFrom(clz)){
PageDataGetter pg = (PageDataGetter) clz.newInstance();
dataGetterObjects.add(pg);
}// else skip if class does not implement PageDataGetter
}
return dataGetterObjects;
}
//Class URIs returned include "java:" and to instantiate object need to remove java: portion
public static String getClassNameFromUri(String dataGetterClassUri) {
if( !StringUtils.isEmpty(dataGetterClassUri) && dataGetterClassUri.contains("java:")) {
String[] splitArray = dataGetterClassUri.split("java:");
if(splitArray.length > 1) {
return splitArray[1];
}
}
return dataGetterClassUri;
}
/**
* Get Individual count for Solr query for intersection of multiple classes
*/
public static long getIndividualCountForIntersection(VitroRequest vreq, ServletContext context, List<String> classUris) {
return IndividualListController.getIndividualCount(classUris, vreq.getWebappDaoFactory().getIndividualDao(), context);
}
/**
* Process results related to VClass or vclasses. Handles both single and multiple vclasses being sent.
*/
public static JSONObject processVclassResultsJSON(Map<String, Object> map, VitroRequest vreq, boolean multipleVclasses) {
JSONObject rObj = new JSONObject();
VClass vclass=null;
try {
// Properties from ontologies used by VIVO - should not be in vitro
DataProperty fNameDp = (new DataProperty());
fNameDp.setURI("http://xmlns.com/foaf/0.1/firstName");
DataProperty lNameDp = (new DataProperty());
lNameDp.setURI("http://xmlns.com/foaf/0.1/lastName");
DataProperty preferredTitleDp = (new DataProperty());
preferredTitleDp.setURI("http://vivoweb.org/ontology/core#preferredTitle");
if( log.isDebugEnabled() ){
@SuppressWarnings("unchecked")
Enumeration<String> e = vreq.getParameterNames();
while(e.hasMoreElements()){
String name = e.nextElement();
log.debug("parameter: " + name);
for( String value : vreq.getParameterValues(name) ){
log.debug("value for " + name + ": '" + value + "'");
}
}
}
//need an unfiltered dao to get firstnames and lastnames
WebappDaoFactory fullWdf = vreq.getUnfilteredWebappDaoFactory();
String[] vitroClassIdStr = vreq.getParameterValues("vclassId");
if ( vitroClassIdStr != null && vitroClassIdStr.length > 0){
for(String vclassId: vitroClassIdStr) {
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassId);
if (vclass == null) {
log.error("Couldn't retrieve vclass ");
throw new Exception ("Class " + vclassId + " not found");
}
}
}else{
log.error("parameter vclassId URI parameter expected ");
throw new Exception("parameter vclassId URI parameter expected ");
}
List<String> vclassIds = Arrays.asList(vitroClassIdStr);
//if single vclass expected, then include vclass. This relates to what the expected behavior is, not size of list
if(!multipleVclasses) {
//currently used for ClassGroupPage
rObj.put("vclass",
new JSONObject().put("URI",vclass.getURI())
.put("name",vclass.getName()));
} else {
//For now, utilize very last VClass (assume that that is the one to be employed)
//TODO: Find more general way of dealing with this
//put multiple ones in?
if(vclassIds.size() > 0) {
int numberVClasses = vclassIds.size();
vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vclassIds.get(numberVClasses - 1));
rObj.put("vclass", new JSONObject().put("URI",vclass.getURI())
.put("name",vclass.getName()));
}
// rObj.put("vclasses", new JSONObject().put("URIs",vitroClassIdStr)
// .put("name",vclass.getName()));
}
if (vclass != null) {
rObj.put("totalCount", map.get("totalCount"));
rObj.put("alpha", map.get("alpha"));
List<Individual> inds = (List<Individual>)map.get("entities");
log.debug("Number of individuals returned from request: " + inds.size());
JSONArray jInds = new JSONArray();
for(Individual ind : inds ){
JSONObject jo = new JSONObject();
jo.put("URI", ind.getURI());
jo.put("label",ind.getRdfsLabel());
jo.put("name",ind.getName());
jo.put("thumbUrl", ind.getThumbUrl());
jo.put("imageUrl", ind.getImageUrl());
jo.put("profileUrl", UrlBuilder.getIndividualProfileUrl(ind, vreq));
jo.put("mostSpecificTypes", JsonServlet.getMostSpecificTypes(ind,fullWdf));
jo.put("preferredTitle", JsonServlet.getDataPropertyValue(ind, preferredTitleDp, fullWdf));
jInds.put(jo);
}
rObj.put("individuals", jInds);
JSONArray wpages = new JSONArray();
//Made sure that PageRecord here is SolrIndividualListController not IndividualListController
List<PageRecord> pages = (List<PageRecord>)map.get("pages");
for( PageRecord pr: pages ){
JSONObject p = new JSONObject();
p.put("text", pr.text);
p.put("param", pr.param);
p.put("index", pr.index);
wpages.put( p );
}
rObj.put("pages",wpages);
JSONArray jletters = new JSONArray();
List<String> letters = Controllers.getLetters();
for( String s : letters){
JSONObject jo = new JSONObject();
jo.put("text", s);
jo.put("param", "alpha=" + URLEncoder.encode(s, "UTF-8"));
jletters.put( jo );
}
rObj.put("letters", jletters);
}
} catch(Exception ex) {
log.error("Error occurred in processing JSON object", ex);
}
return rObj;
}
/*
* Copied from JSONServlet as expect this to be related to VitroClassGroup
*/
public static JSONObject processVClassGroupJSON(VitroRequest vreq, ServletContext context, VClassGroup vcg) {
JSONObject map = new JSONObject();
try {
ArrayList<JSONObject> classes = new ArrayList<JSONObject>(vcg.size());
for( VClass vc : vcg){
JSONObject vcObj = new JSONObject();
vcObj.put("name", vc.getName());
vcObj.put("URI", vc.getURI());
vcObj.put("entityCount", vc.getEntityCount());
classes.add(vcObj);
}
map.put("classes", classes);
map.put("classGroupName", vcg.getPublicName());
map.put("classGroupUri", vcg.getURI());
} catch(Exception ex) {
log.error("Error occurred in processing VClass group ", ex);
}
return map;
}
//Get All VClass Groups information
//Used within menu management and processing
//TODO: Check if more appropriate location possible
public static List<HashMap<String, String>> getClassGroups(HttpServletRequest req) {
//Wanted this to be
VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(req);
List<VClassGroup> vcgList = vcgc.getGroups();
//For now encoding as hashmap with label and URI as trying to retrieve class group
//results in errors for some reason
List<HashMap<String, String>> classGroups = new ArrayList<HashMap<String, String>>();
for(VClassGroup vcg: vcgList) {
HashMap<String, String> hs = new HashMap<String, String>();
hs.put("publicName", vcg.getPublicName());
hs.put("URI", vcg.getURI());
classGroups.add(hs);
}
return classGroups;
}
//Return data getter type to be employed in display model
public static String generateDataGetterTypeURI(String dataGetterClassName) {
return "java:" + dataGetterClassName;
}
//TODO: Check whether this needs to be put here or elsewhere, as this is data getter specific
//with respect to class groups
//Need to use VClassGroupCache to retrieve class group information - this is the information returned from "for class group"
public static void getClassGroupForDataGetter(HttpServletRequest req, Map<String, Object> pageData, Map<String, Object> templateData) {
//Get the class group from VClassGroup, this is the same as the class group for the class group page data getter
//and the associated class group (not custom) for individuals datagetter
String classGroupUri = (String) pageData.get("classGroupUri");
VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(req);
VClassGroup group = vcgc.getGroup(classGroupUri);
templateData.put("classGroup", group);
templateData.put("associatedPage", group.getPublicName());
templateData.put("associatedPageURI", group.getURI());
}
}

View file

@ -77,10 +77,10 @@ public class IndividualShortViewDirective extends BaseTemplateDirectiveModel {
private void renderShortView(Individual individual,
ShortViewContext svContext) {
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);
if (svs == null) {
log.warn("ShortViewService was not initialized properly.");
@ -88,7 +88,7 @@ public class IndividualShortViewDirective extends BaseTemplateDirectiveModel {
}
TemplateAndSupplementalData svInfo = svs.getShortViewInfo(individual,
svContext, vreq);
svContext, new VitroRequest(request));
ObjectWrapper objectWrapper = env.getConfiguration().getObjectWrapper();

View file

@ -5,8 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
@ -21,13 +19,12 @@ import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfigurationLoader;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException;
import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.DataPropertyListConfig;
import freemarker.cache.TemplateLoader;
@ -136,7 +133,7 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
}
protected TemplateLoader getFreemarkerTemplateLoader() {
return FreemarkerConfigurationLoader.getConfig(vreq).getTemplateLoader();
return FreemarkerConfiguration.getConfig(vreq).getTemplateLoader();
}
@Override

View file

@ -22,12 +22,12 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfigurationLoader;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.PropertyListConfig;
import freemarker.cache.TemplateLoader;
@ -152,7 +152,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
* This will do for now.
*/
protected TemplateLoader getFreemarkerTemplateLoader() {
return FreemarkerConfigurationLoader.getConfig(vreq).getTemplateLoader();
return FreemarkerConfiguration.getConfig(vreq).getTemplateLoader();
}
protected List<Map<String, String>> getStatementData() {

View file

@ -10,7 +10,6 @@ import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
@ -57,7 +56,7 @@ public abstract class Widget {
public String doMarkup(Environment env, Map params) {
HttpServletRequest request = (HttpServletRequest) env.getCustomAttribute("request");
ServletContext context = (ServletContext) env.getCustomAttribute("context");
ServletContext context = request.getSession().getServletContext();
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
// if it's already there or else add it. Leave this for later.
Template template = new Template("widget", new StringReader(templateString), env.getConfiguration());
// 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();
template.process(map, out);
} catch (Exception e) {
log.error("Could not process widget " + widgetName, e);
}