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

@ -774,6 +774,39 @@
<p>
to build Vitro and deploy to Tomcat's webapps directory.
</p>
<p>
The build script may run for as much as five minutes,
and creates more than 100 lines of output.
The process comprises several steps:
<ul>
<li>collecting the source files from the distribution directory,</li>
<li>compiling the Java source code,</li>
<li>compiling and running unit tests,</li>
<li>preparing the Solr search engine,</li>
<li>deploying Vitro and Solr to Tomcat.</li>
</ul>
</p>
<p>
The output of the build may include a variety of warning messages.
The Java compiler may warn of code that is outdated.
Unit tests may produce warning messages,
and some tests may be ignored if they do not produce consistent results.
</p>
<table align="center"><tr><td>
BUILD SUCCESSFUL<br>Total time: 1 minute 49 seconds
</td></tr></table>
<p>
If the output ends with a success message, the build was successful.
Proceed to the next step.
</p>
<table align="center"><tr><td>
BUILD FAILED<br>Total time: 35 seconds
</td></tr></table>
<p>
If the output ends with a failure message, the build has failed.
Find the cause of the failure, fix the problem, and run the script again.
</p>
<h3 id="tomcat_settings">VII. Configure Tomcat</h3>
<h4>Set JVM parameters</h4>
<p>

View file

@ -188,13 +188,6 @@
<!-- Copy the build.properties file to the resources directory. -->
<copy todir="${main.resources.dir}" file="${build.properties.file}" />
<!-- If there is a runtime.properties file in the same directory as build.properties, copy that too. -->
<dirname file="${build.properties.file}" property="runtime.properties.dir"/>
<copy todir="${main.resources.dir}" >
<fileset dir="${runtime.properties.dir}" >
<filename name="runtime.properties" />
</fileset>
</copy>
<!-- copy any xml files from source tree to the war directory -->
<copy todir="${main.compiled.dir}">

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);
}

View file

@ -23,7 +23,6 @@ import java.util.Set;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import javax.media.jai.operator.StreamDescriptor;
import javax.media.jai.widget.ImageCanvas;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
@ -107,7 +106,7 @@ public class ImageUploaderThumbnailerTester_2 extends Frame {
JPanel p = new JPanel();
p.setLayout(new BorderLayout());
p.add("South", l);
p.add("Center", new ImageCanvas(image));
p.add("Center", new javax.media.jai.widget.ImageCanvas(image));
p.setBackground(new Color(0xFFFFFF));
p.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

View file

@ -192,6 +192,7 @@ public class JsonServletTest extends AbstractTestClass {
public void individualsByClassNoIndividuals() throws ServletException,
IOException {
setLoggerLevel(JsonServlet.class, Level.FATAL);
setLoggerLevel(ModelAccess.class, Level.ERROR);
String vclassId = "http://myVclass";
vcDao.setVClass(vclassId, new VClass(vclassId));
req.addParameter(GET_SOLR_INDIVIDUALS_BY_VCLASS, "true");

View file

@ -67,15 +67,6 @@ public class DataGetterUtilsTest extends AbstractTestClass{
}
@Test
public void testNonPageDataGetter() throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException{
DataGetter dg = DataGetterUtils.dataGetterForURI(vreq, displayModel,dataGetterX);
Assert.assertNull(dg);
List<DataGetter> dgList =
DataGetterUtils.getDataGettersForPage(vreq, displayModel, pageX);
Assert.assertNotNull(dgList);
Assert.assertTrue("List should be, it was not", dgList.size() == 0);
}
}

View file

@ -20,14 +20,5 @@ display:query1data
display:saveToVar "people" .
### test of what happens with a PageDataGetter instead of a DataGetter ###
display:pageX
a display:Page ;
display:title "A PageDataGetter, not a DataGetter" ;
display:urlMapping "/query2" ;
display:hasDataGetter display:pageDataGetterX .
display:pageDataGetterX
a <java:edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.ClassGroupPageData> .

View file

@ -1,68 +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.io.InputStream;
import java.util.List;
import org.apache.log4j.Level;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import stubs.javax.servlet.http.HttpServletRequestStub;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.impl.RDFDefaultErrorHandler;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.SimpleOntModelSelector;
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
public class PageDataGetterUtilsTest extends AbstractTestClass{
OntModel displayModel;
WebappDaoFactory wdf;
String pageURI = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#pageX";
String pageURI_2 = "http://vitro.mannlib.cornell.edu/ontologies/display/1.1#SPARQLPage";
@Before
public void setUp() throws Exception {
// Suppress error logging.
setLoggerLevel(RDFDefaultErrorHandler.class, Level.OFF);
OntModel model = ModelFactory.createOntologyModel( OntModelSpec.OWL_MEM);
InputStream in = PageDataGetterUtilsTest.class.getResourceAsStream("resources/pageDataGetter.n3");
model.read(in,"","N3");
displayModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM,model);
SimpleOntModelSelector sos = new SimpleOntModelSelector( ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM));
sos.setDisplayModel(displayModel);
wdf = new WebappDaoFactoryJena(sos);
}
@Test
public void testGetPageDataGetterObjects() throws Exception{
VitroRequest vreq = new VitroRequest( new HttpServletRequestStub() );
ModelAccess.on(vreq).setWebappDaoFactory(wdf);
List<PageDataGetter> pdgList = PageDataGetterUtils.getPageDataGetterObjects(vreq, pageURI);
Assert.assertNotNull(pdgList);
Assert.assertTrue("should have one PageDataGetter", pdgList.size() == 1);
}
@Test
public void testGetNonPageDataGetterObjects() throws Exception{
VitroRequest vreq = new VitroRequest( new HttpServletRequestStub() );
ModelAccess.on(vreq).setWebappDaoFactory(wdf);
List<PageDataGetter> pdgList = PageDataGetterUtils.getPageDataGetterObjects(vreq, pageURI_2);
Assert.assertNotNull(pdgList);
Assert.assertTrue("should have no PageDataGetters", pdgList.size() == 0);
}
}

View file

@ -1,30 +0,0 @@
# $This file is distributed under the terms of the license in /doc/license.txt$
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix display: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix core: <http://vivoweb.org/ontology/core#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
### This file is for the test PageDataGetterUtilsTest.java
display:SPARQLPage
a display:Page ;
display:title "TestQuery" ;
display:urlMapping "/query1" ;
display:hasDataGetter display:query1data .
display:query1data
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlQueryDataGetter>;
display:query "SELECT * WHERE { ?uri a <http://xmlns.com/foaf/0.1/Person> } " ;
display:saveToVar "people" .
display:pageX
a display:Page ;
display:title "A PageDataGetter, not a DataGetter" ;
display:urlMapping "/query2" ;
display:hasDataGetter display:pageDataGetterX .
display:pageDataGetterX
a <java:edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.ClassGroupPageData> .

View file

@ -200,6 +200,7 @@ public class ServletContextStub implements ServletContext {
}
@Override
@Deprecated
public Servlet getServlet(String arg0) throws ServletException {
throw new RuntimeException(
"ServletContextStub.getServlet() not implemented.");
@ -213,6 +214,7 @@ public class ServletContextStub implements ServletContext {
@Override
@SuppressWarnings("rawtypes")
@Deprecated
public Enumeration getServletNames() {
throw new RuntimeException(
"ServletContextStub.getServletNames() not implemented.");
@ -220,6 +222,7 @@ public class ServletContextStub implements ServletContext {
@Override
@SuppressWarnings("rawtypes")
@Deprecated
public Enumeration getServlets() {
throw new RuntimeException(
"ServletContextStub.getServlets() not implemented.");
@ -231,6 +234,7 @@ public class ServletContextStub implements ServletContext {
}
@Override
@Deprecated
public void log(Exception arg0, String arg1) {
throw new RuntimeException("ServletContextStub.log() not implemented.");
}

View file

@ -60,8 +60,8 @@ public class HttpServletRequestStub implements HttpServletRequest {
/**
* Supply the request URL as a single URL. We will parse it on the
* assumption that the contextPath and the pathInfo are empty.
* Don't include a query string. Instead, set parameters.
* assumption that the contextPath and the pathInfo are empty. Don't include
* a query string. Instead, set parameters.
*/
public void setRequestUrl(URL url) {
this.contextPath = "";
@ -81,8 +81,7 @@ public class HttpServletRequestStub implements HttpServletRequest {
/**
* Supply the pieces of the request URL, so we can respond correctly when
* asked for a piece.
* Don't include a query string. Instead, set parameters.
* asked for a piece. Don't include a query string. Instead, set parameters.
*/
public void setRequestUrlByParts(String shemeHostPort, String contextPath,
String servletPath, String pathInfo) {
@ -102,8 +101,9 @@ public class HttpServletRequestStub implements HttpServletRequest {
}
this.servletPath = servletPath;
this.requestUri = contextPath + servletPath + ((pathInfo == null) ? "" : pathInfo);
this.requestUri = contextPath + servletPath
+ ((pathInfo == null) ? "" : pathInfo);
if (shemeHostPort == null) {
throw new NullPointerException("shemeHostPort may not be null.");
}
@ -183,21 +183,21 @@ public class HttpServletRequestStub implements HttpServletRequest {
public String getServletPath() {
return servletPath;
}
@Override
public String getPathInfo() {
return pathInfo;
}
@Override
public String getQueryString() {
if (parameters.isEmpty()) {
return null;
}
String qs = "";
for (String key:parameters.keySet()) {
for (String value: parameters.get(key)) {
for (String key : parameters.keySet()) {
for (String value : parameters.get(key)) {
qs += "&" + key + "=" + URLEncoder.encode(value);
}
}
@ -302,167 +302,202 @@ public class HttpServletRequestStub implements HttpServletRequest {
// Un-implemented methods
// ----------------------------------------------------------------------
@Override
public String getAuthType() {
throw new RuntimeException(
"HttpServletRequestStub.getAuthType() not implemented.");
}
@Override
public Cookie[] getCookies() {
throw new RuntimeException(
"HttpServletRequestStub.getCookies() not implemented.");
}
@Override
public long getDateHeader(String arg0) {
throw new RuntimeException(
"HttpServletRequestStub.getDateHeader() not implemented.");
}
@Override
public int getIntHeader(String arg0) {
throw new RuntimeException(
"HttpServletRequestStub.getIntHeader() not implemented.");
}
@Override
public String getPathTranslated() {
throw new RuntimeException(
"HttpServletRequestStub.getPathTranslated() not implemented.");
}
@Override
public String getRemoteUser() {
throw new RuntimeException(
"HttpServletRequestStub.getRemoteUser() not implemented.");
}
@Override
public String getRequestedSessionId() {
throw new RuntimeException(
"HttpServletRequestStub.getRequestedSessionId() not implemented.");
}
@Override
public Principal getUserPrincipal() {
throw new RuntimeException(
"HttpServletRequestStub.getUserPrincipal() not implemented.");
}
@Override
public boolean isRequestedSessionIdFromCookie() {
throw new RuntimeException(
"HttpServletRequestStub.isRequestedSessionIdFromCookie() not implemented.");
}
@Override
public boolean isRequestedSessionIdFromURL() {
throw new RuntimeException(
"HttpServletRequestStub.isRequestedSessionIdFromURL() not implemented.");
}
@Override
@Deprecated
public boolean isRequestedSessionIdFromUrl() {
throw new RuntimeException(
"HttpServletRequestStub.isRequestedSessionIdFromUrl() not implemented.");
}
@Override
public boolean isRequestedSessionIdValid() {
throw new RuntimeException(
"HttpServletRequestStub.isRequestedSessionIdValid() not implemented.");
}
@Override
public boolean isUserInRole(String arg0) {
throw new RuntimeException(
"HttpServletRequestStub.isUserInRole() not implemented.");
}
@Override
public String getCharacterEncoding() {
throw new RuntimeException(
"HttpServletRequestStub.getCharacterEncoding() not implemented.");
}
@Override
public int getContentLength() {
throw new RuntimeException(
"HttpServletRequestStub.getContentLength() not implemented.");
}
@Override
public String getContentType() {
throw new RuntimeException(
"HttpServletRequestStub.getContentType() not implemented.");
}
@Override
public ServletInputStream getInputStream() throws IOException {
throw new RuntimeException(
"HttpServletRequestStub.getInputStream() not implemented.");
}
@Override
public String getLocalAddr() {
throw new RuntimeException(
"HttpServletRequestStub.getLocalAddr() not implemented.");
}
@Override
public String getLocalName() {
throw new RuntimeException(
"HttpServletRequestStub.getLocalName() not implemented.");
}
@Override
public int getLocalPort() {
throw new RuntimeException(
"HttpServletRequestStub.getLocalPort() not implemented.");
}
@Override
public Locale getLocale() {
throw new RuntimeException(
"HttpServletRequestStub.getLocale() not implemented.");
}
@Override
@SuppressWarnings("rawtypes")
public Enumeration getLocales() {
throw new RuntimeException(
"HttpServletRequestStub.getLocales() not implemented.");
}
@Override
public String getProtocol() {
throw new RuntimeException(
"HttpServletRequestStub.getProtocol() not implemented.");
}
@Override
public BufferedReader getReader() throws IOException {
throw new RuntimeException(
"HttpServletRequestStub.getReader() not implemented.");
}
@Override
@Deprecated
public String getRealPath(String arg0) {
throw new RuntimeException(
"HttpServletRequestStub.getRealPath() not implemented.");
}
@Override
public String getRemoteHost() {
throw new RuntimeException(
"HttpServletRequestStub.getRemoteHost() not implemented.");
}
@Override
public int getRemotePort() {
throw new RuntimeException(
"HttpServletRequestStub.getRemotePort() not implemented.");
}
@Override
public RequestDispatcher getRequestDispatcher(String arg0) {
throw new RuntimeException(
"HttpServletRequestStub.getRequestDispatcher() not implemented.");
}
@Override
public String getScheme() {
throw new RuntimeException(
"HttpServletRequestStub.getScheme() not implemented.");
}
@Override
public String getServerName() {
throw new RuntimeException(
"HttpServletRequestStub.getServerName() not implemented.");
}
@Override
public int getServerPort() {
throw new RuntimeException(
"HttpServletRequestStub.getServerPort() not implemented.");
}
@Override
public boolean isSecure() {
throw new RuntimeException(
"HttpServletRequestStub.isSecure() not implemented.");
}
@Override
public void setCharacterEncoding(String arg0)
throws UnsupportedEncodingException {
throw new RuntimeException(

View file

@ -126,12 +126,14 @@ public class HttpSessionStub implements HttpSession {
}
@Override
@Deprecated
public Object getValue(String arg0) {
throw new RuntimeException(
"HttpSessionStub.getValue() not implemented.");
}
@Override
@Deprecated
public String[] getValueNames() {
throw new RuntimeException(
"HttpSessionStub.getValueNames() not implemented.");
@ -149,12 +151,14 @@ public class HttpSessionStub implements HttpSession {
}
@Override
@Deprecated
public void putValue(String arg0, Object arg1) {
throw new RuntimeException(
"HttpSessionStub.putValue() not implemented.");
}
@Override
@Deprecated
public void removeValue(String arg0) {
throw new RuntimeException(
"HttpSessionStub.removeValue() not implemented.");

View file

@ -9,5 +9,5 @@
# Ontology is complete.
#
# Find out how to use this file at
# https://sourceforge.net/apps/mediawiki/vivo/index.php?title=Using_Short_Views_in_Release_1.5
# https://wiki.duraspace.org/display/VIVO/Using+Short+Views+in+Release+1.5
#

View file

@ -65,6 +65,7 @@ edu.cornell.mannlib.vitro.webapp.i18n.selection.LocaleSelectionSetup
edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup
edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerSetup
edu.cornell.mannlib.vitro.webapp.freemarker.config.FreemarkerConfiguration$Setup
# On shutdown, this will kill the background thread started by Apache Commons File Upload
org.apache.commons.fileupload.servlet.FileCleanerCleanup

View file

@ -55,7 +55,12 @@ var customForm = {
// the verify popup window. Although there could be multiple verifyMatch objects
// selecting one and binding the event works for all of them
this.verifyMatch = this.form.find('.verifyMatch');
this.defaultAcType = ""; // will be set in setType() first time through
this.templateDefinedAcTypes = false;
if ( this.acTypes != undefined ) {
this.templateDefinedAcTypes = true;
}
// find all the acSelector input elements
this.acSelectors = [] ;
@ -86,7 +91,7 @@ var customForm = {
// Used with the cancel link. If the user cancels after a type selection, this check
// ensures that any a/c fields (besides the one associated with the type) will be reset
this.clearAcSelections = false;
},
// Set up the form on page load
@ -126,6 +131,10 @@ var customForm = {
this.initFormView();
// Set the initial autocomplete help text in the acSelector fields.
$.each(this.acSelectors, function() {
customForm.addAcHelpText($(this));
});
},
initFormView: function() {
@ -288,7 +297,7 @@ var customForm = {
//to the filtering list
this.getAcFilterForIndividuals();
this.acCache = {};
$(selectedObj).autocomplete({
minLength: 3,
source: function(request, response) {
@ -312,8 +321,9 @@ var customForm = {
},
complete: function(xhr, status) {
// Not sure why, but we need an explicit json parse here.
var results = $.parseJSON(xhr.responseText),
var results = $.parseJSON(xhr.responseText),
filteredResults = customForm.filterAcResults(results);
customForm.acCache[request.term] = filteredResults;
response(filteredResults);
}
@ -321,6 +331,9 @@ var customForm = {
},
select: function(event, ui) {
customForm.showAutocompleteSelection(ui.item.label, ui.item.uri, $(selectedObj));
if ( $(selectedObj).attr('acGroupName') == customForm.typeSelector.attr('acGroupName') ) {
customForm.typeSelector.val(ui.item.msType);
}
}
});
},
@ -420,17 +433,24 @@ var customForm = {
// provides a way to monitor selection in other js files, e.g. to hide fields upon selection
$acDiv.addClass("userSelected");
// If the form has a type selector, add type name to label in add mode. In edit mode, use typeSelectorSpan
// html. The second case is an "else if" and not an else because the template may not be passing the label
// to the acSelection macro or it may not be using the macro at all and the label is hard-coded in the html.
if ( this.typeSelector.length && ($acDiv.attr('acGroupName') == this.typeSelector.attr('acGroupName')) ) {
$acDiv.find('label').html('Selected ' + this.typeName + ':');
}
else if ( this.typeSelectorSpan.html() && ($acDiv.attr('acGroupName') == this.typeSelectorInput.attr('acGroupName')) ) {
$acDiv.find('label').html('Selected ' + this.typeSelectorSpan.html() + ':');
}
else if ( $acDiv.find('label').html() == '' ) {
$acDiv.find('label').html('Selected ' + this.multipleTypeNames[$(selectedObj).attr('acGroupName')] + ':');
// If the form has a type selector, add type name to label in add mode. In edit mode,
// use typeSelectorSpan html. The second case is an "else if" and not an else because
// the template may not be passing the label to the acSelection macro or it may not be
// using the macro at all and the label is hard-coded in the html.
// ** With release 1.6 and display of all fields, more labels are hard-coded in html.
// ** So check if there's a label before doing anything else.
if ( $acDiv.find('label').html().length === 0 ) {
if ( this.typeSelector.length && ($acDiv.attr('acGroupName') == this.typeSelector.attr('acGroupName')) ) {
$acDiv.find('label').html('Selected ' + this.typeName + ':');
}
else if ( this.typeSelectorSpan.html() && ($acDiv.attr('acGroupName') == this.typeSelectorInput.attr('acGroupName')) ) {
$acDiv.find('label').html('Selected ' + this.typeSelectorSpan.html() + ':');
}
else if ( $acDiv.find('label').html() == '' ) {
$acDiv.find('label').html('Selected ' + this.multipleTypeNames[$(selectedObj).attr('acGroupName')] + ':');
}
}
$acDiv.show();
@ -447,7 +467,6 @@ var customForm = {
//On initialization in this mode, submit button is disabled
this.enableSubmit();
}
},
undoAutocompleteSelection: function(selectedObj) {
@ -482,11 +501,12 @@ var customForm = {
$acSelector = customForm.getAcSelector($checkSelection);
$acSelector.parent('p').show();
}
});
}
});
}
}
else {
$acSelectionObj = $(selectedObj);
customForm.typeSelector.val('');
}
$acSelector = this.getAcSelector($acSelectionObj);
@ -530,10 +550,9 @@ var customForm = {
// Note: we still need this in edit mode, to set the text values.
setType: function() {
var selectedType;
// If there's no type selector, these values have been specified in customFormData,
// and will not change over the life of the form.
if (!this.typeSelector.length) {
if (!this.typeSelector.length) {
if ( this.editMode == 'edit' && (this.typeSelectorSpan.html() != null && this.typeSelectorInput.val() != null) ) {
this.typeName = this.typeSelectorSpan.html();
this.acTypes[this.typeSelectorInput.attr('acGroupName')] = this.typeSelectorInput.val();
@ -542,7 +561,11 @@ var customForm = {
}
selectedType = this.typeSelector.find(':selected');
var acTypeKey = this.typeSelector.attr('acGroupName');
var acTypeKey = this.typeSelector.attr('acGroupName');
if ( this.templateDefinedAcTypes && !this.defaultAcType.length ) {
this.defaultAcType = this.acTypes[acTypeKey];
}
if (selectedType.val().length) {
this.acTypes[acTypeKey] = selectedType.val();
this.typeName = selectedType.html();
@ -551,15 +574,20 @@ var customForm = {
$acSelect.find('label').html( customForm.selectedString + ' ' + this.typeName + ':');
}
}
// reset to empty values; may not need
// reset to empty values;
else {
delete this.acTypes[acTypeKey];
this.typeName = '';
if ( this.templateDefinedAcTypes ) {
this.acTypes[acTypeKey] = this.defaultAcType;
}
else {
this.acTypes = new Object();
}
this.typeName = this.defaultTypeName;
}
},
// Set field labels based on type selection. Although these won't change in edit
// mode, it's easier to specify the text here than in the jsp.
// mode, it's easier to specify the text here than in the ftl.
setLabels: function() {
var typeName = this.getTypeNameForLabels();
@ -575,10 +603,20 @@ var customForm = {
// or in repair mode in a two-step form with no type selected. Use the default type
// name specified in the form data.
if ( !selectedObj || !this.hasMultipleTypeNames ) {
return this.acTypes ? this.typeName : this.capitalize(this.defaultTypeName);
if ( this.acTypes && this.typeName ) {
return this.typeName;
}
else {
return this.capitalize(this.defaultTypeName);
}
}
else if ( selectedObj && ( $(selectedObj).attr('acGroupName') == this.typeSelector.attr('acGroupName') ) ) {
return this.acTypes ? this.typeName : this.capitalize(this.defaultTypeName);
if ( this.acTypes && this.typeName ) {
return this.typeName;
}
else {
return this.capitalize(this.defaultTypeName);
}
}
else {
var name = customForm.multipleTypeNames[$(selectedObj).attr('id')];