Merge remote-tracking branch 'origin' into develop

This commit is contained in:
Brian Caruso 2013-03-05 17:15:58 -05:00
commit 08f583e280
110 changed files with 5057 additions and 1583 deletions

View file

@ -120,7 +120,7 @@ public class RootUserPolicy implements PolicyIface {
PROPERTY_ROOT_USER_EMAIL);
if (email == null) {
throw new IllegalStateException(
"deploy.properties must contain a value for '"
"runtime.properties must contain a value for '"
+ PROPERTY_ROOT_USER_EMAIL + "'");
} else {
return email;
@ -177,7 +177,7 @@ public class RootUserPolicy implements PolicyIface {
private void complainAboutMultipleRootUsers() {
for (String other : otherRootUsers) {
ss.warning(this, "deploy.properties specifies '"
ss.warning(this, "runtime.properties specifies '"
+ configuredRootUser + "' as the value for '"
+ PROPERTY_ROOT_USER_EMAIL
+ "', but the system also contains this root user: "
@ -189,7 +189,7 @@ public class RootUserPolicy implements PolicyIface {
private void complainAboutWrongRootUsers() {
for (String other : otherRootUsers) {
ss.warning(this, "deploy.properties specifies '"
ss.warning(this, "runtime.properties specifies '"
+ configuredRootUser + "' as the value for '"
+ PROPERTY_ROOT_USER_EMAIL
+ "', but the system contains this root user instead: "

View file

@ -49,15 +49,6 @@ public class ApplicationBean {
private String copyrightAnchor;
private String themeDir;
public static ApplicationBean getAppBean(ServletContext sc){
if( sc != null ){
Object obj = sc.getAttribute("applicationBean");
if( obj != null )
return (ApplicationBean)obj;
}
return new ApplicationBean();
}
public String toString() {
String output = "Application Bean Contents:\n";
output += " initialized from DB: [" + initialized + "]\n";

View file

@ -20,8 +20,8 @@ import org.apache.commons.logging.LogFactory;
* are attached to the servlet context.
*
* The customary behavior is for ConfigurationPropertiesSetup to create a
* ConfigurationPropertiesImpl, which will parse the deploy.properties file for
* these properties.
* ConfigurationPropertiesImpl, which will obtain the properties from the
* build.properties file and the runtime.properties file.
*/
public abstract class ConfigurationProperties {
private static final Log log = LogFactory

View file

@ -9,13 +9,16 @@ import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* The basic implementation of ConfigurationProperties. It loads the
* configuration properties from a properties file and stores them in a map.
* configuration properties from a properties file and stores them in a map. It
* also permits the caller to supply a map of "preemptive" properties that will
* be included and will override any matching properties from the file.
*
* Leading and trailing white space are trimmed from the property values.
*
@ -27,23 +30,25 @@ public class ConfigurationPropertiesImpl extends ConfigurationProperties {
private final Map<String, String> propertyMap;
public ConfigurationPropertiesImpl(InputStream stream) {
public ConfigurationPropertiesImpl(InputStream stream,
Map<String, String> preemptiveProperties) throws IOException {
Properties props = loadFromPropertiesFile(stream);
Map<String, String> map = copyPropertiesToMap(props);
trimWhiteSpaceFromValues(map);
this.propertyMap = Collections.unmodifiableMap(map);
if (preemptiveProperties != null) {
map.putAll(preemptiveProperties);
}
trimWhiteSpaceFromValues(map);
this.propertyMap = Collections.unmodifiableMap(map);
log.debug("Configuration properties are: " + map);
}
private Properties loadFromPropertiesFile(InputStream stream) {
private Properties loadFromPropertiesFile(InputStream stream)
throws IOException {
Properties props = new Properties();
try {
props.load(stream);
} catch (IOException e) {
throw new IllegalStateException(
"Failed to parse the configuration properties file.", e);
}
props.load(stream);
return props;
}
@ -84,7 +89,8 @@ public class ConfigurationPropertiesImpl extends ConfigurationProperties {
@Override
public String toString() {
return "ConfigurationPropertiesImpl[propertyMap=" + propertyMap + "]";
return "ConfigurationPropertiesImpl[propertyMap="
+ new TreeMap<String, String>(propertyMap) + "]";
}
}

View file

@ -4,11 +4,13 @@ package edu.cornell.mannlib.vitro.webapp.config;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
@ -21,61 +23,45 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
* Reads the configuration properties from a file and stores them in the servlet
* Locates the runtime configuration properties and stores them in the servlet
* context.
*
* This must be invoked before any listener that requires configuration
* properties.
*
* The path to the file can be specified by an Environment name in the Context,
* like this:
* The properties file must be called 'runtime.properties' in the Vitro home
* directory. The path to the Vitro home directory can be specifed by an JNDI
* value, or by a System property, or by a property in
* WEB-INF/resources/build.properties, in that order. If the Vitro home
* directory is specified in more than one way, a warning is issued and the
* first value is used.
*
* <pre>
* If the Vitro home directory cannot be located, or if it does not contain a
* file called 'runtime.properties', or if the file cannot be loaded, a fatal
* error is registered to abort the startup.
*
* <Context override="true">
* <Environment name="path.configuration"
* value="/wherever/the/file/lives/deploy.properties"
* type="java.lang.String"
* override="false" />
* </Context>
*
* </pre>
*
* We look in this environment variable to find the path to the properties file.
* If there is no such environment variable, the default path is used.
*
* Once the path has been determined, we will use it to look for a resource in
* the classpath. So if the path is "deploy.properties", it might be found in
* "tomcat/webapps/vivo/WEB-INF/classes/deploy.properties". Of course, it might
* also be found in any other portion of the classpath as well.
*
* If we can't find the resource in the classpath, we will use it to look for an
* external file. So, one might reasonably set this value to something like
* "/usr/local/vitro/stuff/my.deploy.properties".
*
* If neither a resource nor an external file can be found, we throw an
* exception and set AbortStartup.
* The ConfigurationProperties bean is created from the key/value pairs found in
* 'runtime.properties', and is stored in the servlet context. The value that
* was determined for 'vitro.home' is also included in the bean.
*/
public class ConfigurationPropertiesSetup implements ServletContextListener {
private static final Log log = LogFactory
.getLog(ConfigurationPropertiesSetup.class);
/**
* The JNDI naming context where Tomcat stores environment attributes.
*/
static final String JNDI_BASE = "java:comp/env";
/** JNDI path that defines the Vitro home directory */
private static final String VHD_JNDI_PATH = "java:comp/env/vitro/home";
/**
* The name of the JNDI environment mapping for the path to the
* configuration file (or resource).
*/
static final String PATH_CONFIGURATION = "path.configuration";
/** System property that defines the Vitro home directory */
private static final String VHD_SYSTEM_PROPERTY = "vitro.home";
/**
* If we don't find the path to the config properties from a JNDI mapping,
* use this. Not final, so we can jigger it for unit tests.
*/
private static String DEFAULT_CONFIG_PATH = "deploy.properties";
/** build.properties property that defines the Vitro home directory */
private static final String VHD_BUILD_PROPERTY = "vitro.home";
/** Configuration property to store the Vitro home directory */
private static final String VHD_CONFIGURATION_PROPERTY = "vitro.home";
/** Name of the file that contains runtime properties. */
private static final String FILE_RUNTIME_PROPERTIES = "runtime.properties";
@Override
public void contextInitialized(ServletContextEvent sce) {
@ -85,12 +71,18 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
try {
InputStream stream = null;
try {
stream = locatePropertiesFile();
File vitroHomeDir = locateVitroHomeDirectory(ctx, ss);
File runtimePropertiesFile = locateRuntimePropertiesFile(
vitroHomeDir, ss);
stream = new FileInputStream(runtimePropertiesFile);
Map<String, String> preempts = createPreemptiveProperties(
VHD_CONFIGURATION_PROPERTY, vitroHomeDir);
ConfigurationPropertiesImpl bean = new ConfigurationPropertiesImpl(
stream);
stream, preempts);
ConfigurationProperties.setBean(ctx, bean);
ss.info(this, "Loaded " + bean.getPropertyMap().size()
+ " properties.");
} finally {
@ -102,81 +94,171 @@ public class ConfigurationPropertiesSetup implements ServletContextListener {
}
}
}
} catch (IllegalStateException e) {
ss.fatal(this, e.getMessage(), e);
} catch (Exception e) {
log.error(e, e);
ss.fatal(this, e.getMessage(), e);
}
}
private InputStream locatePropertiesFile() {
String path = determinePathToProperties();
log.debug("Configuration properties path is '" + path + "'");
if (resourceExists(path)) {
log.debug("Found configuration properties as a resource.");
return getResourceStream(path);
}
if (externalFileExists(path)) {
log.debug("Found configuration properties as an external file.");
return getExternalFileStream(path);
}
throw new IllegalStateException("Can't find the properties file at '"
+ path + "'");
}
/**
* If we can't find it with JNDI, use the default.
* Look in the JDNI environment, the system properties, and the
* build.properties file.
*
* If we don't find it, fail. If we find it more than once, warn and use the
* first one.
*
* Confirm that it is an existing, readable directory.
*/
private String determinePathToProperties() {
private File locateVitroHomeDirectory(ServletContext ctx, StartupStatus ss) {
Map<String, String> whereWasIt = new LinkedHashMap<String, String>();
getVhdFromJndi(whereWasIt);
getVhdFromSystemProperties(whereWasIt);
getVhdFromBuildProperties(ctx, whereWasIt);
if (whereWasIt.isEmpty()) {
String message = String.format("Can't find a value "
+ "for the Vitro home directory. "
+ "Looked in JNDI environment at '%s'. "
+ "Looked for a system property named '%s'. "
+ "Looked in 'WEB-INF/resources/build.properties' "
+ "for '%s'.", VHD_JNDI_PATH, VHD_SYSTEM_PROPERTY,
VHD_BUILD_PROPERTY);
throw new IllegalStateException(message);
} else if (whereWasIt.size() > 1) {
String message = String.format("Found multiple values for the "
+ "Vitro home directory: " + whereWasIt.keySet());
ss.warning(this, message);
}
String message = whereWasIt.keySet().iterator().next();
String vhdPath = whereWasIt.values().iterator().next();
ss.info(this, message);
File vhd = new File(vhdPath);
if (!vhd.exists()) {
throw new IllegalStateException("Vitro home directory '" + vhdPath
+ "' does not exist.");
}
if (!vhd.isDirectory()) {
throw new IllegalStateException("Vitro home directory '" + vhdPath
+ "' is not a directory.");
}
if (!vhd.canRead()) {
throw new IllegalStateException("Vitro home directory '" + vhdPath
+ "' cannot be read.");
}
if (!vhd.canWrite()) {
throw new IllegalStateException(
"Can't write to Vitro home directory: '" + vhdPath + "'.");
}
return vhd;
}
private void getVhdFromJndi(Map<String, String> whereWasIt) {
try {
Context envCtx = (Context) new InitialContext().lookup(JNDI_BASE);
if (envCtx == null) {
log.debug("JNDI Lookup on '" + JNDI_BASE + "' failed.");
return DEFAULT_CONFIG_PATH;
String vhdPath = (String) new InitialContext()
.lookup(VHD_JNDI_PATH);
if (vhdPath == null) {
log.debug("Didn't find a JNDI value at '" + VHD_JNDI_PATH
+ "'.");
return;
}
String configPath = (String) envCtx.lookup(PATH_CONFIGURATION);
if (configPath == null) {
log.debug("JNDI Lookup on '" + PATH_CONFIGURATION + "' failed.");
return DEFAULT_CONFIG_PATH;
}
log.debug("deploy.property as specified by JNDI: " + configPath);
return configPath;
log.debug("'" + VHD_JNDI_PATH + "' as specified by JNDI: "
+ vhdPath);
String message = String.format(
"JNDI environment '%s' was set to '%s'", VHD_JNDI_PATH,
vhdPath);
whereWasIt.put(message, vhdPath);
} catch (NamingException e) {
log.warn("JNDI lookup failed. "
+ "Using default path for config properties.", e);
return DEFAULT_CONFIG_PATH;
log.debug("JNDI lookup failed. " + e);
}
}
private boolean resourceExists(String path) {
return getResourceStream(path) != null;
private void getVhdFromSystemProperties(Map<String, String> whereWasIt) {
String vhdPath = System.getProperty(VHD_SYSTEM_PROPERTY);
if (vhdPath == null) {
log.debug("Didn't find a system property value at '"
+ VHD_SYSTEM_PROPERTY + "'.");
return;
}
log.debug("'" + VHD_SYSTEM_PROPERTY
+ "' as specified by system property: " + vhdPath);
String message = String.format("System property '%s' was set to '%s'",
VHD_SYSTEM_PROPERTY, vhdPath);
whereWasIt.put(message, vhdPath);
}
private InputStream getResourceStream(String path) {
return getClass().getClassLoader().getResourceAsStream(path);
}
private void getVhdFromBuildProperties(ServletContext ctx,
Map<String, String> whereWasIt) {
String resourcePath = "/WEB-INF/resources/build.properties";
private boolean externalFileExists(String path) {
File file = new File(path);
return file.isFile();
}
private InputStream getExternalFileStream(String path) {
InputStream stream = null;
File file = new File(path);
if (file.isFile()) {
try {
stream = new FileInputStream(file);
} catch (FileNotFoundException e) {
// testing file.isFile() should have prevented this
log.error(e, e);
try {
stream = ctx.getResourceAsStream(resourcePath);
if (stream == null) {
log.debug("Didn't find a resource at '" + resourcePath + "'.");
return;
}
Properties props = new Properties();
props.load(stream);
String vhdPath = props.getProperty(VHD_BUILD_PROPERTY);
if (vhdPath == null) {
log.debug("'" + resourcePath + "' didn't contain a value for '"
+ VHD_BUILD_PROPERTY + "'.");
return;
}
log.debug("'" + VHD_BUILD_PROPERTY
+ "' as specified by build.properties: " + vhdPath);
String message = String.format(
"In resource '%s', '%s' was set to '%s'.", resourcePath,
VHD_BUILD_PROPERTY, vhdPath);
whereWasIt.put(message, vhdPath);
} catch (IOException e) {
log.warn("Failed to load from '" + resourcePath + "'.", e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return stream;
}
private File locateRuntimePropertiesFile(File vitroHomeDir, StartupStatus ss) {
File rpf = new File(vitroHomeDir, FILE_RUNTIME_PROPERTIES);
if (!rpf.exists()) {
throw new IllegalStateException("Did not find '"
+ FILE_RUNTIME_PROPERTIES + "' in vitro home directory '"
+ vitroHomeDir + "'");
}
if (!rpf.isFile()) {
throw new IllegalStateException("'" + rpf.getPath()
+ "' is not a file.");
}
if (!rpf.canRead()) {
throw new IllegalStateException("Cannot read '" + rpf.getPath()
+ "'.");
}
ss.info(this, "Loading runtime properties from '" + rpf.getPath() + "'");
return rpf;
}
private Map<String, String> createPreemptiveProperties(
String propertyVitroHome, File vitroHomeDir) {
Map<String, String> map = new HashMap<String, String>();
map.put(propertyVitroHome, vitroHomeDir.getAbsolutePath());
return map;
}
@Override

View file

@ -32,7 +32,7 @@ public class ConfigurationPropertiesSmokeTests implements
private static final Log log = LogFactory
.getLog(ConfigurationPropertiesSmokeTests.class);
private static final String PROPERTY_HOME_DIRECTORY = "vitro.home.directory";
private static final String PROPERTY_HOME_DIRECTORY = "vitro.home";
private static final String PROPERTY_DB_URL = "VitroConnection.DataSource.url";
private static final String PROPERTY_DB_USERNAME = "VitroConnection.DataSource.username";
private static final String PROPERTY_DB_PASSWORD = "VitroConnection.DataSource.password";
@ -61,7 +61,7 @@ public class ConfigurationPropertiesSmokeTests implements
ConfigurationProperties props, StartupStatus ss) {
String homeDirectoryPath = props.getProperty(PROPERTY_HOME_DIRECTORY);
if (homeDirectoryPath == null || homeDirectoryPath.isEmpty()) {
ss.fatal(this, "deploy.properties does not contain a value for '"
ss.fatal(this, "Can't find a value for the home directory: '"
+ PROPERTY_HOME_DIRECTORY + "'");
return;
}
@ -97,19 +97,19 @@ public class ConfigurationPropertiesSmokeTests implements
ConfigurationProperties props, StartupStatus ss) {
String url = props.getProperty(PROPERTY_DB_URL);
if (url == null || url.isEmpty()) {
ss.fatal(this, "deploy.properties does not contain a value for '"
ss.fatal(this, "runtime.properties does not contain a value for '"
+ PROPERTY_DB_URL + "'");
return;
}
String username = props.getProperty(PROPERTY_DB_USERNAME);
if (username == null || username.isEmpty()) {
ss.fatal(this, "deploy.properties does not contain a value for '"
ss.fatal(this, "runtime.properties does not contain a value for '"
+ PROPERTY_DB_USERNAME + "'");
return;
}
String password = props.getProperty(PROPERTY_DB_PASSWORD);
if (password == null || password.isEmpty()) {
ss.fatal(this, "deploy.properties does not contain a value for '"
ss.fatal(this, "runtime.properties does not contain a value for '"
+ PROPERTY_DB_PASSWORD + "'");
return;
}
@ -259,7 +259,7 @@ public class ConfigurationPropertiesSmokeTests implements
ConfigurationProperties props, StartupStatus ss) {
String ns = props.getProperty(PROPERTY_DEFAULT_NAMESPACE);
if (ns == null || ns.isEmpty()) {
ss.fatal(this, "deploy.properties does not contain a value for '"
ss.fatal(this, "runtime.properties does not contain a value for '"
+ PROPERTY_DEFAULT_NAMESPACE + "'");
return;
}

View file

@ -33,9 +33,6 @@ import edu.cornell.mannlib.vitro.webapp.web.ContentType;
public class OntologyController extends VitroHttpServlet{
private static final Log log = LogFactory.getLog(OntologyController.class.getName());
private String default_jsp = Controllers.BASIC_JSP;
private ApplicationBean appBean;
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException{
doGet(request, response);
@ -242,7 +239,7 @@ public class OntologyController extends VitroHttpServlet{
throws IOException, ServletException {
VitroRequest vreq = new VitroRequest(req);
ApplicationBean appBean = ApplicationBean.getAppBean(getServletContext());
ApplicationBean appBean = vreq.getAppBean();
//set title before we do the highlighting so we don't get markup in it.
req.setAttribute("title","not found");

View file

@ -283,12 +283,8 @@ public class VitroRequest extends HttpServletRequestWrapper {
}
public ApplicationBean getAppBean(){
//return (ApplicationBean) getAttribute("appBean");
return getWebappDaoFactory().getApplicationDao().getApplicationBean();
}
public void setAppBean(ApplicationBean ab){
setAttribute("appBean",ab);
}
@SuppressWarnings("unchecked")
@Override

View file

@ -7,7 +7,6 @@ import java.util.Map;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
@ -31,7 +30,7 @@ public class StartupStatusController extends FreemarkerHttpServlet {
body.put("title", "Startup Status");
body.put("status", StartupStatus.getBean(getServletContext()));
body.put("contextPath", getContextPath());
body.put("applicationName", getApplicationName());
body.put("applicationName", getApplicationName(vreq));
return new TemplateResponseValues("startupStatus-display.ftl", body);
}
@ -45,11 +44,10 @@ public class StartupStatusController extends FreemarkerHttpServlet {
}
}
private Object getApplicationName() {
private Object getApplicationName(VitroRequest vreq) {
String name = "";
try {
ApplicationBean app = ApplicationBean.getAppBean(getServletContext());
name = app.getApplicationName();
name = vreq.getAppBean().getApplicationName();
} catch (Exception e) {
// deal with problems below
}

View file

@ -117,7 +117,7 @@ public class ExternalAuthHelper {
}
if (externalAuthServerUrl == null) {
log.debug("deploy.properties doesn't contain a value for '"
log.debug("runtime.properties doesn't contain a value for '"
+ PROPERTY_EXTERNAL_AUTH_SERVER_URL
+ "' -- sending directly to '" + returnUrl + "'");
return returnUrl;
@ -142,7 +142,7 @@ public class ExternalAuthHelper {
if (externalAuthHeaderName == null) {
log.error("User asked for external authentication, "
+ "but deploy.properties doesn't contain a value for '"
+ "but runtime.properties doesn't contain a value for '"
+ PROPERTY_EXTERNAL_AUTH_ID_HEADER + "'");
return null;
}

View file

@ -37,7 +37,7 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
* the header will contain the name of the user who just logged in.
*
* Deal with these possibilities:
* - The header name was not configured in deploy.properties. Complain.
* - The header name was not configured in runtime.properties. Complain.
* - No username: the login failed. Complain
* - User corresponds to a User acocunt. Record the login.
* - User corresponds to an Individual (self-editor).

View file

@ -50,7 +50,7 @@ public class ContactMailController extends FreemarkerHttpServlet {
private final static String TEMPLATE_ERROR = "contactForm-error.ftl";
private final static String TEMPLATE_FORM = "contactForm-form.ftl";
private static final String PROPERTY_VITRO_HOME_DIR = "vitro.home.directory";
private static final String PROPERTY_VITRO_HOME_DIR = "vitro.home";
private static final String EMAIL_JOURNAL_FILE_DIR = "emailJournal";
private static final String EMAIL_JOURNAL_FILE_NAME = "contactFormEmails.html";

View file

@ -0,0 +1,126 @@
/* $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.IOException;
import java.io.Reader;
import java.io.StringReader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import freemarker.cache.TemplateLoader;
/**
* Wrap a TemplateLoader, so each time a template is read, delimiters will be
* inserted at the beginning and end. This makes it easier for a developer can
* see what lines of HTML come from which templates.
*
* TemplateLoader returns a token object when finding a template, and then
* recognizes that object when it is used as an argument to getLastModified() or
* getReader(). In order to keep track of the template name, we wrap the token
* object and the name in a token of our own.
*
* Taking the easy way out and reading in the entire template into a string.
* This limits the template size to less than 2^31 characters (~2 GBytes). That
* seems adequate.
*/
public class DelimitingTemplateLoader implements TemplateLoader {
private static final Log log = LogFactory
.getLog(DelimitingTemplateLoader.class);
private final TemplateLoader innerLoader;
public DelimitingTemplateLoader(TemplateLoader innerLoader) {
this.innerLoader = innerLoader;
}
@Override
public Object findTemplateSource(String name) throws IOException {
Object innerTS = innerLoader.findTemplateSource(name);
if (innerTS == null) {
return null;
} else {
return new DelimitingTemplateSource(name, innerTS);
}
}
@Override
public long getLastModified(Object templateSource) {
DelimitingTemplateSource dts = (DelimitingTemplateSource) templateSource;
return innerLoader.getLastModified(dts.ts);
}
@Override
public Reader getReader(Object templateSource, String encoding)
throws IOException {
DelimitingTemplateSource dts = (DelimitingTemplateSource) templateSource;
StringBuilder sb = new StringBuilder();
sb.append("<!-- FM_BEGIN ").append(dts.name).append(" -->");
sb.append(readTemplateSource(encoding, dts.ts));
sb.append("<!-- FM_END ").append(dts.name).append(" -->\n");
return new StringReader(sb.toString());
}
private StringBuilder readTemplateSource(String encoding, Object ts)
throws IOException {
StringBuilder sb = new StringBuilder();
Reader reader = innerLoader.getReader(ts, encoding);
char[] buffer = new char[8192];
int howmany;
while (-1 != (howmany = reader.read(buffer))) {
sb.append(buffer, 0, howmany);
}
return sb;
}
@Override
public void closeTemplateSource(Object templateSource) throws IOException {
DelimitingTemplateSource dts = (DelimitingTemplateSource) templateSource;
innerLoader.closeTemplateSource(dts.ts);
}
// ----------------------------------------------------------------------
// Helper classes
// ----------------------------------------------------------------------
/**
* Data object, wrapping the template name and the templateSource object
* from the inner TemplateLoader.
*/
private static class DelimitingTemplateSource {
public final String name;
public final Object ts;
public DelimitingTemplateSource(String name, Object ts) {
if (name == null) {
throw new NullPointerException("name may not be null.");
}
if (ts == null) {
throw new NullPointerException("ts may not be null.");
}
this.name = name;
this.ts = ts;
}
@Override
public int hashCode() {
return name.hashCode() ^ ts.hashCode();
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o == null) {
return false;
}
if (!o.getClass().equals(this.getClass())) {
return false;
}
DelimitingTemplateSource that = (DelimitingTemplateSource) o;
return this.name.equals(that.name) && this.ts.equals(that.ts);
}
}
}

View file

@ -6,10 +6,14 @@ 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;
@ -17,8 +21,12 @@ 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;
@ -27,30 +35,38 @@ 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 final String themeDir;
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;
String buildEnv = ConfigurationProperties.getBean(context).getProperty("Environment.build");
log.debug("Current build environment: " + buildEnv);
if ("development".equals(buildEnv)) { // Set Environment.build = development in deploy.properties
log.debug("Disabling Freemarker template caching in development build.");
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;
@ -164,6 +180,7 @@ public class FreemarkerConfiguration extends Configuration {
map.put("profileUrl", new IndividualProfileUrlMethod());
map.put("localName", new IndividualLocalNameMethod());
map.put("placeholderImageUrl", new IndividualPlaceholderImageUrlMethod());
map.put("i18n", new I18nMethodModel());
return map;
}
@ -196,7 +213,110 @@ public class FreemarkerConfiguration extends Configuration {
log.error("Error creating template loaders");
}
return mtl;
// 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

@ -51,12 +51,20 @@ public class TemplateProcessingHelper {
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");
if (FreemarkerHttpServlet.PAGE_TEMPLATE_TYPE.equals(templateType)) {
env.include(getTemplate("pageSetup.ftl"));
}
// Apply any data-getters that are associated with this template.
FreemarkerConfiguration.retrieveAndRunDataGetters(env, template.getName());
// Now process it.
env.process();
} catch (TemplateException e) {
throw new TemplateProcessingException("TemplateException creating processing environment", e);

View file

@ -5,7 +5,8 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
//import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -129,7 +130,7 @@ public class UrlBuilder {
return getUrl(Route.LOGOUT);
}
public static class ParamMap extends HashMap<String, String> {
public static class ParamMap extends LinkedHashMap<String, String> {
private static final long serialVersionUID = 1L;
public ParamMap() { }
@ -276,7 +277,7 @@ public class UrlBuilder {
}
if (profileUrl != null) {
HashMap<String, String> specialParams = getModelParams(vreq);
LinkedHashMap<String, String> specialParams = getModelParams(vreq);
if(specialParams.size() != 0) {
profileUrl = addParams(profileUrl, new ParamMap(specialParams));
}
@ -325,9 +326,9 @@ public class UrlBuilder {
//To be used in different property templates so placing method for reuse here
//Check if special params included, specifically for menu management and other models
public static HashMap<String,String> getModelParams(VitroRequest vreq) {
public static LinkedHashMap<String,String> getModelParams(VitroRequest vreq) {
HashMap<String,String> specialParams = new HashMap<String, String>();
LinkedHashMap<String,String> specialParams = new LinkedHashMap<String, String>();
if(vreq != null) {
//this parameter is sufficient to switch to menu model
String useMenuModelParam = vreq.getParameter(DisplayVocabulary.SWITCH_TO_DISPLAY_MODEL);

View file

@ -201,7 +201,7 @@ public class JSONReconcileServlet extends VitroHttpServlet {
viewJson.put("url", urlBuf.toString() + "/individual?uri={{id}}");
json.put("view", viewJson);
// parse defaultTypeList from deploy.properties
// parse defaultTypeList from runtime.properties
if (defaultTypeList != null) {
String[] splitList = defaultTypeList.split(";");
String[][] idNameArray = new String[splitList.length][splitList.length];

View file

@ -15,12 +15,6 @@ public interface IndividualRequestAnalysisContext {
*/
String getDefaultNamespace();
/**
* Is there a namespace for this prefix? If not, return an empty string, but
* never null.
*/
String getNamespaceForPrefix(String prefix);
/**
* Use the IndividualDao to get this individual.
*

View file

@ -15,8 +15,6 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper;
import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapperFactory;
/**
* Implement all of the fiddly-bits that we need for analyzing the request for
@ -45,25 +43,6 @@ public class IndividualRequestAnalysisContextImpl implements
return wadf.getDefaultNamespace();
}
@Override
public String getNamespaceForPrefix(String prefix) {
if (prefix == null) {
return "";
}
NamespaceMapper namespaceMapper = NamespaceMapperFactory
.getNamespaceMapper(ctx);
if (namespaceMapper == null) {
log.warn("No NamespaceMapper in ServletContext. Request URL was '"
+ vreq.getRequestURL() + "'");
return "";
}
String ns = namespaceMapper.getNamespaceForPrefix(prefix);
return (ns == null) ? "" : ns;
}
@Override
public Individual getIndividualByURI(String individualUri) {
if (individualUri == null) {

View file

@ -30,7 +30,6 @@ public class IndividualRequestAnalyzer {
private static Pattern RDF_REQUEST = Pattern.compile("^/individual/([^/]+)/\\1\\.(rdf|n3|ttl)$");
private static Pattern HTML_REQUEST = Pattern.compile("^/display/([^/]+)$");
private static Pattern LINKED_DATA_URL = Pattern.compile("^/individual/([^/]+)$");
private static Pattern NS_PREFIX_URL = Pattern.compile("^/individual/([^/]*)/([^/]+)$");
private final VitroRequest vreq;
private final IndividualRequestAnalysisContext analysisContext;
@ -164,7 +163,6 @@ public class IndividualRequestAnalyzer {
* /individual/localname/localname.rdf
* /individual/localname/localname.n3
* /individual/localname/localname.ttl
* /individual/nsprefix/localname
* </pre>
*
* @return null on failure.
@ -202,14 +200,6 @@ public class IndividualRequestAnalyzer {
return getIndividualByLocalname(rdfMatch.group(1));
}
// Does the URL look like a namespace prefix followed by a local
// name?
Matcher prefix_match = NS_PREFIX_URL.matcher(url);
if (prefix_match.matches() && prefix_match.groupCount() == 2) {
return getIndividualByPrefixAndLocalname(prefix_match.group(1),
prefix_match.group(2));
}
// Couldn't match it to anything.
return null;
} catch (Throwable e) {
@ -299,12 +289,6 @@ public class IndividualRequestAnalyzer {
return getIndividualByUri(uri);
}
private Individual getIndividualByPrefixAndLocalname(String prefix,
String localName) {
String ns = analysisContext.getNamespaceForPrefix(prefix);
return getIndividualByUri(ns + localName);
}
private Individual getIndividualByNetId(String netId) {
return analysisContext.getIndividualByNetId(netId);
}

View file

@ -82,6 +82,7 @@ class IndividualResponseBuilder {
body.put("relatedSubject", getRelatedSubject());
body.put("namespaces", namespaces);
body.put("temporalVisualizationEnabled", getTemporalVisualizationFlag());
body.put("profilePageTypesEnabled", getprofilePageTypesFlag());
body.put("verbosePropertySwitch", getVerbosePropertyValues());
//Execute data getters that might apply to this individual, e.g. because of the class of the individual
@ -91,6 +92,13 @@ class IndividualResponseBuilder {
log.error("Data retrieval for individual lead to error", ex);
}
// for quick profile view - users can toggle between the quick and the full views,
// so the "destination" let's us know which view they are targeting. On normal
// page request, this string is empty and the default template is loaded.
String targetedView = "";
targetedView = vreq.getParameter("destination");
body.put("targetedView", targetedView);
//Individual template model
IndividualTemplateModel itm = getIndividualTemplateModel(individual);
/* We need to expose non-getters in displaying the individual's property list,
@ -100,6 +108,7 @@ class IndividualResponseBuilder {
*/
// body.put("individual", wrap(itm, BeansWrapper.EXPOSE_SAFE));
body.put("labelCount", getLabelCount(itm.getUri(), vreq));
body.put("profileType", getProfileType(itm.getUri(), vreq));
body.put("individual", wrap(itm, new ReadOnlyBeansWrapper()));
body.put("headContent", getRdfLinkTag(itm));
@ -169,6 +178,12 @@ class IndividualResponseBuilder {
return "enabled".equals(property);
}
private boolean getprofilePageTypesFlag() {
String property = ConfigurationProperties.getBean(vreq).getProperty(
"MultiViews.profilePageTypes");
return "enabled".equals(property);
}
private Map<String, Object> getVerbosePropertyValues() {
Map<String, Object> map = null;
@ -275,4 +290,29 @@ class IndividualResponseBuilder {
}
return theCount;
}
private static String PROFILE_TYPE_QUERY = ""
+ "PREFIX display: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> \n"
+ "SELECT ?profile WHERE { \n"
+ " ?subject display:hasDefaultProfilePageType ?profile \n"
+ "}" ;
private static String getProfileType(String subjectUri, VitroRequest vreq) {
String queryStr = QueryUtils.subUriForQueryVar(PROFILE_TYPE_QUERY, "subject", subjectUri);
log.debug("queryStr = " + queryStr);
String profileType = "none";
try {
ResultSet results = QueryUtils.getQueryResults(queryStr, vreq);
if (results.hasNext()) {
QuerySolution soln = results.nextSolution();
String profileStr = soln.get("profile").toString();
if ( profileStr.length() > 0 ) {
profileType = profileStr.substring(profileStr.indexOf("#")+1,profileStr.length());
}
}
} catch (Exception e) {
log.error(e, e);
}
return profileType;
}
}

View file

@ -2,7 +2,9 @@
package edu.cornell.mannlib.vitro.webapp.controller.json;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
@ -24,7 +26,7 @@ import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.Individual
* Does a Solr search for individuals, and uses the short view to render each of
* the results.
*/
public class GetRenderedSolrIndividualsByVClass extends JsonObjectProducer {
public class GetRenderedSolrIndividualsByVClass extends GetSolrIndividualsByVClasses {
private static final Log log = LogFactory
.getLog(GetRenderedSolrIndividualsByVClass.class);
@ -33,21 +35,34 @@ public class GetRenderedSolrIndividualsByVClass extends JsonObjectProducer {
}
/**
* Search for individuals by VClass. The class URI and the paging
* Search for individuals by VClass or VClasses in the case of multiple parameters. The class URI(s) and the paging
* information are in the request parameters.
*/
@Override
protected JSONObject process() throws Exception {
JSONObject rObj = null;
VClass vclass = getVclassParameter(vreq);
String vclassId = vclass.getURI();
//This gets the first vclass value and sets that as display type
List<String> vclassIds = super.getVclassIds(vreq);
String vclassId = null;
if(vclassIds.size() > 1) {
//This ensures the second class instead of the first
//This is a temporary fix in cases where institutional internal classes are being sent in
//and thus the second class is the actual class with display information associated
vclassId = vclassIds.get(1);
} else {
vclassId = vclassIds.get(0);
}
vreq.setAttribute("displayType", vclassId);
rObj = JsonServlet.getSolrIndividualsByVClass(vclassId, vreq, ctx);
//This will get all the solr individuals by VClass (if one value) or the intersection
//i.e. individuals that have all the types for the different vclasses entered
rObj = super.process();
addShortViewRenderings(rObj);
return rObj;
}
//Get
/**
* Look through the return object. For each individual, render the short

View file

@ -1,197 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.controller.login;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.edit.Authenticate;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State;
/**
* A temporary means of displaying the Login templates within the SiteAdmin
* form.
*
* This class contains stuff that I swiped from {@link Authenticate}. The base
* class, {@link LoginTemplateHelperBase}, contains stuff that I swiped from
* {@link FreemarkerHttpServlet}.
*/
public class LoginTemplateHelper extends LoginTemplateHelperBase {
private static final Log log = LogFactory.getLog(LoginTemplateHelper.class);
/** If they are logging in, show them this form. */
public static final String TEMPLATE_LOGIN = "login-form.ftl";
/** If they are changing their password on first login, show them this form. */
public static final String TEMPLATE_FORCE_PASSWORD_CHANGE = "login-forcedPasswordChange.ftl";
/** Show error message */
public static final String TEMPLATE_SERVER_ERROR = Template.ERROR_MESSAGE.toString();
public static final String BODY_LOGIN_NAME = "loginName";
public static final String BODY_FORM_ACTION = "formAction";
public static final String BODY_INFO_MESSAGE = "infoMessage";
public static final String BODY_ERROR_MESSAGE = "errorMessage";
public static final String BODY_CANCEL_URL = "cancelUrl";
public LoginTemplateHelper(HttpServletRequest req) {
super(req);
}
/** Version for JSP page */
public String showLoginPage(HttpServletRequest request) {
VitroRequest vreq = new VitroRequest(request);
try {
State state = getCurrentLoginState(vreq);
log.debug("State on exit: " + state);
switch (state) {
case LOGGED_IN:
return "";
case FORCED_PASSWORD_CHANGE:
return doTemplate(vreq, showPasswordChangeScreen(vreq));
default:
return doTemplate(vreq, showLoginScreen(vreq));
}
} catch (TemplateProcessingException e) {
log.error(e.getMessage(), e);
return null;
} catch (Exception e) {
log.error(e, e);
try {
return doTemplate(vreq, showError(e));
} catch (TemplateProcessingException e1) {
log.error(e1.getMessage(), e1);
return null;
}
}
}
/** Version for Freemarker page */
public TemplateResponseValues showLoginPanel(VitroRequest vreq) {
try {
State state = getCurrentLoginState(vreq);
log.debug("State on exit: " + state);
switch (state) {
// RY Why does this case exist? We don't call this method if a user is logged in.
case LOGGED_IN:
return null;
case FORCED_PASSWORD_CHANGE:
// return doTemplate(vreq, showPasswordChangeScreen(vreq), body, config);
return showPasswordChangeScreen(vreq);
default:
// return doTemplate(vreq, showLoginScreen(vreq), body, config);
return showLoginScreen(vreq);
}
} catch (Exception e) {
log.error(e, e);
return showError(e);
}
}
/**
* User is just starting the login process. Be sure that we have a
* {@link LoginProcessBean} with the correct status. Show them the login
* screen.
*/
private TemplateResponseValues showLoginScreen(VitroRequest vreq)
throws IOException {
LoginProcessBean bean = LoginProcessBean.getBean(vreq);
bean.setState(State.LOGGING_IN);
log.trace("Going to login screen: " + bean);
TemplateResponseValues trv = new TemplateResponseValues(TEMPLATE_LOGIN);
trv.put(BODY_FORM_ACTION, getAuthenticateUrl(vreq));
trv.put(BODY_LOGIN_NAME, bean.getUsername());
String infoMessage = bean.getInfoMessageAndClear();
if (!infoMessage.isEmpty()) {
trv.put(BODY_INFO_MESSAGE, infoMessage);
}
String errorMessage = bean.getErrorMessageAndClear();
if (!errorMessage.isEmpty()) {
trv.put(BODY_ERROR_MESSAGE, errorMessage);
}
return trv;
}
/**
* The user has given the correct password, but now they are required to
* change it (unless they cancel out).
*/
private TemplateResponseValues showPasswordChangeScreen(VitroRequest vreq) {
LoginProcessBean bean = LoginProcessBean.getBean(vreq);
bean.setState(State.FORCED_PASSWORD_CHANGE);
log.trace("Going to password change screen: " + bean);
TemplateResponseValues trv = new TemplateResponseValues(
TEMPLATE_FORCE_PASSWORD_CHANGE);
trv.put(BODY_FORM_ACTION, getAuthenticateUrl(vreq));
trv.put(BODY_CANCEL_URL, getCancelUrl(vreq));
String errorMessage = bean.getErrorMessageAndClear();
if (!errorMessage.isEmpty()) {
trv.put(BODY_ERROR_MESSAGE, errorMessage);
}
return trv;
}
private TemplateResponseValues showError(Exception e) {
TemplateResponseValues trv = new TemplateResponseValues(
TEMPLATE_SERVER_ERROR);
trv.put(BODY_ERROR_MESSAGE, "Internal server error:<br /> " + e);
return trv;
}
/**
* We processed a response, and want to show a template. Version for JSP
* page.
*/
private String doTemplate(VitroRequest vreq, TemplateResponseValues values) throws TemplateProcessingException {
// Set it up like FreeMarkerHttpServlet.doGet() would do.
Map<String, Object> map = new HashMap<String, Object>();
map.putAll(getPageTemplateValues(vreq));
map.putAll(values.getMap());
return processTemplateToString(values.getTemplateName(), map, vreq);
}
/**
* Where are we in the process? Logged in? Not? Somewhere in between?
*/
private State getCurrentLoginState(HttpServletRequest request) {
if (LoginStatusBean.getBean(request).isLoggedIn()) {
return State.LOGGED_IN;
} else {
return LoginProcessBean.getBean(request).getState();
}
}
/** What's the URL for this servlet? */
private String getAuthenticateUrl(HttpServletRequest request) {
String contextPath = request.getContextPath();
String urlParams = "?login=block";
return contextPath + "/authenticate" + urlParams;
}
/** What's the URL for this servlet, with the cancel parameter added? */
private String getCancelUrl(HttpServletRequest request) {
String contextPath = request.getContextPath();
String urlParams = "?login=block&cancel=true";
return contextPath + "/authenticate" + urlParams;
}
}

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.controller.login;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
/**
* A temporary means of displaying the Login templates within the SiteAdmin
* form.
*
* The constructor insures that the ServletContext is set.
*/
public class LoginTemplateHelperBase extends FreemarkerHttpServlet {
private final ServletContext servletContext;
LoginTemplateHelperBase(HttpServletRequest req) {
this.servletContext = req.getSession().getServletContext();
}
public ServletContext getServletContext() {
return servletContext;
}
}

View file

@ -438,13 +438,17 @@ public class IndividualDaoSDB extends IndividualDaoJena {
final List<String> list =
new LinkedList<String>();
// get all labeled resources from any non-tbox and non-metadata graphs.
// get all labeled resources from any non-tbox and non-metadata graphs,
// as well as the unnamed graph (first pattern below)
String query = "SELECT DISTINCT ?ind WHERE { \n" +
" { ?ind <" + RDFS.label.getURI() + "> ?label } " +
" UNION { " +
" GRAPH ?g { ?ind <" + RDFS.label.getURI() +
"> ?label } \n" +
" FILTER (?g != <" + JenaDataSourceSetupBase
.JENA_APPLICATION_METADATA_MODEL + "> " +
" && !regex(str(?g),\"tbox\")) \n " +
" } " +
"}";
Query q = QueryFactory.create(query);

View file

@ -848,14 +848,19 @@ public class IndividualSDB extends IndividualImpl implements Individual {
String getTypes =
"CONSTRUCT{ <" + this.individualURI + "> <" + RDF.type +
"> ?types }\n" +
"WHERE{ GRAPH ?g"
"WHERE{ { GRAPH ?g"
+ " { <" + this.individualURI +"> <" +RDF.type+ "> ?types } \n"
+ WebappDaoFactorySDB.getFilterBlock(
graphVars, (direct
? WebappDaoFactorySDB.SDBDatasetMode
.ASSERTIONS_ONLY
: datasetMode))
+ "} \n";
+ "} \n"
// GRAPH-less pattern to support retrieving inferred types
// from the unnamed base graph, as in Sesame and OWLIM
+ ((datasetMode.equals(WebappDaoFactorySDB.SDBDatasetMode.ASSERTIONS_ONLY))
? "" : "UNION { <" + this.individualURI +"> <" +RDF.type+ "> ?types }" )
+ "} \n";
RDFService service = webappDaoFactory.getRDFService();
try {
tempModel = RDFServiceUtils.parseModel(

View file

@ -139,10 +139,8 @@ public class VClassDaoSDB extends VClassDaoJena {
try {
String queryText =
"SELECT COUNT( DISTINCT ?instance ) WHERE { \n" +
" GRAPH <urn:x-arq:UnionGraph> { \n" +
" ?class <"+VitroVocabulary.IN_CLASSGROUP+"> <"+vcg.getURI() +"> .\n" +
" ?instance a ?class . \n" +
" } \n" +
"} \n" ;
Query countQuery = QueryFactory.create(queryText, Syntax.syntaxARQ);

View file

@ -66,16 +66,29 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
Individual subject = wDaoFact.getIndividualDao().getIndividualByURI(subjectUri);
ObjectProperty objProp = wDaoFact.getObjectPropertyDao().getObjectPropertyByURI(predicateUri);
List<VClass> vclasses = wDaoFact.getVClassDao().getVClassesForProperty(subject.getVClassURI(), predicateUri);
//get all vclasses applicable to the individual subject
List<VClass> subjectVClasses = subject.getVClasses();
//using hashset to prevent duplicates
HashSet<String> vclassesURIs = new HashSet<String>();
//Get the range vclasses applicable for the property and each vclass for the subject
for(VClass subjectVClass: subjectVClasses) {
List<VClass> vclasses = wDaoFact.getVClassDao().getVClassesForProperty(subjectVClass.getURI(), predicateUri);
//add range vclass to hash
if(vclasses != null) {
for(VClass v: vclasses) {
vclassesURIs.add(v.getURI());
}
}
}
if (vclasses == null || vclasses.size() == 0) {
if (vclassesURIs.size() == 0) {
return optionsMap;
}
List<Individual> individuals = new ArrayList<Individual>();
HashSet<String> uriSet = new HashSet<String>();
for (VClass vclass : vclasses) {
List<Individual> inds = wDaoFact.getIndividualDao().getIndividualsByVClassURI(vclass.getURI(), -1, -1);
for (String vclassURI: vclassesURIs) {
List<Individual> inds = wDaoFact.getIndividualDao().getIndividualsByVClassURI(vclassURI, -1, -1);
for (Individual ind : inds) {
if (!uriSet.contains(ind.getURI())) {
uriSet.add(ind.getURI());
@ -88,7 +101,7 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
individuals = removeIndividualsAlreadyInRange(
individuals, stmts, predicateUri, objectUri);
// Collections.sort(individuals,new compareIndividualsByName());
// Collections.sort(individuals,new compareIndividualsByName());a
for (Individual ind : individuals) {
String uri = ind.getURI();

View file

@ -39,7 +39,17 @@ public class DateTimeIntervalFormGenerator extends
public EditConfigurationVTwo getEditConfiguration(VitroRequest vreq,
HttpSession session) {
EditConfigurationVTwo conf = new EditConfigurationVTwo();
this.setupEditConfiguration(conf, vreq, session);
//Prepare
prepare(vreq, conf);
return conf;
}
//Enables refactoring by other generators, as this code can be used to partially setup an
//edit configuration object which can then be extended - prepare can then be called independently
//enabling sparql queries to be evaluated using the final edit configuration object
public void setupEditConfiguration(EditConfigurationVTwo conf, VitroRequest vreq, HttpSession session) {
initBasics(conf, vreq);
initPropertyParameters(vreq, session, conf);
initObjectPropForm(conf, vreq);
@ -48,11 +58,11 @@ public class DateTimeIntervalFormGenerator extends
conf.setVarNameForSubject("subject");
conf.setVarNameForPredicate("toDateTimeInterval");
conf.setVarNameForObject("intervalNode");
conf.setVarNameForObject(getNodeVar());
conf.setN3Optional(Arrays.asList(n3ForStart, n3ForEnd));
conf.setN3Optional(n3ForStart, n3ForEnd);
conf.addNewResource("intervalNode", DEFAULT_NS_FOR_NEW_RESOURCE);
conf.addNewResource(getNodeVar(), DEFAULT_NS_FOR_NEW_RESOURCE);
conf.addNewResource("startNode", DEFAULT_NS_FOR_NEW_RESOURCE);
conf.addNewResource("endNode", DEFAULT_NS_FOR_NEW_RESOURCE);
@ -61,7 +71,7 @@ public class DateTimeIntervalFormGenerator extends
conf.addSparqlForExistingLiteral(
"endField-value", existingEndDateQuery);
conf.addSparqlForExistingUris(
"intervalNode", existingIntervalNodeQuery);
getNodeVar(), existingIntervalNodeQuery);
conf.addSparqlForExistingUris("startNode", existingStartNodeQuery);
conf.addSparqlForExistingUris("endNode", existingEndNodeQuery);
conf.addSparqlForExistingUris(
@ -85,79 +95,87 @@ public class DateTimeIntervalFormGenerator extends
conf.addValidator(new DateTimeIntervalValidationVTwo("startField","endField"));
//Adding additional data, specifically edit mode
addFormSpecificData(conf, vreq);
//Prepare
prepare(vreq, conf);
return conf;
}
final static String n3ForStart =
"?subject <" + toDateTimeInterval + "> ?intervalNode . \n" +
"?intervalNode a <" + intervalType + "> . \n" +
"?intervalNode <" + intervalToStart + "> ?startNode . \n" +
final String n3ForStart =
"?subject <" + getToDateTimeIntervalPredicate() + "> " + getNodeN3Var() + " . \n" +
getNodeN3Var() + " a <" + intervalType + "> . \n" +
getNodeN3Var() + " <" + intervalToStart + "> ?startNode . \n" +
"?startNode a <" + dateTimeValueType + "> . \n" +
"?startNode <" + dateTimeValue + "> ?startField-value . \n" +
"?startNode <" + dateTimePrecision + "> ?startField-precision . \n";
final static String n3ForEnd =
"?subject <" + toDateTimeInterval + "> ?intervalNode . \n" +
"?intervalNode a <" + intervalType + "> . \n" +
"?intervalNode <" + intervalToEnd + "> ?endNode . \n" +
final String n3ForEnd =
"?subject <" + getToDateTimeIntervalPredicate() + "> " + getNodeN3Var() + " . \n" +
getNodeN3Var() + " a <" + intervalType + "> . \n" +
getNodeN3Var() + " <" + intervalToEnd + "> ?endNode . \n" +
"?endNode a <" + dateTimeValueType + "> . \n" +
"?endNode <" + dateTimeValue + "> ?endField-value . \n" +
"?endNode <" + dateTimePrecision + "> ?endField-precision .";
final static String existingStartDateQuery =
final String existingStartDateQuery =
"SELECT ?existingDateStart WHERE { \n" +
"?subject <" + toDateTimeInterval + "> ?existingIntervalNode . \n" +
"?intervalNode a <" + intervalType + "> . \n" +
"?intervalNode <" + intervalToStart + "> ?startNode . \n" +
"?subject <" + getToDateTimeIntervalPredicate() + "> ?existingIntervalNode . \n" +
getNodeN3Var() + " a <" + intervalType + "> . \n" +
getNodeN3Var() + " <" + intervalToStart + "> ?startNode . \n" +
"?startNode a <" + dateTimeValueType + "> . \n" +
"?startNode <" + dateTimeValue + "> ?existingDateStart }";
final static String existingEndDateQuery =
final String existingEndDateQuery =
"SELECT ?existingEndDate WHERE { \n" +
"?subject <" + toDateTimeInterval + "> ?existingIntervalNode . \n" +
"?intervalNode a <" + intervalType + "> . \n" +
"?intervalNode <" + intervalToEnd + "> ?endNode . \n" +
"?subject <" + getToDateTimeIntervalPredicate() + "> ?existingIntervalNode . \n" +
getNodeN3Var() + " a <" + intervalType + "> . \n" +
getNodeN3Var() + " <" + intervalToEnd + "> ?endNode . \n" +
"?endNode a <" + dateTimeValueType + "> . \n " +
"?endNode <" + dateTimeValue + "> ?existingEndDate . }";
final static String existingIntervalNodeQuery =
final String existingIntervalNodeQuery =
"SELECT ?existingIntervalNode WHERE { \n" +
"?subject <" + toDateTimeInterval + "> ?existingIntervalNode . \n" +
"?subject <" + getToDateTimeIntervalPredicate() + "> ?existingIntervalNode . \n" +
"?existingIntervalNode a <" + intervalType + "> . }";
final static String existingStartNodeQuery =
final String existingStartNodeQuery =
"SELECT ?existingStartNode WHERE { \n" +
"?subject <" + toDateTimeInterval + "> ?existingIntervalNode . \n" +
"?intervalNode a <" + intervalType + "> . \n" +
"?intervalNode <" + intervalToStart + "> ?existingStartNode . \n" +
"?subject <" + getToDateTimeIntervalPredicate() + "> ?existingIntervalNode . \n" +
getNodeN3Var() + " a <" + intervalType + "> . \n" +
getNodeN3Var() + " <" + intervalToStart + "> ?existingStartNode . \n" +
"?existingStartNode a <" + dateTimeValueType + "> .} ";
final static String existingEndNodeQuery =
final String existingEndNodeQuery =
"SELECT ?existingEndNode WHERE { \n" +
"?subject <" + toDateTimeInterval + "> ?existingIntervalNode . \n" +
"?intervalNode a <" + intervalType + "> . \n" +
"?intervalNode <" + intervalToEnd + "> ?existingEndNode . \n" +
"?subject <" + getToDateTimeIntervalPredicate() + "> ?existingIntervalNode . \n" +
getNodeN3Var() + " a <" + intervalType + "> . \n" +
getNodeN3Var() + " <" + intervalToEnd + "> ?existingEndNode . \n" +
"?existingEndNode a <" + dateTimeValueType + "> .} ";
final static String existingStartPrecisionQuery =
final String existingStartPrecisionQuery =
"SELECT ?existingStartPrecision WHERE { \n" +
"?subject <" + toDateTimeInterval + "> ?existingIntervalNode . \n" +
"?intervalNode a <" + intervalType + "> . \n" +
"?intervalNode <" + intervalToStart + "> ?startNode . \n" +
"?subject <" + getToDateTimeIntervalPredicate() + "> ?existingIntervalNode . \n" +
getNodeN3Var() + " a <" + intervalType + "> . \n" +
getNodeN3Var() + " <" + intervalToStart + "> ?startNode . \n" +
"?startNode a <" + dateTimeValueType + "> . \n" +
"?startNode <" + dateTimePrecision + "> ?existingStartPrecision . }";
final static String existingEndPrecisionQuery =
final String existingEndPrecisionQuery =
"SELECT ?existingEndPrecision WHERE { \n" +
"?subject <" + toDateTimeInterval + "> ?existingIntervalNode . \n" +
"?intervalNode a <" + intervalType + "> . \n" +
"?intervalNode <" + intervalToEnd + "> ?endNode . \n" +
"?subject <" + getToDateTimeIntervalPredicate() + "> ?existingIntervalNode . \n" +
getNodeN3Var() + " a <" + intervalType + "> . \n" +
getNodeN3Var() + " <" + intervalToEnd + "> ?endNode . \n" +
"?endNode a <" + dateTimeValueType + "> . \n" +
"?endNode <" + dateTimePrecision + "> ?existingEndPrecision . }";
public String getToDateTimeIntervalPredicate() {
return toDateTimeInterval;
}
public String getNodeVar() {
return "intervalNode";
}
public String getNodeN3Var() {
return "?" + getNodeVar();
}
//Adding form specific data such as edit mode
public void addFormSpecificData(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
HashMap<String, Object> formSpecificData = new HashMap<String, Object>();

View file

@ -27,7 +27,7 @@ public class DateTimeValueFormGenerator extends BaseEditConfigurationGenerator
implements EditConfigurationGenerator {
final static String vivoCore = "http://vivoweb.org/ontology/core#";
final static String toDateTimeValue = vivoCore + "dateTimeValue";
final String toDateTimeValue = vivoCore + "dateTimeValue";
final static String valueType = vivoCore + "DateTimeValue";
final static String dateTimeValue = vivoCore + "dateTime";
final static String dateTimePrecision = vivoCore + "dateTimePrecision";
@ -41,23 +41,23 @@ public class DateTimeValueFormGenerator extends BaseEditConfigurationGenerator
initPropertyParameters(vreq, session, conf);
initObjectPropForm(conf, vreq);
conf.setTemplate("dateTimeValueForm.ftl");
conf.setTemplate(this.getTemplate());
conf.setVarNameForSubject("subject");
conf.setVarNameForPredicate("toDateTimeValue");
conf.setVarNameForObject("valueNode");
conf.setN3Optional(Arrays.asList(n3ForValue));
conf.setN3Optional(Arrays.asList(getN3ForValue()));
conf.addNewResource("valueNode", DEFAULT_NS_FOR_NEW_RESOURCE);
conf.addSparqlForExistingLiteral(
"dateTimeField-value", existingDateTimeValueQuery);
"dateTimeField-value", getExistingDateTimeValueQuery());
conf.addSparqlForExistingUris(
"dateTimeField-precision", existingPrecisionQuery);
conf.addSparqlForExistingUris("valueNode", existingNodeQuery);
"dateTimeField-precision", getExistingPrecisionQuery());
conf.addSparqlForExistingUris("valueNode", getExistingNodeQuery());
FieldVTwo dateTimeField = new FieldVTwo().setName("dateTimeField");
FieldVTwo dateTimeField = new FieldVTwo().setName(this.getDateTimeFieldName());
dateTimeField.setEditElement(new DateTimeWithPrecisionVTwo(dateTimeField,
VitroVocabulary.Precision.SECOND.uri(),
VitroVocabulary.Precision.NONE.uri()));
@ -67,34 +67,61 @@ public class DateTimeValueFormGenerator extends BaseEditConfigurationGenerator
//Adding additional data, specifically edit mode
addFormSpecificData(conf, vreq);
//prepare
prepare(vreq, conf);
return conf;
}
prepare(vreq, conf);
return conf;
}
final static String n3ForValue =
"?subject <" + toDateTimeValue + "> ?valueNode . \n" +
//Writing these as methods instead of static strings allows the method getToDateTimeValuePredicate
//to be called after the class has been initialized - this is important for subclasses of this generator
//that rely on vreq for predicate
protected String getN3ForValue() {
return "?subject <" + this.getToDateTimeValuePredicate() + "> ?valueNode . \n" +
"?valueNode a <" + valueType + "> . \n" +
"?valueNode <" + dateTimeValue + "> ?dateTimeField-value . \n" +
"?valueNode <" + dateTimePrecision + "> ?dateTimeField-precision .";
"?valueNode <" + dateTimePrecision + "> ?dateTimeField-precision .";
}
final static String existingDateTimeValueQuery =
"SELECT ?existingDateTimeValue WHERE { \n" +
"?subject <" + toDateTimeValue + "> ?existingValueNode . \n" +
protected String getExistingDateTimeValueQuery () {
return "SELECT ?existingDateTimeValue WHERE { \n" +
"?subject <" + this.getToDateTimeValuePredicate() + "> ?existingValueNode . \n" +
"?existingValueNode a <" + valueType + "> . \n" +
"?existingValueNode <" + dateTimeValue + "> ?existingDateTimeValue }";
}
final static String existingPrecisionQuery =
"SELECT ?existingPrecision WHERE { \n" +
"?subject <" + toDateTimeValue + "> ?existingValueNode . \n" +
protected String getExistingPrecisionQuery() {
return "SELECT ?existingPrecision WHERE { \n" +
"?subject <" + this.getToDateTimeValuePredicate() + "> ?existingValueNode . \n" +
"?existingValueNode a <" + valueType + "> . \n" +
"?existingValueNode <" + dateTimePrecision + "> ?existingPrecision }";
final static String existingNodeQuery =
"SELECT ?existingNode WHERE { \n" +
"?subject <" + toDateTimeValue + "> ?existingNode . \n" +
}
protected String getExistingNodeQuery() {
return "SELECT ?existingNode WHERE { \n" +
"?subject <" + this.getToDateTimeValuePredicate() + "> ?existingNode . \n" +
"?existingNode a <" + valueType + "> }";
}
public static String getNodeVar() {
return "valueNode";
}
public static String getNodeN3Var() {
return "?" + getNodeVar();
}
//isolating the predicate in this fashion allows this class to be subclassed for other date time value
//properties
protected String getToDateTimeValuePredicate() {
return this.toDateTimeValue;
}
protected String getDateTimeFieldName() {
return "dateTimeField";
}
protected String getTemplate() {
return "dateTimeValueForm.ftl";
}
//Adding form specific data such as edit mode
public void addFormSpecificData(EditConfigurationVTwo editConfiguration, VitroRequest vreq) {
HashMap<String, Object> formSpecificData = new HashMap<String, Object>();

View file

@ -7,6 +7,7 @@ import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -101,15 +102,23 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
}
protected List<String> getRangeTypes(VitroRequest vreq) {
Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq);
String predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq);
String predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
WebappDaoFactory wDaoFact = vreq.getWebappDaoFactory();
List<String> types = new ArrayList<String>();
List <VClass> vclasses = new ArrayList<VClass>();
vclasses = wDaoFact.getVClassDao().getVClassesForProperty(subject.getVClassURI(),predicateUri);
for(VClass v: vclasses) {
types.add(v.getURI());
}
//Get all vclasses applicable to subject
List<VClass> vClasses = subject.getVClasses();
HashSet<String> typesHash = new HashSet<String>();
for(VClass vclass: vClasses) {
List<VClass> rangeVclasses = wDaoFact.getVClassDao().getVClassesForProperty(vclass.getURI(),predicateUri);
if(rangeVclasses != null) {
for(VClass range: rangeVclasses) {
//a hash will keep a unique list of types and so prevent duplicates
typesHash.add(range.getURI());
}
}
}
types.addAll(typesHash);
return types;
}

View file

@ -0,0 +1,11 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
//For use with classes that explicitly modify configurations through AJAX requests
public interface EditConfigurationAJAXGenerator {
public void modifyEditConfiguration( EditConfigurationVTwo config, VitroRequest vreq ) throws Exception;
}

View file

@ -128,10 +128,11 @@ public class ProcessSparqlDataGetterN3 extends ProcessDataGetterAbstract {
existingLiteralValues.put(this.getVarName("query", counter),
new ArrayList<Literal>(Arrays.asList(queryLiteral)));
existingUriValues.put(this.getVarName("queryModel", counter),
//Query model is optional
if(queryModelResource != null && queryModelResource.getURI() != null) {
existingUriValues.put(this.getVarName("queryModel", counter),
new ArrayList<String>(Arrays.asList(queryModelResource.getURI())));
}
}
} catch(Exception ex) {

View file

@ -0,0 +1,132 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.controller;
import static edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils.getPredicateUri;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
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.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.DirectRedirectResponseValues;
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.controller.json.GetDataForPage;
import edu.cornell.mannlib.vitro.webapp.controller.json.GetEntitiesByVClass;
import edu.cornell.mannlib.vitro.webapp.controller.json.GetEntitiesByVClassContinuation;
import edu.cornell.mannlib.vitro.webapp.controller.json.GetRenderedSolrIndividualsByVClass;
import edu.cornell.mannlib.vitro.webapp.controller.json.GetSolrIndividualsByVClass;
import edu.cornell.mannlib.vitro.webapp.controller.json.GetSolrIndividualsByVClasses;
import edu.cornell.mannlib.vitro.webapp.controller.json.GetVClassesForVClassGroup;
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.EditConfigurationUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditSubmissionUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.MultiValueEditSubmission;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.EditConfigurationAJAXGenerator;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators.EditConfigurationGenerator;
import edu.cornell.mannlib.vitro.webapp.utils.log.LogUtils;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.edit.EditConfigurationTemplateModel;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.edit.MultiValueEditSubmissionTemplateModel;
/**
* This servlet is intended to handle all requests to create a form for use
* by the N3 editing system. It will examine the request parameters, determine
* which form to use, execute a EditConfiguration setup, and evaluate the
* view indicated by the EditConfiguration.
*
* Do not add code to this class to achieve some behavior in a
* form. Try adding the behavior logic to the code that generates the
* EditConfiguration for the form.
*/
public class EditRequestAJAXController extends VitroHttpServlet {
private static final long serialVersionUID = 1L;
public static Log log = LogFactory.getLog(EditRequestDispatchController.class);
protected Actions requiredActions(VitroRequest vreq) {
return SimplePermission.DO_FRONT_END_EDITING.ACTIONS;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
log.debug(LogUtils.formatRequestProperties(log, "debug", req));
VitroRequest vreq = new VitroRequest(req);
try {
//Get edit configuration object based on editk key in request
EditConfigurationVTwo config = getEditConfiguration(vreq);
//Get the generator name also from the request parameter
String generatorName = vreq.getParameter("generator");
String javaGeneratorName = "edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators." + generatorName;
//TODO: Add this method to generators, but for now constructing a new class of generator specifically for AJAX requests
EditConfigurationAJAXGenerator generator = getAJAXGenerator(javaGeneratorName, vreq, vreq.getSession());
//run the modification
generator.modifyEditConfiguration(config, vreq);
} catch(Exception ex) {
log.error("An error occurred in retrieving configuration and/or generator ", ex);
}
}
protected EditConfigurationVTwo getEditConfiguration(VitroRequest vreq) {
EditConfigurationVTwo config = EditConfigurationVTwo.getConfigFromSession(vreq.getSession(), vreq);
return config;
}
private EditConfigurationAJAXGenerator getAJAXGenerator(
String editConfGeneratorName, VitroRequest vreq, HttpSession session) throws Exception {
EditConfigurationAJAXGenerator EditConfigurationVTwoGenerator = null;
Object object = null;
try {
Class classDefinition = Class.forName(editConfGeneratorName);
object = classDefinition.newInstance();
EditConfigurationVTwoGenerator = (EditConfigurationAJAXGenerator) object;
} catch (InstantiationException e) {
System.out.println(e);
} catch (IllegalAccessException e) {
System.out.println(e);
} catch (ClassNotFoundException e) {
System.out.println(e);
}
if(EditConfigurationVTwoGenerator == null){
throw new Error("Could not find EditConfigurationVTwoGenerator " + editConfGeneratorName);
} else {
return EditConfigurationVTwoGenerator;
}
}
}

View file

@ -155,12 +155,25 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
private EditConfigurationVTwo setupEditConfiguration(String editConfGeneratorName,
VitroRequest vreq) throws Exception {
HttpSession session = vreq.getSession();
EditConfigurationVTwo editConfig =
makeEditConfigurationVTwo( editConfGeneratorName, vreq, session);
//edit key is set here, NOT in the generator class
String editKey = EditConfigurationUtils.getEditKey(vreq);
editConfig.setEditKey(editKey);
//Originally, this code called makeEditConfiguration before checking for/setting the edit key
//which meant that in the case of page reload on an error, you would recreate an edit configuration
//using the generator
//Given recent updates enabling modification of edit configuration dynamically through AJAX,
//we will first check whether the edit key exists and if there is already an edit configuration
//in the session - and then will utilize the edit configuration that already exists
//edit key is set here, NOT in the generator class
EditConfigurationVTwo editConfig = null;
EditConfigurationVTwo existingConfig = EditConfigurationVTwo.getConfigFromSession(session, vreq);
if(existingConfig != null) {
editConfig = existingConfig;
} else {
editConfig =
makeEditConfigurationVTwo( editConfGeneratorName, vreq, session);
}
String editKey = EditConfigurationUtils.getEditKey(vreq);
editConfig.setEditKey(editKey);
//put edit configuration in session so it can be accessed on form submit.
EditConfigurationVTwo.putConfigInSession(editConfig, session);

View file

@ -35,7 +35,7 @@ public class FileStorageSetup implements ServletContextListener {
* {@link ConfigurationProperties} for the vivo home directory. The file
* storage base directory is in a subdirectory below this one.
*/
public static final String PROPERTY_VITRO_HOME_DIR = "vitro.home.directory";
public static final String PROPERTY_VITRO_HOME_DIR = "vitro.home";
public static final String FILE_STORAGE_SUBDIRECTORY = "uploads";
/**

View file

@ -94,6 +94,10 @@ public class FileServingServlet extends VitroHttpServlet {
String actualFilename = findAndValidateFilename(fileInfo, path);
in = openImageInputStream(fileInfo, actualFilename);
} catch (FileServingException e) {
log.info("Failed to serve the file at '" + path + "' -- " + e.getMessage());
in = openMissingLinkImage(request);
mimeType = "image/png";
} catch (Exception e) {
log.warn("Failed to serve the file at '" + path + "' -- " + e.getMessage());
in = openMissingLinkImage(request);

View file

@ -21,6 +21,8 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
import freemarker.cache.WebappTemplateLoader;
import freemarker.template.Configuration;
@ -67,36 +69,36 @@ public class StartupStatusDisplayFilter implements Filter {
statusAlreadyDisplayed = true;
}
private void displayStartupStatus(ServletRequest req, ServletResponse resp) throws IOException,
ServletException {
HttpServletResponse hResp = (HttpServletResponse) resp;
private void displayStartupStatus(ServletRequest req, ServletResponse resp)
throws IOException, ServletException {
HttpServletResponse hresp = (HttpServletResponse) resp;
HttpServletRequest hreq = (HttpServletRequest) req;
try {
Map<String, Object> bodyMap = new HashMap<String, Object>();
bodyMap.put("status", ss);
bodyMap.put("showLink", !isFatal());
bodyMap.put("contextPath", getContextPath());
bodyMap.put("applicationName", getApplicationName());
HttpServletRequest httpreq = (HttpServletRequest) req;
String url = "";
String path = httpreq.getRequestURI();
if( path != null ){
url = path;
}
String query = httpreq.getQueryString();
if( !StringUtils.isEmpty( query )){
url = url + "?" + query;
}
bodyMap.put("url", url );
bodyMap.put("applicationName", getApplicationName());
hResp.setContentType("text/html;charset=UTF-8");
hResp.setStatus(SC_INTERNAL_SERVER_ERROR);
String url = "";
String path = hreq.getRequestURI();
if (path != null) {
url = path;
}
String query = hreq.getQueryString();
if (!StringUtils.isEmpty(query)) {
url = url + "?" + query;
}
bodyMap.put("url", url);
hresp.setContentType("text/html;charset=UTF-8");
hresp.setStatus(SC_INTERNAL_SERVER_ERROR);
Template tpl = loadFreemarkerTemplate();
tpl.process(bodyMap, hResp.getWriter());
tpl.process(bodyMap, hresp.getWriter());
} catch (TemplateException e) {
throw new ServletException("Problem with Freemarker Template", e);
}
@ -114,7 +116,9 @@ public class StartupStatusDisplayFilter implements Filter {
private Object getApplicationName() {
String name = "";
try {
ApplicationBean app = ApplicationBean.getAppBean(ctx);
WebappDaoFactory wadf = (WebappDaoFactory) ctx
.getAttribute("webappDaoFactory");
ApplicationBean app = wadf.getApplicationDao().getApplicationBean();
name = app.getApplicationName();
} catch (Exception e) {
// deal with problems below

View file

@ -38,7 +38,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
@ -82,19 +81,10 @@ public class VitroRequestPrep implements Filter {
};
private ServletContext _context;
private ApplicationBean _appbean;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
_context = filterConfig.getServletContext();
Object o = _context.getAttribute("applicationBean");
if (o instanceof ApplicationBean) {
_appbean = (ApplicationBean) o;
} else {
_appbean = new ApplicationBean();
}
log.debug("VitroRequestPrep: AppBean theme " + _appbean.getThemeDir());
}
@Override
@ -132,9 +122,6 @@ public class VitroRequestPrep implements Filter {
VitroRequest vreq = new VitroRequest(req);
//-- setup appBean --//
vreq.setAppBean(_appbean);
//-- setup DAO factory --//
WebappDaoFactory wdf = getWebappDaoFactory(vreq);
//TODO: get accept-language from request and set as preferred languages

View file

@ -0,0 +1,231 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.ResourceBundle.Control;
import java.util.concurrent.atomic.AtomicReference;
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.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* Provides access to a bundle of text strings, based on the name of the bundle,
* the Locale of the requesting browser, and the current theme directory.
*
* If the bundle name is not specified, the default name of "all" is used.
*
* If a requested bundle is not found, no error is thrown. Instead, an empty
* bundle is returned that produces error message strings when asked for text.
*/
public class I18n {
private static final Log log = LogFactory.getLog(I18n.class);
public static final String DEFAULT_BUNDLE_NAME = "all";
private static final String PROPERTY_DEVELOPER_DEFEAT_CACHE = "developer.defeatI18nCache";
/**
* This is where the work gets done. Not declared final, so it can be
* modified in unit tests.
*/
private static I18n instance = new I18n();
// ----------------------------------------------------------------------
// Static methods
// ----------------------------------------------------------------------
/**
* A convenience method to get a bundle and format the text.
*/
public static String text(String bundleName, HttpServletRequest req,
String key, Object... parameters) {
return bundle(bundleName, req).text(key, parameters);
}
/**
* A convenience method to get the default bundle and format the text.
*/
public static String text(HttpServletRequest req, String key,
Object... parameters) {
return bundle(req).text(key, parameters);
}
/**
* Get a I18nBundle by this name.
*/
public static I18nBundle bundle(String bundleName, HttpServletRequest req) {
return instance.getBundle(bundleName, req);
}
/**
* Get the default I18nBundle.
*/
public static I18nBundle bundle(HttpServletRequest req) {
return instance.getBundle(DEFAULT_BUNDLE_NAME, req);
}
// ----------------------------------------------------------------------
// The instance
// ----------------------------------------------------------------------
/** Holds the current theme directory, as far as we know. */
private AtomicReference<String> themeDirectory = new AtomicReference<String>(
"");
/**
* Get an I18nBundle by this name. The request provides the preferred
* Locale, the application directory, the theme directory and the
* development mode flag.
*
* If the request indicates that the system is in development mode, then the
* cache is cleared on each request.
*
* If the theme directory has changed, the cache is cleared.
*/
private I18nBundle getBundle(String bundleName, HttpServletRequest req) {
log.debug("Getting bundle '" + bundleName + "'");
try {
checkDevelopmentMode(req);
checkForChangeInThemeDirectory(req);
String dir = themeDirectory.get();
ServletContext ctx = req.getSession().getServletContext();
ResourceBundle.Control control = getControl(ctx, dir);
ResourceBundle rb = ResourceBundle.getBundle(bundleName,
req.getLocale(), control);
return new I18nBundle(bundleName, rb);
} catch (MissingResourceException e) {
log.warn("Didn't find text bundle '" + bundleName + "'");
return I18nBundle.emptyBundle(bundleName);
} catch (Exception e) {
log.error("Failed to create text bundle '" + bundleName + "'", e);
return I18nBundle.emptyBundle(bundleName);
}
}
/**
* If we are in development mode, clear the cache on each request.
*/
private void checkDevelopmentMode(HttpServletRequest req) {
ConfigurationProperties bean = ConfigurationProperties.getBean(req);
String flag = bean
.getProperty(PROPERTY_DEVELOPER_DEFEAT_CACHE, "false");
if (Boolean.valueOf(flag.trim())) {
log.debug("In development mode - clearing the cache.");
ResourceBundle.clearCache();
}
}
/**
* If the theme directory has changed from before, clear the cache of all
* ResourceBundles.
*/
private void checkForChangeInThemeDirectory(HttpServletRequest req) {
String currentDir = new VitroRequest(req).getAppBean().getThemeDir();
String previousDir = themeDirectory.getAndSet(currentDir);
if (!currentDir.equals(previousDir)) {
log.debug("Theme directory changed from '" + previousDir + "' to '"
+ currentDir + "' - clearing the cache.");
ResourceBundle.clearCache();
}
}
/**
* Override this method in the unit tests, to return a more testable Control
* instance.
*/
protected Control getControl(ServletContext ctx, String dir) {
return new ThemeBasedControl(ctx, dir);
}
// ----------------------------------------------------------------------
// Control classes for instantiating ResourceBundles
// ----------------------------------------------------------------------
/**
* Instead of looking in the classpath, look in the theme i18n directory and
* the application i18n directory.
*/
private static class ThemeBasedControl extends ResourceBundle.Control {
private static final String BUNDLE_DIRECTORY = "i18n/";
private final ServletContext ctx;
private final String themeDirectory;
public ThemeBasedControl(ServletContext ctx, String themeDirectory) {
this.ctx = ctx;
this.themeDirectory = themeDirectory;
}
/**
* Don't look for classes to satisfy the request, just property files.
*/
@Override
public List<String> getFormats(String baseName) {
return FORMAT_PROPERTIES;
}
/**
* Don't look in the class path, look in the current servlet context, in
* the bundle directory under the theme directory and in the bundle
* directory under the application directory.
*/
@Override
public ResourceBundle newBundle(String baseName, Locale locale,
String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException,
IOException {
checkArguments(baseName, locale, format);
log.debug("Creating bundle for '" + baseName + "', " + locale
+ ", '" + format + "', " + reload);
String bundleName = toBundleName(baseName, locale);
if (bundleName == null) {
throw new NullPointerException("bundleName may not be null.");
}
String themeI18nPath = "/" + themeDirectory + BUNDLE_DIRECTORY;
String appI18nPath = "/" + BUNDLE_DIRECTORY;
log.debug("Paths are '" + themeI18nPath + "' and '" + appI18nPath
+ "'");
return VitroResourceBundle.getBundle(bundleName, ctx, appI18nPath,
themeI18nPath, this);
}
/**
* The documentation for ResourceBundle.Control.newBundle() says I
* should throw these exceptions.
*/
private void checkArguments(String baseName, Locale locale,
String format) {
if (baseName == null) {
throw new NullPointerException("baseName may not be null.");
}
if (locale == null) {
throw new NullPointerException("locale may not be null.");
}
if (format == null) {
throw new NullPointerException("format may not be null.");
}
if (!FORMAT_DEFAULT.contains(format)) {
throw new IllegalArgumentException(
"format must be one of these: " + FORMAT_DEFAULT);
}
}
}
}

View file

@ -0,0 +1,102 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.Enumeration;
import java.util.ResourceBundle;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A wrapper for a ResourceBundle that will not throw an exception, no matter
* what string you request.
*
* If the ResourceBundle was not found, or if it doesn't contain the requested
* key, an error message string is returned, to help the developer diagnose the
* problem.
*/
public class I18nBundle {
private static final Log log = LogFactory.getLog(I18nBundle.class);
private static final String MESSAGE_BUNDLE_NOT_FOUND = "Text bundle ''{0}'' not found.";
private static final String MESSAGE_KEY_NOT_FOUND = "Text bundle ''{0}'' has no text for ''{1}''";
public static I18nBundle emptyBundle(String bundleName) {
return new I18nBundle(bundleName);
}
private final String bundleName;
private final ResourceBundle resources;
private final String notFoundMessage;
private I18nBundle(String bundleName) {
this(bundleName, new EmptyResourceBundle(), MESSAGE_BUNDLE_NOT_FOUND);
}
public I18nBundle(String bundleName, ResourceBundle resources) {
this(bundleName, resources, MESSAGE_KEY_NOT_FOUND);
}
private I18nBundle(String bundleName, ResourceBundle resources, String notFoundMessage) {
if (bundleName == null) {
throw new IllegalArgumentException("bundleName may not be null");
}
if (bundleName.isEmpty()) {
throw new IllegalArgumentException("bundleName may not be empty");
}
if (resources == null) {
throw new NullPointerException("resources may not be null.");
}if (notFoundMessage == null) {
throw new NullPointerException("notFoundMessage may not be null.");
}
this.bundleName = bundleName;
this.resources = resources;
this.notFoundMessage = notFoundMessage;
}
public String text(String key, Object... parameters) {
log.debug("Asking for '" + key + "' from bundle '" + bundleName + "'");
String textString;
if (resources.containsKey(key)) {
textString = resources.getString(key);
return formatString(textString, parameters);
} else {
String message = MessageFormat.format(notFoundMessage, bundleName,
key);
log.warn(message);
return "ERROR: " + message;
}
}
private static String formatString(String textString, Object... parameters) {
if (parameters.length == 0) {
return textString;
} else {
return MessageFormat.format(textString, parameters);
}
}
/**
* A resource bundle that contains no strings.
*/
public static class EmptyResourceBundle extends ResourceBundle {
@Override
public Enumeration<String> getKeys() {
return Collections.enumeration(Collections.<String> emptySet());
}
@Override
protected Object handleGetObject(String key) {
if (key == null) {
throw new NullPointerException("key may not be null.");
}
return null;
}
}
}

View file

@ -0,0 +1,211 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.servlet.ServletContext;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Works like a PropertyResourceBundle with two exceptions:
*
* It looks for the file in both the i18n directory of the theme and in the i18n
* directory of the application. Properties found in the theme override those
* found in the application.
*
* It allows a property to take its contents from a file. File paths are
* relative to the i18n directory. Again, a file in the theme will override one
* in the application.
*
* If a property has a value (after overriding) of "@@file <filepath>", the
* bundle looks for the file relative to the i18n directory of the theme, then
* relative to the i18n directory of the application. If the file is not found
* in either location, a warning is written to the log and the property will
* contain an error message for displayed.
*
* Note that the filename is not manipulated for Locale, so the author of the
* properties files must do it explicitly. For example:
*
* In all.properties: account_email_html = @@file accountEmail.html
*
* In all_es.properties: account_email_html = @@file accountEmail_es.html
*/
public class VitroResourceBundle extends ResourceBundle {
private static final Log log = LogFactory.getLog(VitroResourceBundle.class);
private static final String FILE_FLAG = "@@file ";
private static final String MESSAGE_FILE_NOT_FOUND = "File {1} not found for property {0}.";
// ----------------------------------------------------------------------
// Factory method
// ----------------------------------------------------------------------
public static VitroResourceBundle getBundle(String bundleName,
ServletContext ctx, String appI18nPath, String themeI18nPath,
Control control) {
try {
return new VitroResourceBundle(bundleName, ctx, appI18nPath,
themeI18nPath, control);
} catch (FileNotFoundException e) {
log.debug(e);
return null;
} catch (Exception e) {
log.warn(e, e);
return null;
}
}
// ----------------------------------------------------------------------
// The instance
// ----------------------------------------------------------------------
private final String bundleName;
private final ServletContext ctx;
private final String appI18nPath;
private final String themeI18nPath;
private final Control control;
private final Properties defaults;
private final Properties properties;
private VitroResourceBundle(String bundleName, ServletContext ctx,
String appI18nPath, String themeI18nPath, Control control)
throws IOException {
this.bundleName = bundleName;
this.ctx = ctx;
this.appI18nPath = appI18nPath;
this.themeI18nPath = themeI18nPath;
this.control = control;
this.defaults = new Properties();
this.properties = new Properties(this.defaults);
loadProperties();
loadReferencedFiles();
}
private void loadProperties() throws IOException {
String resourceName = control.toResourceName(bundleName, "properties");
String defaultsPath = joinPath(appI18nPath, resourceName);
String propertiesPath = joinPath(themeI18nPath, resourceName);
File defaultsFile = locateFile(defaultsPath);
File propertiesFile = locateFile(propertiesPath);
if ((defaultsFile == null) && (propertiesFile == null)) {
throw new FileNotFoundException("Property file not found at '"
+ defaultsPath + "' or '" + propertiesPath + "'");
}
if (defaultsFile != null) {
log.debug("Loading bundle '" + bundleName + "' defaults from '"
+ defaultsPath + "'");
FileInputStream stream = new FileInputStream(defaultsFile);
Reader reader = new InputStreamReader(stream, "UTF-8");
try {
this.defaults.load(reader);
} finally {
reader.close();
}
}
if (propertiesFile != null) {
log.debug("Loading bundle '" + bundleName + "' overrides from '"
+ propertiesPath + "'");
FileInputStream stream = new FileInputStream(propertiesFile);
Reader reader = new InputStreamReader(stream, "UTF-8");
try {
this.properties.load(reader);
} finally {
reader.close();
}
}
}
private void loadReferencedFiles() throws IOException {
for (String key : this.properties.stringPropertyNames()) {
String value = this.properties.getProperty(key);
if (value.startsWith(FILE_FLAG)) {
String filepath = value.substring(FILE_FLAG.length()).trim();
loadReferencedFile(key, filepath);
}
}
}
private void loadReferencedFile(String key, String filepath)
throws IOException {
String appFilePath = joinPath(appI18nPath, filepath);
String themeFilePath = joinPath(themeI18nPath, filepath);
File appFile = locateFile(appFilePath);
File themeFile = locateFile(themeFilePath);
if (themeFile != null) {
this.properties.setProperty(key,
FileUtils.readFileToString(themeFile, "UTF-8"));
} else if (appFile != null) {
this.properties.setProperty(key,
FileUtils.readFileToString(appFile, "UTF-8"));
} else {
String message = MessageFormat.format(MESSAGE_FILE_NOT_FOUND, key,
themeFilePath, appFilePath);
this.properties.setProperty(key, message);
log.warn(message);
}
}
private String joinPath(String root, String twig) {
if ((root.charAt(root.length() - 1) == File.separatorChar)
|| (twig.charAt(0) == File.separatorChar)) {
return root + twig;
} else {
return root + File.separatorChar + twig;
}
}
private File locateFile(String path) {
String realPath = ctx.getRealPath(path);
if (realPath == null) {
log.debug("No real path for '" + path + "'");
return null;
}
File f = new File(realPath);
if (!f.isFile()) {
log.debug("No file at '" + realPath + "'");
return null;
}
if (!f.canRead()) {
log.error("Can't read the file at '" + realPath + "'");
return null;
}
log.debug("Located file '" + path + "' at '" + realPath + "'");
return f;
}
@SuppressWarnings("unchecked")
@Override
public Enumeration<String> getKeys() {
return (Enumeration<String>) this.properties.propertyNames();
}
@Override
protected Object handleGetObject(String key) {
String value = this.properties.getProperty(key);
if (value == null) {
log.debug(bundleName + " has no value for '" + key + "'");
}
return value;
}
}

View file

@ -0,0 +1,40 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.freemarker;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.i18n.I18nBundle;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
/**
* For Freemarker, this acts like a bundle of text strings. It is simply a
* wrapper around an I18nBundle.
*/
public class I18nBundleTemplateModel implements TemplateHashModel {
private static final Log log = LogFactory
.getLog(I18nBundleTemplateModel.class);
private final String bundleName;
private final I18nBundle textBundle;
public I18nBundleTemplateModel(String bundleName, I18nBundle textBundle) {
this.bundleName = bundleName;
this.textBundle = textBundle;
}
@Override
public TemplateModel get(String key) throws TemplateModelException {
return new I18nStringTemplateModel(bundleName, key,
textBundle.text(key));
}
@Override
public boolean isEmpty() throws TemplateModelException {
return false;
}
}

View file

@ -0,0 +1,50 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.freemarker;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
import edu.cornell.mannlib.vitro.webapp.i18n.I18nBundle;
import freemarker.core.Environment;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
/**
* This Freemarker method will produce a bundle of text strings. It is simply a
* wrapper around I18n that produces a wrapped I18nBundle.
*
* If the bundle name is not provided, the default bundle is assumed.
*/
public class I18nMethodModel implements TemplateMethodModel {
private static final Log log = LogFactory.getLog(I18nMethodModel.class);
@SuppressWarnings("rawtypes")
@Override
public Object exec(List args) throws TemplateModelException {
if (args.size() > 1) {
throw new TemplateModelException("Too many arguments: "
+ "displayText method only requires a bundle name.");
}
Object arg = args.isEmpty() ? I18n.DEFAULT_BUNDLE_NAME : args.get(0);
if (!(arg instanceof String)) {
throw new IllegalArgumentException(
"Arguments to a TemplateMethodModel are supposed to be Strings!");
}
log.debug("Asking for this bundle: " + arg);
String bundleName = (String) arg;
Environment env = Environment.getCurrentEnvironment();
HttpServletRequest request = (HttpServletRequest) env
.getCustomAttribute("request");
I18nBundle tb = I18n.bundle(bundleName, request);
return new I18nBundleTemplateModel(bundleName, tb);
}
}

View file

@ -0,0 +1,79 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.freemarker;
import java.text.MessageFormat;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateScalarModel;
import freemarker.template.utility.DeepUnwrap;
/**
* A Freemarker representation of a text string. Because it implements
* TemplateScalarModel, you can use it as a string value. And because it
* implements TemplateMethodModel, you can pass arguments to it for formatting.
*
* So if the string is "His name is {0}!", then these references could be used:
*
* ${string} ==> "His name is {0}!"
*
* ${string("Bozo")} ==> "His name is Bozo!"
*
* Note that the format of the message is determined by java.text.MessageFormat,
* so argument indices start at 0 and you can escape a substring by wrapping it
* in apostrophes.
*/
public class I18nStringTemplateModel implements TemplateMethodModelEx,
TemplateScalarModel {
private static final Log log = LogFactory
.getLog(I18nStringTemplateModel.class);
private final String bundleName;
private final String key;
private final String textString;
public I18nStringTemplateModel(String bundleName, String key,
String textString) {
this.bundleName = bundleName;
this.key = key;
this.textString = textString;
}
@Override
public String getAsString() throws TemplateModelException {
return textString;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Object exec(List args) throws TemplateModelException {
log.debug("Formatting string '" + key + "' from bundle '" + bundleName
+ "' with these arguments: " + args);
if (args.isEmpty()) {
return textString;
} else {
Object[] unwrappedArgs = new Object[args.size()];
for (int i = 0; i < args.size(); i++) {
unwrappedArgs[i] = DeepUnwrap.unwrap((TemplateModel) args
.get(i));
}
try {
return MessageFormat.format(textString, unwrappedArgs);
} catch (Exception e) {
String message = "Can't format '" + key + "' from bundle '"
+ bundleName + "', wrong argument types: " + args
+ " for message format'" + textString + "'";
log.warn(message);
return message;
}
}
}
}

View file

@ -0,0 +1,100 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.selection;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.LocaleUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
/**
* Call this at /selectLocale&selection=[locale_string]
*
* For example: /selectLocale&selection=en_US or /selectLocale&selection=es
*
* Write an error to the log (and to DisplayMessage) if the selection is not
* syntactically valid.
*
* Write a warning to the log if the selection code is not one of the selectable
* Locales from runtime.properties, or if the selection code is not recognized
* by the system.
*
* Set the new Locale in the Session using SelectedLocale and return to the
* referrer.
*/
public class LocaleSelectionController extends HttpServlet {
private static final Log log = LogFactory
.getLog(LocaleSelectionController.class);
public static final String PARAMETER_SELECTION = "selection";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String referrer = req.getHeader("referer");
String selectedLocale = req.getParameter(PARAMETER_SELECTION);
try {
processSelectedLocale(req, selectedLocale);
} catch (Exception e) {
log.error("Failed to process the user's Locale selection", e);
}
if (StringUtils.isEmpty(referrer)) {
resp.sendRedirect(UrlBuilder.getHomeUrl());
} else {
resp.sendRedirect(referrer);
}
}
private void processSelectedLocale(HttpServletRequest req,
String selectedLocale) {
if (StringUtils.isBlank(selectedLocale)) {
log.debug("No '" + PARAMETER_SELECTION + "' parameter");
return;
}
Locale locale = null;
try {
locale = LocaleUtils.toLocale(selectedLocale.trim());
log.debug("Locale selection is " + locale);
} catch (IllegalArgumentException e) {
log.error("Failed to convert the selection to a Locale", e);
DisplayMessage.setMessage(req,
"There was a problem in the system. "
+ "Your language choice was rejected.");
return;
}
List<Locale> selectables = SelectedLocale.getSelectableLocales(req);
if (!selectables.contains(locale)) {
log.warn("User selected a locale '" + locale
+ "' that was not in the list: " + selectables);
} else if (!LocaleUtils.isAvailableLocale(locale)) {
log.warn("User selected an unrecognized locale: '" + locale + "'");
}
SelectedLocale.setSelectedLocale(req, locale);
log.debug("Setting selected locale to " + locale);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}

View file

@ -0,0 +1,95 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.selection;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
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.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter;
/**
* Get the data for the selectable Locales, so the Freemarker template can
* create a row of flag images that will select the desired locale.
*
* If there are no selectable Locales in runtime.properties, we return an empty
* map. (selectLocale?? will return false)
*
* If the Locale has been forced by runtime.properties, we do the same.
*
* If there are selectable Locales, the returned map will contain a structure
* like this:
*
* <pre>
* {selectLocale={
* selectLocaleUrl = [the URL for the form action to select a Locale]
* locales={ [a list of maps]
* { [a map for each Locale]
* code = [the code for the Locale, e.g. "en_US"]
* label = [the alt text for the Locale, e.g. "Spanish (Spain)"]
* imageUrl = [the URL of the image that represents the Locale]
* }
* }
* }
* }
* </pre>
*/
public class LocaleSelectionDataGetter implements DataGetter {
private static final Log log = LogFactory
.getLog(LocaleSelectionDataGetter.class);
private final VitroRequest vreq;
public LocaleSelectionDataGetter(VitroRequest vreq) {
this.vreq = vreq;
}
@Override
public Map<String, Object> getData(Map<String, Object> valueMap) {
List<Locale> selectables = SelectedLocale.getSelectableLocales(vreq);
if (selectables.isEmpty()) {
return Collections.emptyMap();
}
Map<String, Object> result = new HashMap<String, Object>();
result.put("selectLocaleUrl", UrlBuilder.getUrl("/selectLocale"));
result.put("locales", buildLocalesList(selectables));
Map<String, Object> bodyMap = new HashMap<String, Object>();
bodyMap.put("selectLocale", result);
log.debug("Sending these values: " + bodyMap);
return bodyMap;
}
private List<Map<String, Object>> buildLocalesList(List<Locale> selectables) {
Locale currentLocale = SelectedLocale.getCurrentLocale(vreq);
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
for (Locale locale : selectables) {
try {
list.add(buildLocaleMap(locale, currentLocale));
} catch (FileNotFoundException e) {
log.warn("Can't show the Locale selector for '" + locale
+ "': " + e);
}
}
return list;
}
private Map<String, Object> buildLocaleMap(Locale locale,
Locale currentLocale) throws FileNotFoundException {
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", locale.toString());
map.put("label", locale.getDisplayName(currentLocale));
map.put("imageUrl", LocaleSelectorUtilities.getImageUrl(vreq, locale));
return map;
}
}

View file

@ -0,0 +1,114 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.selection;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.collections.EnumerationUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Check for a Locale in the ServletContext or the Session that should override
* the Locale in the ServletRequest.
*
* If there is such a Locale, wrap the ServletRequest so it behaves as if that
* is the preferred Locale.
*
* Otherwise, just process the request as usual.
*/
public class LocaleSelectionFilter implements Filter {
private static final Log log = LogFactory
.getLog(LocaleSelectionFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Nothing to do at startup.
}
@Override
public void destroy() {
// Nothing to do at shutdown.
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HttpServletRequest hreq = (HttpServletRequest) request;
Locale overridingLocale = SelectedLocale.getOverridingLocale(hreq);
log.debug("overriding Locale is " + overridingLocale);
if (overridingLocale != null) {
request = new LocaleSelectionRequestWrapper(hreq,
overridingLocale);
}
} else {
log.debug("Not an HttpServletRequest.");
}
chain.doFilter(request, response);
}
// ----------------------------------------------------------------------
// Helper classes
// ----------------------------------------------------------------------
/**
* Uses the selected Locale as the preferred Locale of the request.
*/
private static class LocaleSelectionRequestWrapper extends
HttpServletRequestWrapper {
private final List<Locale> locales;
@SuppressWarnings("unchecked")
public LocaleSelectionRequestWrapper(HttpServletRequest request,
Locale selectedLocale) {
super(request);
if (request == null) {
throw new NullPointerException("request may not be null.");
}
if (selectedLocale == null) {
throw new NullPointerException(
"selectedLocale may not be null.");
}
Locale selectedLanguage = new Locale(selectedLocale.getLanguage());
locales = EnumerationUtils.toList(request.getLocales());
locales.remove(selectedLanguage);
locales.add(0, selectedLanguage);
locales.remove(selectedLocale);
locales.add(0, selectedLocale);
}
@Override
public Locale getLocale() {
return locales.get(0);
}
/**
* Get the modified list of locales.
*/
@SuppressWarnings("rawtypes")
@Override
public Enumeration getLocales() {
return Collections.enumeration(locales);
}
}
}

View file

@ -0,0 +1,148 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.selection;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.lang.LocaleUtils;
import org.apache.commons.lang.StringUtils;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
* Check the ConfigurationProperties for a forced locale, or for a
* comma-separate list of selectable locales.
*
* Create the appropriate Locale objects and store them in the ServletContext.
*/
public class LocaleSelectionSetup implements ServletContextListener {
/**
* If this is set, the locale is forced. No selection will be offered to the
* user, and browser locales will be ignored.
*/
public static final String PROPERTY_FORCE_LOCALE = "languages.forceLocale";
/**
* This is the list of locales that the user may select. There should be a
* national flag or symbol available for each supported locale.
*/
public static final String PROPERTY_SELECTABLE_LOCALES = "languages.selectableLocales";
private ServletContext ctx;
private StartupStatus ss;
private ConfigurationProperties props;
private String forceString;
private String selectableString;
@Override
public void contextInitialized(ServletContextEvent sce) {
ctx = sce.getServletContext();
ss = StartupStatus.getBean(ctx);
props = ConfigurationProperties.getBean(sce);
readProperties();
if (isForcing() && hasSelectables()) {
warnAboutOverride();
}
if (isForcing()) {
forceLocale();
} else if (hasSelectables()) {
setUpSelections();
} else {
reportNoLocales();
}
}
private void readProperties() {
forceString = props.getProperty(PROPERTY_FORCE_LOCALE, "");
selectableString = props.getProperty(PROPERTY_SELECTABLE_LOCALES, "");
}
private boolean isForcing() {
return StringUtils.isNotBlank(forceString);
}
private boolean hasSelectables() {
return StringUtils.isNotBlank(selectableString);
}
private void warnAboutOverride() {
ss.warning(this, "'" + PROPERTY_FORCE_LOCALE + "' will override '"
+ PROPERTY_SELECTABLE_LOCALES + "'.");
}
private void forceLocale() {
try {
Locale forceLocale = buildLocale(forceString);
SelectedLocale.setForcedLocale(ctx, forceLocale);
ssInfo("Setting forced locale to '" + forceLocale + "'.");
} catch (IllegalArgumentException e) {
ssWarning("Problem in '" + PROPERTY_FORCE_LOCALE + "': "
+ e.getMessage());
}
}
private void setUpSelections() {
List<Locale> locales = new ArrayList<Locale>();
for (String string : splitSelectables()) {
try {
locales.add(buildLocale(string));
} catch (IllegalArgumentException e) {
ssWarning("Problem in '" + PROPERTY_SELECTABLE_LOCALES + "': "
+ e.getMessage());
}
}
SelectedLocale.setSelectableLocales(ctx, locales);
ssInfo("Setting selectable locales to '" + locales + "'.");
}
private String[] splitSelectables() {
return selectableString.split("\\s*,\\s*");
}
private void reportNoLocales() {
ssInfo("There is no Locale information.");
}
private void ssInfo(String message) {
ss.info(this, message + showPropertyValues());
}
private void ssWarning(String message) {
ss.warning(this, message + showPropertyValues());
}
private String showPropertyValues() {
return " In runtime.properties, '" + PROPERTY_FORCE_LOCALE
+ "' is set to '" + forceString + "', '"
+ PROPERTY_SELECTABLE_LOCALES + "' is set to '"
+ selectableString + "'";
}
private Locale buildLocale(String localeString)
throws IllegalArgumentException {
Locale locale = LocaleUtils.toLocale(localeString);
if (!LocaleUtils.isAvailableLocale(locale)) {
ssWarning("'" + locale + "' is not a recognized locale.");
}
return locale;
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// Nothing to do at shutdown.
}
}

View file

@ -0,0 +1,54 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.selection;
import java.io.FileNotFoundException;
import java.util.Locale;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* Some static methods for the GUI aspects of selecting a Locale.
*/
public class LocaleSelectorUtilities {
private static final Log log = LogFactory
.getLog(LocaleSelectorUtilities.class);
/**
* Look in the current theme directory to find a selection image for this
* Locale.
*
* Images are expected at a resource path like
* /[themeDir]/i18n/images/select_locale_[locale_code].*
*
* For example, /themes/wilma/i18n/images/select_locale_en.png
* /themes/wilma/i18n/images/select_locale_en.JPEG
* /themes/wilma/i18n/images/select_locale_en.gif
*
* To create a proper URL, prepend the context path.
*/
public static String getImageUrl(VitroRequest vreq, Locale locale)
throws FileNotFoundException {
String filename = "select_locale_" + locale + ".";
String themeDir = vreq.getAppBean().getThemeDir();
String imageDirPath = "/" + themeDir + "i18n/images/";
ServletContext ctx = vreq.getSession().getServletContext();
for (Object o : ctx.getResourcePaths(imageDirPath)) {
String resourcePath = (String) o;
if (resourcePath.contains(filename)) {
String fullPath = vreq.getContextPath() + resourcePath;
log.debug("Found image for " + locale + " at '" + fullPath
+ "'");
return fullPath;
}
}
throw new FileNotFoundException("Can't find an image for " + locale);
}
}

View file

@ -0,0 +1,204 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.i18n.selection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A utility class for storing and retrieving Locale information.
*
* The static methods create beans and store them in the ServletContext or the
* session, where the information can be found later.
*/
public abstract class SelectedLocale {
private static final Log log = LogFactory.getLog(SelectedLocale.class);
/** Use this attribute on both the ServletContext and the Session. */
protected static final String ATTRIBUTE_NAME = "SELECTED_LOCALE";
/**
* Store the forced locale in the servlet context. Clear any selectable
* Locales.
*/
public static void setForcedLocale(ServletContext ctx, Locale forcedLocale) {
log.debug("Set forced locale: " + forcedLocale);
ctx.setAttribute(ATTRIBUTE_NAME,
new ContextSelectedLocale(forcedLocale));
}
/**
* Store the selected locale in the current session.
*/
public static void setSelectedLocale(HttpServletRequest req,
Locale selectedLocale) {
log.debug("Set selected locale: " + selectedLocale);
req.getSession().setAttribute(ATTRIBUTE_NAME,
new SessionSelectedLocale(selectedLocale));
}
/**
* Do we need to override the Locale in the current request? return the
* first of these to be found:
* <ul>
* <li>The forced Locale in the servlet context</li>
* <li>The selected Locale in the session</li>
* <li>null</li>
* </ul>
*/
public static Locale getOverridingLocale(HttpServletRequest req) {
HttpSession session = req.getSession();
ServletContext ctx = session.getServletContext();
Object ctxInfo = ctx.getAttribute(ATTRIBUTE_NAME);
if (ctxInfo instanceof ContextSelectedLocale) {
Locale forcedLocale = ((ContextSelectedLocale) ctxInfo)
.getForcedLocale();
if (forcedLocale != null) {
log.debug("Found forced locale in the context: " + forcedLocale);
return forcedLocale;
}
}
Object sessionInfo = session.getAttribute(ATTRIBUTE_NAME);
if (sessionInfo instanceof SessionSelectedLocale) {
Locale selectedLocale = ((SessionSelectedLocale) sessionInfo)
.getSelectedLocale();
if (selectedLocale != null) {
log.debug("Found selected locale in the session: "
+ selectedLocale);
return selectedLocale;
}
}
return null;
}
/**
* Get the current Locale to use, which is the first of these to be found:
* <ul>
* <li>The forced Locale in the servlet context</li>
* <li>The selected Locale in the session</li>
* <li>The Locale from the request</li>
* <li>The default Locale for the JVM</li>
* </ul>
*/
public static Locale getCurrentLocale(HttpServletRequest req) {
Locale overridingLocale = getOverridingLocale(req);
if (overridingLocale != null) {
return overridingLocale;
}
Locale requestLocale = req.getLocale();
if (requestLocale != null) {
log.debug("Found locale in the request: " + requestLocale);
return requestLocale;
}
log.debug("Using default locale: " + Locale.getDefault());
return Locale.getDefault();
}
/**
* Store a list of selectable Locales in the servlet context, so we can
* easily build the selection panel in the GUI. Clears any forced locale.
*/
public static void setSelectableLocales(ServletContext ctx,
List<Locale> selectableLocales) {
log.debug("Setting selectable locales: " + selectableLocales);
ctx.setAttribute(ATTRIBUTE_NAME, new ContextSelectedLocale(
selectableLocales));
}
/**
* Get the list of selectable Locales from the servlet context. May return
* an empty list, but never returns null.
*/
public static List<Locale> getSelectableLocales(HttpServletRequest req) {
ServletContext ctx = req.getSession().getServletContext();
Object ctxInfo = ctx.getAttribute(ATTRIBUTE_NAME);
if (ctxInfo instanceof ContextSelectedLocale) {
List<Locale> selectableLocales = ((ContextSelectedLocale) ctxInfo)
.getSelectableLocales();
if (selectableLocales != null) {
log.debug("Returning selectable locales: " + selectableLocales);
return selectableLocales;
}
}
log.debug("No selectable locales were found. Returning an empty list.");
return Collections.emptyList();
}
// ----------------------------------------------------------------------
// Bean classes
// ----------------------------------------------------------------------
/** Holds Locale information in the ServletContext. */
protected static class ContextSelectedLocale {
// Only one of these is populated.
private final Locale forcedLocale;
private final List<Locale> selectableLocales;
public ContextSelectedLocale(Locale forcedLocale) {
if (forcedLocale == null) {
throw new NullPointerException("forcedLocale may not be null.");
}
this.forcedLocale = forcedLocale;
this.selectableLocales = Collections.emptyList();
}
public ContextSelectedLocale(List<Locale> selectableLocales) {
if (selectableLocales == null) {
selectableLocales = Collections.emptyList();
}
this.forcedLocale = null;
this.selectableLocales = selectableLocales;
}
public Locale getForcedLocale() {
return forcedLocale;
}
public List<Locale> getSelectableLocales() {
return selectableLocales;
}
@Override
public String toString() {
return "ContextSelectedLocale[forced=" + forcedLocale
+ ", selectable=" + selectableLocales + "]";
}
}
/** Holds Locale information in the Session. */
protected static class SessionSelectedLocale {
private final Locale selectedLocale;
public SessionSelectedLocale(Locale selectedLocale) {
this.selectedLocale = selectedLocale;
}
public Locale getSelectedLocale() {
return selectedLocale;
}
@Override
public String toString() {
return "SessionSelectedLocale[" + selectedLocale + "]";
}
}
}

View file

@ -11,7 +11,6 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -42,26 +41,20 @@ public class LanguageFilteringRDFService implements RDFService {
this.langs = normalizeLangs(langs);
}
private List<String> normalizeLangs(List<String> langs) {
List<String> normalizedLangs = new ArrayList<String>();
String currentBaseLang = null;
for (String lang : langs) {
String normalizedLang = StringUtils.lowerCase(lang);
String baseLang = normalizedLang.split("-")[0];
if (currentBaseLang == null) {
currentBaseLang = baseLang;
} else if (!currentBaseLang.equals(baseLang)) {
if (!normalizedLangs.contains(currentBaseLang)) {
normalizedLangs.add(currentBaseLang);
}
currentBaseLang = baseLang;
}
}
if (currentBaseLang != null && !normalizedLangs.contains(currentBaseLang)) {
normalizedLangs.add(currentBaseLang);
}
return normalizedLangs;
}
private List<String> normalizeLangs(List<String> langs) {
log.debug("Preferred languages:" + langs);
List<String> normalizedLangs = new ArrayList<String>(langs);
for (String lang : langs) {
String baseLang = lang.split("-")[0];
if (!normalizedLangs.contains(baseLang)) {
normalizedLangs.add(baseLang);
}
}
log.debug("Normalized languages:" + normalizedLangs);
return normalizedLangs;
}
@Override
public boolean changeSetUpdate(ChangeSet changeSet)
@ -106,6 +99,7 @@ public class LanguageFilteringRDFService implements RDFService {
}
private Model filterModel(Model m) {
log.debug("filterModel");
List<Statement> retractions = new ArrayList<Statement>();
StmtIterator stmtIt = m.listStatements();
while (stmtIt.hasNext()) {
@ -117,6 +111,7 @@ public class LanguageFilteringRDFService implements RDFService {
continue;
}
Collections.sort(candidatesForRemoval, new StatementSortByLang());
log.debug("sorted statements: " + showSortedStatements(candidatesForRemoval));
Iterator<Statement> candIt = candidatesForRemoval.iterator();
String langRegister = null;
boolean chuckRemaining = false;
@ -142,9 +137,27 @@ public class LanguageFilteringRDFService implements RDFService {
return m;
}
@Override
private String showSortedStatements(List<Statement> candidatesForRemoval) {
List<String> langStrings = new ArrayList<String>();
for (Statement stmt: candidatesForRemoval) {
if (stmt == null) {
langStrings.add("null stmt");
} else {
RDFNode node = stmt.getObject();
if (!node.isLiteral()) {
langStrings.add("not literal");
} else {
langStrings.add(node.asLiteral().getLanguage());
}
}
}
return langStrings.toString();
}
@Override
public InputStream sparqlSelectQuery(String query,
ResultFormat resultFormat) throws RDFServiceException {
log.debug("sparqlSelectQuery: " + query.replaceAll("\\s+", " "));
ResultSet resultSet = ResultSetFactory.fromJSON(
s.sparqlSelectQuery(query, RDFService.ResultFormat.JSON));
List<QuerySolution> solnList = getSolutionList(resultSet);
@ -178,6 +191,7 @@ public class LanguageFilteringRDFService implements RDFService {
continue;
}
Collections.sort(candidatesForRemoval, new RowIndexedLiteralSortByLang());
log.debug("sorted RowIndexedLiterals: " + showSortedRILs(candidatesForRemoval));
Iterator<RowIndexedLiteral> candIt = candidatesForRemoval.iterator();
String langRegister = null;
boolean chuckRemaining = false;
@ -223,7 +237,15 @@ public class LanguageFilteringRDFService implements RDFService {
return new ByteArrayInputStream(outputStream.toByteArray());
}
private class RowIndexedLiteral {
private String showSortedRILs(List<RowIndexedLiteral> candidatesForRemoval) {
List<String> langstrings = new ArrayList<String>();
for (RowIndexedLiteral ril: candidatesForRemoval) {
langstrings.add(ril.getLiteral().getLanguage());
}
return langstrings.toString();
}
private class RowIndexedLiteral {
private Literal literal;
private int index;
@ -324,37 +346,44 @@ public class LanguageFilteringRDFService implements RDFService {
}
private class LangSort {
// any inexact match is worse than any exact match
private int inexactMatchPenalty = langs.size();
// no language is worse than any inexact match (if the preferred list does not include "").
private int noLanguage = 2 * inexactMatchPenalty;
// no match is worse than no language.
private int noMatch = noLanguage + 1;
protected int compareLangs(String t1lang, String t2lang) {
t1lang = StringUtils.lowerCase(t1lang);
t2lang = StringUtils.lowerCase(t2lang);
if ( t1lang == null && t2lang == null) {
return 0;
} else if (t1lang == null) {
return 1;
} else if (t2lang == null) {
return -1;
} else {
int t1langPref = langs.indexOf(t1lang);
int t2langPref = langs.indexOf(t2lang);
if (t1langPref == -1 && t2langPref == -1) {
if ("".equals(t1lang) && "".equals(t2lang)) {
return 0;
} else if ("".equals(t1lang) && !("".equals(t2lang))) {
return -1;
} else {
return 1;
}
} else if (t1langPref > -1 && t2langPref == -1) {
return -1;
} else if (t1langPref == -1 && t2langPref > -1) {
return 1;
} else {
return t1langPref - t2langPref;
}
}
return languageIndex(t1lang) - languageIndex(t2lang);
}
/**
* Return index of exact match, or index of partial match, or
* language-free, or no match.
*/
private int languageIndex(String lang) {
if (lang == null) {
lang = "";
}
int index = langs.indexOf(lang);
if (index >= 0) {
return index;
}
if (lang.length() > 2) {
index = langs.indexOf(lang.substring(0, 2));
if (index >= 0) {
return index + inexactMatchPenalty;
}
}
if (lang.isEmpty()) {
return noLanguage;
}
return noMatch;
}
}
private class RowIndexedLiteralSortByLang extends LangSort implements Comparator<RowIndexedLiteral> {

View file

@ -90,7 +90,7 @@ public class SolrSetup implements javax.servlet.ServletContextListener{
/* setup the http connection with the solr server */
String solrServerUrlString = ConfigurationProperties.getBean(sce).getProperty("vitro.local.solr.url");
if( solrServerUrlString == null ){
ss.fatal(this, "Could not find vitro.local.solr.url in deploy.properties. "+
ss.fatal(this, "Could not find vitro.local.solr.url in runtime.properties. "+
"Vitro application needs a URL of a solr server that it can use to index its data. " +
"It should be something like http://localhost:${port}" + context.getContextPath() + "solr"
);
@ -102,7 +102,7 @@ public class SolrSetup implements javax.servlet.ServletContextListener{
solrServerUrl = new URL(solrServerUrlString);
} catch (MalformedURLException e) {
ss.fatal(this, "Can't connect with the solr server. " +
"The value for vitro.local.solr.url in deploy.properties is not a valid URL: " + solrServerUrlString);
"The value for vitro.local.solr.url in runtime.properties is not a valid URL: " + solrServerUrlString);
return;
}

View file

@ -80,7 +80,7 @@ public class ContextNodeFields implements DocumentModifier{
* @return StringBuffer with text values to add to ALLTEXT field of solr Document.
*/
protected StringBuffer executeQueryForValues( Individual individual, Collection<String> queries){
/* execute all the queries on the list and concat the values to add to all text */
/* execute all the queries on the list and concat the values to add to all text */
RDFService rdfService = rdfServiceFactory.getRDFService();
StringBuffer allValues = new StringBuffer("");
@ -95,7 +95,7 @@ public class ContextNodeFields implements DocumentModifier{
ResultSet results = RDFServiceUtils.sparqlSelectQuery(subInUriQuery, rdfService);
while(results.hasNext()){
valuesForQuery.append(
getTextForRow( results.nextSolution() ) ) ;
getTextForRow( results.nextSolution(), true ) ) ;
}
}catch(Throwable t){
@ -111,10 +111,10 @@ public class ContextNodeFields implements DocumentModifier{
}
rdfService.close();
return allValues;
return allValues;
}
protected String getTextForRow( QuerySolution row){
protected String getTextForRow( QuerySolution row, boolean addSpace){
if( row == null )
return "";
@ -124,7 +124,11 @@ public class ContextNodeFields implements DocumentModifier{
String name = iter.next();
RDFNode node = row.get( name );
if( node != null ){
text.append(" ").append( node.toString() );
if(addSpace) {
text.append(" ").append( node.toString() );
} else {
text.append(node.toString());
}
}else{
log.debug(name + " is null");
}
@ -132,7 +136,6 @@ public class ContextNodeFields implements DocumentModifier{
return text.toString();
}
public void shutdown(){
shutdown=true;
}

View file

@ -546,7 +546,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
if ((dns != null) && (!dns.isEmpty())) {
return dns;
} else {
throw new IllegalStateException("deploy.properties does not "
throw new IllegalStateException("runtime.properties does not "
+ "contain a value for '" + VITRO_DEFAULT_NAMESPACE + "'");
}
}

View file

@ -50,7 +50,7 @@ public class SolrSmokeTest implements ServletContextListener {
.getProperty("vitro.local.solr.url", "");
if (solrUrlString.isEmpty()) {
ss.fatal(this, "Can't connect to Solr search engine. "
+ "deploy.properties must contain a value for "
+ "runtime.properties must contain a value for "
+ "vitro.local.solr.url");
return;
}
@ -62,7 +62,7 @@ public class SolrSmokeTest implements ServletContextListener {
} catch (MalformedURLException e) {
ss.fatal(this, "Can't connect to Solr search engine. "
+ "The value for vitro.local.solr.url "
+ "in deploy.properties is not a valid URL: '"
+ "in runtime.properties is not a valid URL: '"
+ solrUrlString + "'", e);
}
@ -124,9 +124,7 @@ public class SolrSmokeTest implements ServletContextListener {
int status = e.getStatusCode();
Throwable cause = e.getCause();
if (status == HttpStatus.SC_FORBIDDEN) {
warnForbidden();
} else if (status == SOCKET_TIMEOUT_STATUS) {
if (status == SOCKET_TIMEOUT_STATUS) {
warnSocketTimeout();
} else if (status != 0) {
warnBadHttpStatus(status);
@ -151,23 +149,14 @@ public class SolrSmokeTest implements ServletContextListener {
ss.warning(listener, "Can't connect to the Solr search engine. "
+ "The socket connection has repeatedly timed out. "
+ "Check the value of vitro.local.solr.url in "
+ "deploy.properties. Is Solr responding at that URL?");
}
private void warnForbidden() {
ss.warning(listener, "Can't connect to the Solr search engine. "
+ "The Solr server will not accept connections from this "
+ "host. Check the value of "
+ "vitro.local.solr.ipaddress.mask in "
+ "deploy.properties -- "
+ "does it authorize access from this IP address?");
+ "runtime.properties. Is Solr responding at that URL?");
}
private void warnBadHttpStatus(int status) {
ss.warning(listener, "Can't connect to the Solr search engine. "
+ "The Solr server returned a status code of " + status
+ ". Check the value of vitro.local.solr.url in "
+ "deploy.properties.");
+ "runtime.properties.");
}
private void warnProtocolViolation(HttpException e) {
@ -179,7 +168,7 @@ public class SolrSmokeTest implements ServletContextListener {
ss.warning(listener, "Can't connect to the Solr search engine. '"
+ e.getMessage() + "' is an unknown host."
+ "Check the value of vitro.local.solr.url in "
+ "deploy.properties.", e);
+ "runtime.properties.", e);
}
private void warnConnectionRefused(ConnectException e) {
@ -187,7 +176,7 @@ public class SolrSmokeTest implements ServletContextListener {
+ "The host refused the connection. "
+ "Is it possible that the port number is incorrect? "
+ "Check the value of vitro.local.solr.url in "
+ "deploy.properties.", e);
+ "runtime.properties.", e);
}
private void warnTransportError(IOException e) {

View file

@ -182,10 +182,10 @@ public class UpdatePermissionSetUris implements ServletContextListener {
Journal(ServletContext ctx) throws IOException {
String homeDirectoryPath = ConfigurationProperties.getBean(ctx)
.getProperty("vitro.home.directory");
.getProperty("vitro.home");
if (homeDirectoryPath == null) {
throw new IllegalStateException(
"No value found for vitro.home.directory");
"No value found for vitro.home");
}
File homeDirectory = new File(homeDirectoryPath);
confirmIsDirectory(homeDirectory);

View file

@ -23,7 +23,7 @@ import org.apache.commons.logging.LogFactory;
public class StartupStatus {
private static final Log log = LogFactory.getLog(StartupStatus.class);
private static final String ATTRIBUTE_NAME = "STARTUP_STATUS";
protected static final String ATTRIBUTE_NAME = "STARTUP_STATUS";
// ----------------------------------------------------------------------
// static methods

View file

@ -59,39 +59,58 @@ public class DataGetterUtils {
* This should not return PageDataGetters and should not throw an
* exception if a page has PageDataGetters.
*/
public static List<DataGetter> getDataGettersForPage( VitroRequest vreq, Model displayModel, String pageURI)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException{
//get data getter uris for pageURI
List<String> dgUris = getDataGetterURIsForPageURI( displayModel, pageURI);
List<DataGetter> dgList = new ArrayList<DataGetter>();
for( String dgURI: dgUris){
DataGetter dg =dataGetterForURI(vreq, displayModel, dgURI) ;
if( dg != null )
dgList.add(dg);
}
log.debug("getDataGettersForPage: " + dgList);
return dgList;
}
public static List<DataGetter> getDataGettersForPage(VitroRequest vreq, Model displayModel, String pageURI)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException {
List<String> dgUris = getDataGetterURIsForAssociatedURI(displayModel, pageURI);
List<DataGetter> dgList = dataGettersForURIs(vreq, displayModel, dgUris);
log.debug("getDataGettersForPage: " + dgList);
return dgList;
}
/**
* Get a list of DataGetter objects that are associated with a JAVA class.
* Get a list of DataGetter objects that are associated with a Vitro VClass.
* This allows the individual profile for an individual of a specific class to be returned .
*/
public static List<DataGetter> getDataGettersForClass( VitroRequest vreq, Model displayModel, String classURI)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException{
//get data getter uris for pageURI
List<String> dgUris = getDataGetterURIsForClassURI( displayModel, classURI);
List<DataGetter> dgList = new ArrayList<DataGetter>();
for( String dgURI: dgUris){
DataGetter dg =dataGetterForURI(vreq, displayModel, dgURI) ;
if( dg != null )
dgList.add(dg);
}
log.debug("getDataGettersForClass: " + dgList);
return dgList;
}
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException{
List<String> dgUris = getDataGetterURIsForAssociatedURI( displayModel, classURI);
List<DataGetter> dgList = dataGettersForURIs(vreq, displayModel, dgUris);
log.debug("getDataGettersForClass: " + dgList);
return dgList;
}
/**
* Get a list of DataGetter objects that are associated with a Freemarker template.
* @param templateName a filename like "index.ftl", which will be used as a URI like "freemarker:index.ftl".
*/
public static List<DataGetter> getDataGettersForTemplate( VitroRequest vreq, Model displayModel, String templateName)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException{
String templateUri = "freemarker:" + templateName;
List<String> dgUris = getDataGetterURIsForAssociatedURI( displayModel, templateUri);
List<DataGetter> dgList = dataGettersForURIs(vreq, displayModel, dgUris);
log.debug("getDataGettersForTemplate '" + templateName + "': " + dgList);
return dgList;
}
/**
* Return a list of DataGetters from the list of URIs. Each DataGetter will be configured from information
* in the displayModel.
*
* Problems instantiating and configuring a particular DataGetter may result in an exception,
* or may just mean that there will be no entry in the result for that URI.
*
* May return an empty list, but will not return null.
*/
private static List<DataGetter> dataGettersForURIs(VitroRequest vreq, Model displayModel, List<String> dgUris)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException {
List<DataGetter> dgList = new ArrayList<DataGetter>();
for( String dgURI: dgUris){
DataGetter dg =dataGetterForURI(vreq, displayModel, dgURI) ;
if( dg != null )
dgList.add(dg);
}
return dgList;
}
/**
* Returns a DataGetter using information in the
@ -103,7 +122,7 @@ public class DataGetterUtils {
* that does not implement the DataGetter interface.
*/
public static DataGetter dataGetterForURI(VitroRequest vreq, Model displayModel, String dataGetterURI)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchMethodException
throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException, SecurityException
{
//get java class for dataGetterURI
String dgClassName = getJClassForDataGetterURI(displayModel, dataGetterURI);
@ -180,47 +199,18 @@ public class DataGetterUtils {
}
private static List<String> getDataGetterURIsForPageURI(Model displayModel, String pageURI) {
private static List<String> getDataGetterURIsForAssociatedURI(Model displayModel, String associatedURI) {
String query = prefixes +
"SELECT ?dataGetter WHERE { ?pageURI display:hasDataGetter ?dataGetter. }";
Query dgForPageQuery = QueryFactory.create(query);
"SELECT ?dataGetter WHERE { ?associatedURI display:hasDataGetter ?dataGetter }";
Query dgForUriQuery = QueryFactory.create(query);
QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("pageURI", ResourceFactory.createResource( pageURI ));
initialBindings.add("associatedURI", ResourceFactory.createResource( associatedURI ));
List<String> dgURIs = new ArrayList<String>();
displayModel.enterCriticalSection(false);
try{
QueryExecution qexec = QueryExecutionFactory.create(dgForPageQuery,displayModel,initialBindings );
try{
ResultSet results = qexec.execSelect();
while (results.hasNext()) {
QuerySolution soln = results.nextSolution();
Resource dg = soln.getResource("dataGetter");
if( dg != null && dg.getURI() != null){
dgURIs.add( dg.getURI());
}
}
}finally{ qexec.close(); }
}finally{ displayModel.leaveCriticalSection(); }
return dgURIs;
}
//Get data getters for a specific JAVA class - associates data getters with individuals for a specific JAVA class
private static List<String> getDataGetterURIsForClassURI(Model displayModel, String classURI) {
//Class URI will be substituted in so this is for a specific class uri
String query = prefixes +
"SELECT ?dataGetter WHERE { ?classURI display:hasDataGetter ?dataGetter }";
Query dgForPageQuery = QueryFactory.create(query);
QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("classURI", ResourceFactory.createResource( classURI ));
List<String> dgURIs = new ArrayList<String>();
displayModel.enterCriticalSection(false);
try{
QueryExecution qexec = QueryExecutionFactory.create(dgForPageQuery,displayModel,initialBindings );
QueryExecution qexec = QueryExecutionFactory.create(dgForUriQuery,displayModel,initialBindings );
try{
ResultSet results = qexec.execSelect();
while (results.hasNext()) {
@ -233,6 +223,7 @@ public class DataGetterUtils {
}finally{ qexec.close(); }
}finally{ displayModel.leaveCriticalSection(); }
log.debug("Found " + dgURIs.size() +" DataGetter URIs for '" + associatedURI + "': " + dgURIs);
return dgURIs;
}

View file

@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -504,6 +505,7 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
//TODO:Check where this logic should actually go, copied from input element formatting tag
//Updating to enable multiple vclasses applicable to subject to be analyzed to understand possible range of types
public Map<String, String> getOfferTypesCreateNew() {
WebappDaoFactory wdf = vreq.getWebappDaoFactory();
ObjectProperty op =
@ -513,9 +515,34 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
wdf.getIndividualDao().getIndividualByURI(editConfig.getSubjectUri());
List<VClass> vclasses = null;
vclasses = wdf.getVClassDao().getVClassesForProperty(sub.getVClassURI(), op.getURI());
if( vclasses == null )
List<VClass> subjectVClasses = sub.getVClasses();
if( subjectVClasses == null ) {
vclasses = wdf.getVClassDao().getAllVclasses();
}
else {
//this hash is used to make sure there are no duplicates in the vclasses
//a more elegant method may look at overriding equals/hashcode to enable a single hashset of VClass objects
HashSet<String> vclassesURIs = new HashSet<String>();
vclasses = new ArrayList<VClass>();
//Get the range vclasses applicable for the property and each vclass for the subject
for(VClass subjectVClass: subjectVClasses) {
List<VClass> rangeVclasses = wdf.getVClassDao().getVClassesForProperty(subjectVClass.getURI(), op.getURI());
//add range vclass to hash
if(rangeVclasses != null) {
for(VClass v: rangeVclasses) {
if(!vclassesURIs.contains(v.getURI())) {
vclassesURIs.add(v.getURI());
vclasses.add(v);
}
}
}
}
}
//if each subject vclass resulted in null being returned for range vclasses, then size of vclasses would be zero
if(vclasses.size() == 0) {
vclasses = wdf.getVClassDao().getAllVclasses();
}
HashMap<String,String> types = new HashMap<String, String>();
for( VClass vclass : vclasses ){

View file

@ -70,7 +70,7 @@ public class OpenSocialSmokeTests implements ServletContextListener {
configProps = ConfigurationProperties.getBean(ctx);
/*
* If OpenSocial is not configured in deploy.properties, skip the tests.
* If OpenSocial is not configured in runtime.properties, skip the tests.
*/
if (!configurationPresent()) {
ss.info(this, "The OpenSocial connection is not configured.");
@ -188,7 +188,7 @@ public class OpenSocialSmokeTests implements ServletContextListener {
}
/**
* Check that the Token Key file has been specified in deploy.properties,
* Check that the Token Key file has been specified in runtime.properties,
* and that it actually does exist.
*/
private void checkTokenKeyFile() {
@ -210,14 +210,14 @@ public class OpenSocialSmokeTests implements ServletContextListener {
}
/**
* Get the Token Service info from deploy.properties. It must be in the form
* Get the Token Service info from runtime.properties. It must be in the form
* of host:port, and may not refer to localhost.
*/
private void checkTokenServiceInfo() {
String tsInfo = configProps.getProperty(PROPERTY_SHINDIG_TOKEN_SERVICE);
if (StringUtils.isEmpty(tsInfo)) {
warnings.add(new Warning("There is no value for '"
+ PROPERTY_SHINDIG_TOKEN_SERVICE + "' in deploy.properties"));
+ PROPERTY_SHINDIG_TOKEN_SERVICE + "' in runtime.properties"));
return;
}
@ -278,7 +278,7 @@ public class OpenSocialSmokeTests implements ServletContextListener {
private static class NoSuchPropertyException extends Exception {
NoSuchPropertyException(String key) {
super("There is no value for '" + key + "' in deploy.properties");
super("There is no value for '" + key + "' in build.properties");
}
}