NIHVIVO-3300 Placeholder images are configured by a properties file, which is loaded at startup.
This commit is contained in:
parent
94717a3705
commit
9442468b75
10 changed files with 278 additions and 79 deletions
|
@ -24,7 +24,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.ImageUtil;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
|
@ -134,8 +134,8 @@ public class ManageProxiesListPage extends AbstractPageHandler {
|
|||
private ProxyItemInfo wrapProxyItem(ProxyItemInfo item) {
|
||||
String imagePath = item.getImageUrl();
|
||||
if (imagePath.isEmpty()) {
|
||||
imagePath = ImageUtil
|
||||
.getPlaceholderImagePathForType(VitroVocabulary.USERACCOUNT);
|
||||
imagePath = PlaceholderUtil.getPlaceholderImagePathForType(vreq,
|
||||
VitroVocabulary.USERACCOUNT);
|
||||
}
|
||||
|
||||
UserAccount ua = userAccountsDao.getUserAccountByUri(item.getUri());
|
||||
|
@ -151,8 +151,8 @@ public class ManageProxiesListPage extends AbstractPageHandler {
|
|||
private ProxyItemInfo wrapProfileItem(ProxyItemInfo item) {
|
||||
String imagePath = item.getImageUrl();
|
||||
if (imagePath.isEmpty()) {
|
||||
imagePath = ImageUtil.getPlaceholderImagePathForIndividual(vreq,
|
||||
item.getUri());
|
||||
imagePath = PlaceholderUtil.getPlaceholderImagePathForIndividual(
|
||||
vreq, item.getUri());
|
||||
}
|
||||
|
||||
return new ProfileItemWrapper(item.getUri(), item.getLabel(),
|
||||
|
|
|
@ -24,9 +24,9 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.ImageUtil;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||
|
||||
/**
|
||||
* Get the basic auto-complete info for the proxy selection.
|
||||
|
@ -64,8 +64,9 @@ public class BasicProxiesGetter extends AbstractAjaxResponder {
|
|||
OntModelSelector oms = ModelContext.getUnionOntModelSelector(ctx);
|
||||
userAccountsModel = oms.getUserAccountsModel();
|
||||
|
||||
placeholderImageUrl = UrlBuilder.getUrl(ImageUtil
|
||||
.getPlaceholderImagePathForType(VitroVocabulary.USERACCOUNT));
|
||||
placeholderImageUrl = UrlBuilder.getUrl(PlaceholderUtil
|
||||
.getPlaceholderImagePathForType(vreq,
|
||||
VitroVocabulary.USERACCOUNT));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.ajax.AbstractAjaxResponder;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.ImageUtil;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||
|
||||
/**
|
||||
* Get more information (class label and image URL) about a selected proxy.
|
||||
|
@ -79,7 +79,7 @@ public class MoreProfileInfo extends AbstractAjaxResponder {
|
|||
private String getFullImageUrl(Individual ind) {
|
||||
String path = ind.getThumbUrl();
|
||||
if ((path == null) || path.isEmpty()) {
|
||||
path = ImageUtil.getPlaceholderImagePathForIndividual(vreq,
|
||||
path = PlaceholderUtil.getPlaceholderImagePathForIndividual(vreq,
|
||||
ind.getURI());
|
||||
}
|
||||
return UrlBuilder.getUrl(path);
|
||||
|
|
|
@ -27,7 +27,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
|||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.ImageUtil;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||
|
||||
/**
|
||||
* Handle the "My Account" form display and submission.
|
||||
|
@ -270,8 +270,9 @@ public class UserAccountsMyAccountPage extends UserAccountsPage {
|
|||
String userUri = proxyUser.getUri();
|
||||
String label = assembleUserAccountLabel(proxyUser);
|
||||
String classLabel = "";
|
||||
String imageUrl = UrlBuilder.getUrl(ImageUtil
|
||||
.getPlaceholderImagePathForType(VitroVocabulary.USERACCOUNT));
|
||||
String imageUrl = UrlBuilder.getUrl(PlaceholderUtil
|
||||
.getPlaceholderImagePathForType(vreq,
|
||||
VitroVocabulary.USERACCOUNT));
|
||||
|
||||
// Does this user have a profile? Can we get better info?
|
||||
Individual proxyProfilePage = getProfilePage(proxyUser);
|
||||
|
|
|
@ -36,7 +36,7 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup;
|
|||
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
||||
import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo;
|
||||
import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.ImageUtil;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||
|
||||
/**
|
||||
* Handle adding, replacing or deleting the main image on an Individual.
|
||||
|
@ -405,8 +405,9 @@ public class ImageUploadController extends FreemarkerHttpServlet {
|
|||
ACTION_UPLOAD);
|
||||
String cancelUrl = (entity == null) ? "" : exitPageUrl(vreq,
|
||||
entity.getURI());
|
||||
String placeholderUrl = (entity == null) ? "" : UrlBuilder.getUrl(ImageUtil
|
||||
.getPlaceholderImagePathForIndividual(vreq, entity.getURI()));
|
||||
String placeholderUrl = (entity == null) ? "" : UrlBuilder
|
||||
.getUrl(PlaceholderUtil.getPlaceholderImagePathForIndividual(
|
||||
vreq, entity.getURI()));
|
||||
|
||||
TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_NEW);
|
||||
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
|
||||
/**
|
||||
* Some static methods that help in dealing with image files.
|
||||
*/
|
||||
public class ImageUtil {
|
||||
private static final String DEFAULT_IMAGE_PATH = "/images/placeholders/thumbnail.jpg";
|
||||
|
||||
private static final Map<String, String> DEFAULT_IMAGE_PATHS_BY_TYPE = initImagePaths();
|
||||
|
||||
private static Map<String, String> initImagePaths() {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
// No images other than the default.
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* If we have a placeholder image for this exact type, return it. Otherwise,
|
||||
* return the default.
|
||||
*/
|
||||
public static String getPlaceholderImagePathForType(String typeUri) {
|
||||
for (Entry<String, String> entry : DEFAULT_IMAGE_PATHS_BY_TYPE
|
||||
.entrySet()) {
|
||||
if (typeUri.equals(entry.getKey())) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return DEFAULT_IMAGE_PATH;
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is a placeholder image for any type that this Individual
|
||||
* instantiates, return that image. Otherwise, return the default.
|
||||
*/
|
||||
public static String getPlaceholderImagePathForIndividual(
|
||||
VitroRequest vreq, String individualUri) {
|
||||
IndividualDao indDao = vreq.getWebappDaoFactory().getIndividualDao();
|
||||
for (Entry<String, String> entry : DEFAULT_IMAGE_PATHS_BY_TYPE
|
||||
.entrySet()) {
|
||||
if (indDao.isIndividualOfClass(entry.getKey(), individualUri)) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return DEFAULT_IMAGE_PATH;
|
||||
}
|
||||
|
||||
/** Never need to instantiate this -- all methods are static. */
|
||||
private ImageUtil() {
|
||||
// Nothing to do
|
||||
}
|
||||
}
|
|
@ -0,0 +1,238 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.web.images;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
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.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
|
||||
/**
|
||||
* A utility for finding the URL of the correct Placeholder image.
|
||||
*
|
||||
* The mapping of image URLs to classes is created at startup, and stored in the
|
||||
* ServletContext.
|
||||
*/
|
||||
public class PlaceholderUtil {
|
||||
private static final Log log = LogFactory.getLog(PlaceholderUtil.class);
|
||||
|
||||
private static final String ATTRIBUTE_NAME = PlaceholderUtil.class
|
||||
.getName();
|
||||
private static final String PROPERTIES_FILE_PATH = "/images/placeholders/placeholders.properties";
|
||||
private static final String DEFAULT_IMAGE_PATH = "/images/placeholders/thumbnail.jpg";
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Static methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* If we have a placeholder image for this exact type, return it. Otherwise,
|
||||
* return the default.
|
||||
*/
|
||||
public static String getPlaceholderImagePathForType(VitroRequest vreq,
|
||||
String typeUri) {
|
||||
PlaceholderUtil pu = getPlaceholderUtil(vreq);
|
||||
if (pu == null) {
|
||||
return DEFAULT_IMAGE_PATH;
|
||||
} else {
|
||||
return pu.getPlaceholderImagePathForType(typeUri);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is a placeholder image for any type that this Individual
|
||||
* instantiates, return that image. Otherwise, return the default.
|
||||
*/
|
||||
public static String getPlaceholderImagePathForIndividual(
|
||||
VitroRequest vreq, String individualUri) {
|
||||
PlaceholderUtil pu = getPlaceholderUtil(vreq);
|
||||
if (pu == null) {
|
||||
return DEFAULT_IMAGE_PATH;
|
||||
} else {
|
||||
IndividualDao iDao = vreq.getWebappDaoFactory().getIndividualDao();
|
||||
return pu.getPlaceholderImagePathForIndividual(iDao, individualUri);
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the PlaceholderUtil instance from the context, or null if none. */
|
||||
private static PlaceholderUtil getPlaceholderUtil(VitroRequest vreq) {
|
||||
if (vreq == null) {
|
||||
return null;
|
||||
}
|
||||
ServletContext ctx = vreq.getSession().getServletContext();
|
||||
Object attrib = ctx.getAttribute(ATTRIBUTE_NAME);
|
||||
if (attrib instanceof PlaceholderUtil) {
|
||||
return (PlaceholderUtil) attrib;
|
||||
} else {
|
||||
log.warn("Looked for a PlaceholerUtil, but found " + attrib);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// The object
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private final Map<String, String> mapUrlsByClass;
|
||||
|
||||
private PlaceholderUtil(Map<String, String> map) {
|
||||
this.mapUrlsByClass = Collections
|
||||
.unmodifiableMap(new HashMap<String, String>(map));
|
||||
}
|
||||
|
||||
/**
|
||||
* If we have a placeholder image for this exact type, return it. Otherwise,
|
||||
* return the default.
|
||||
*/
|
||||
private String getPlaceholderImagePathForType(String typeUri) {
|
||||
if (typeUri == null) {
|
||||
log.debug("getPlaceholderImagePathForType: typeUri is null");
|
||||
return DEFAULT_IMAGE_PATH;
|
||||
}
|
||||
String url = mapUrlsByClass.get(typeUri);
|
||||
if (url == null) {
|
||||
log.debug("getPlaceholderImagePathForType: no value for '"
|
||||
+ typeUri + "'");
|
||||
return DEFAULT_IMAGE_PATH;
|
||||
}
|
||||
log.debug("getPlaceholderImagePathForType: value for '" + typeUri
|
||||
+ "' is '" + url + "'");
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* If there is a placeholder image for any type that this Individual
|
||||
* instantiates, return that image. Otherwise, return the default.
|
||||
*/
|
||||
private String getPlaceholderImagePathForIndividual(IndividualDao iDao,
|
||||
String individualUri) {
|
||||
if (individualUri == null) {
|
||||
log.debug("getPlaceholderImagePathForIndividual: "
|
||||
+ "individualUri is null");
|
||||
return DEFAULT_IMAGE_PATH;
|
||||
}
|
||||
for (String classUri : mapUrlsByClass.keySet()) {
|
||||
String imageUrl = mapUrlsByClass.get(classUri);
|
||||
if (iDao.isIndividualOfClass(classUri, individualUri)) {
|
||||
log.debug("getPlaceholderImagePathForIndividual: individual '"
|
||||
+ individualUri + "' is of class '" + classUri
|
||||
+ "', value is '" + imageUrl + "'");
|
||||
return imageUrl;
|
||||
}
|
||||
}
|
||||
log.debug("getPlaceholderImagePathForIndividual: individual '"
|
||||
+ individualUri + "' is not of any recognized class");
|
||||
return DEFAULT_IMAGE_PATH;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Classes used for setup
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public static class Setup implements ServletContextListener {
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext ctx = sce.getServletContext();
|
||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||
|
||||
try {
|
||||
File propertiesFile = confirmRealPath(ctx, PROPERTIES_FILE_PATH);
|
||||
Map<String, String> map = loadPropertiesToMap(propertiesFile);
|
||||
confirmImagesArePresent(ctx, map);
|
||||
ctx.setAttribute(ATTRIBUTE_NAME, new PlaceholderUtil(map));
|
||||
} catch (SetupException e) {
|
||||
if (e.getCause() == null) {
|
||||
ss.warning(this, e.getMessage());
|
||||
} else {
|
||||
ss.warning(this, e.getMessage(), e.getCause());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> loadPropertiesToMap(File propertiesFile)
|
||||
throws SetupException {
|
||||
Properties props = new Properties();
|
||||
try {
|
||||
props.load(new FileReader(propertiesFile));
|
||||
} catch (IOException e) {
|
||||
throw new SetupException(
|
||||
"Can't load properties from the file at '"
|
||||
+ PROPERTIES_FILE_PATH
|
||||
+ "'. Is it in a valid format?", e);
|
||||
}
|
||||
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
for (Enumeration<Object> keys = props.keys(); keys
|
||||
.hasMoreElements();) {
|
||||
String key = (String) keys.nextElement();
|
||||
String value = props.getProperty(key);
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private void confirmImagesArePresent(ServletContext ctx,
|
||||
Map<String, String> map) throws SetupException {
|
||||
Set<String> imageUrls = new HashSet<String>();
|
||||
imageUrls.add(DEFAULT_IMAGE_PATH);
|
||||
imageUrls.addAll(map.values());
|
||||
for (String imageUrl : imageUrls) {
|
||||
confirmRealPath(ctx, imageUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private File confirmRealPath(ServletContext ctx, String url)
|
||||
throws SetupException {
|
||||
String path = ctx.getRealPath(url);
|
||||
if (path == null) {
|
||||
throw new SetupException("Can't translate to real path: '"
|
||||
+ url + "'");
|
||||
}
|
||||
File file = new File(path);
|
||||
if (!file.exists()) {
|
||||
throw new SetupException("No file found at '" + url + "'.");
|
||||
}
|
||||
if (!file.canRead()) {
|
||||
throw new SetupException("Can't read the file at '" + url
|
||||
+ "'.");
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
sce.getServletContext().removeAttribute(ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class SetupException extends Exception {
|
||||
public SetupException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public SetupException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.ImageUtil;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||
import freemarker.core.Environment;
|
||||
import freemarker.template.TemplateModelException;
|
||||
|
||||
|
@ -32,7 +32,7 @@ public class IndividualPlaceholderImageUrlMethod extends BaseTemplateMethodModel
|
|||
Environment env = Environment.getCurrentEnvironment();
|
||||
HttpServletRequest request = (HttpServletRequest) env.getCustomAttribute("request");
|
||||
VitroRequest vreq = new VitroRequest(request);
|
||||
String imageUrl = ImageUtil.getPlaceholderImagePathForIndividual(vreq, uri);
|
||||
String imageUrl = PlaceholderUtil.getPlaceholderImagePathForIndividual(vreq, uri);
|
||||
return UrlBuilder.getUrl(imageUrl);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@ edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase
|
|||
|
||||
edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil$Setup
|
||||
|
||||
# Update the URIs on Permission Sets on UserAccounts from model (1.4) to 1.5.
|
||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdatePermissionSetUris
|
||||
|
||||
|
|
17
webapp/web/images/placeholders/placeholders.properties
Normal file
17
webapp/web/images/placeholders/placeholders.properties
Normal file
|
@ -0,0 +1,17 @@
|
|||
#
|
||||
# Assign placeholder images to classes of individuals.
|
||||
#
|
||||
# If showing an individual that has no image, a placeholder image may be shown.
|
||||
# By default, the placeholder is /images/placeholders/thumbnail.jpg. However,
|
||||
# this file allows you to associate classes with special placeholder images, and
|
||||
# if the individual belongs to such a class, the special placeholder is shown
|
||||
# instead of the default.
|
||||
#
|
||||
# EXAMPLE:
|
||||
# http\://xmlns.com/foaf/0.1/Person = /images/placeholders/person.thumbnail.jpg
|
||||
# means that any individual of type foaf:Person will be represented by
|
||||
# person.thumbnail.jpg
|
||||
#
|
||||
# NOTE: a colon is a special character in a properties file, and must be escaped
|
||||
# by a backslash.
|
||||
|
Loading…
Add table
Reference in a new issue