diff --git a/doc/install.html b/doc/install.html index f3baf7702..6121d15a6 100644 --- a/doc/install.html +++ b/doc/install.html @@ -649,6 +649,26 @@ remote_userID + + + + Tell Vitro to generate HTTP headers on its responses to facilitate caching the + profile pages that it creates. This can improve performance, but it can also + result in serving stale data. Default is false if not set. + For more information, see the VIVO wiki page: + + Use HTTP caching to improve performance + + + + + http.createCacheHeaders + + + true + + + Force VIVO to use a specific language or Locale instead of those diff --git a/solr/homeDirectoryTemplate/conf/schema.xml b/solr/homeDirectoryTemplate/conf/schema.xml index b784f33c9..95b616d3e 100644 --- a/solr/homeDirectoryTemplate/conf/schema.xml +++ b/solr/homeDirectoryTemplate/conf/schema.xml @@ -250,6 +250,11 @@ + + + + + diff --git a/solr/homeDirectoryTemplate/conf/solrconfig.xml b/solr/homeDirectoryTemplate/conf/solrconfig.xml index 4c6bca060..bfe0ae889 100644 --- a/solr/homeDirectoryTemplate/conf/solrconfig.xml +++ b/solr/homeDirectoryTemplate/conf/solrconfig.xml @@ -856,18 +856,14 @@ type header if posted in the body. For example, curl now requires: -H 'Content-type:text/xml; charset=utf-8' --> - - - - dedupe + etag - --> - + + @@ -1480,6 +1476,23 @@ --> + + + + true + etag + false + solr.processor.Lookup3Signature + + + + + + + + + + + + + + + + + + The Vitro build script requires Java 7 or later. + Java system property java.version = ${java.version} + Java system property java.home = ${java.home} + JAVA_HOME environment variable = ${env.JAVA_HOME} + + + + + + + + + + The Vitro build script requires Ant 1.8 or later. + Ant property ant.version = ${ant.version} + Ant property ant.home = ${ant.home} + ANT_HOME environment variable = ${env.ANT_HOME} + @@ -99,7 +129,7 @@ encoding="UTF8" includeantruntime="false" optimize="false" - source="1.6"> + source="1.7"> @@ -137,7 +167,7 @@ - + + source="1.7"> @@ -224,7 +254,7 @@ encoding="UTF8" includeantruntime="false" optimize="false" - source="1.6"> + source="1.7"> diff --git a/webapp/config/example.runtime.properties b/webapp/config/example.runtime.properties index 3802063d2..c91188ae3 100644 --- a/webapp/config/example.runtime.properties +++ b/webapp/config/example.runtime.properties @@ -120,6 +120,19 @@ proxy.eligibleTypeList = http://www.w3.org/2002/07/owl#Thing # RDFService.languageFilter = true +# +# Tell VIVO to generate HTTP headers on its responses to facilitate caching the +# profile pages that it creates. +# +# For more information, see +# https://wiki.duraspace.org/display/VIVO/Use+HTTP+caching+to+improve+performance +# +# Developers will likely want to leave caching disabled, since a change to a +# Freemarker template or to a Java class would not cause the page to be +# considered stale. +# +# http.createCacheHeaders = true + # # Force VIVO to use a specific language or Locale instead of those # specified by the browser. This affects RDF data retrieved from the model, diff --git a/webapp/config/default.log4j.properties b/webapp/config/log4j.properties similarity index 97% rename from webapp/config/default.log4j.properties rename to webapp/config/log4j.properties index 5dd5339b1..b5cf2bf83 100644 --- a/webapp/config/default.log4j.properties +++ b/webapp/config/log4j.properties @@ -20,7 +20,7 @@ # More information can be found here: # http://logging.apache.org/log4j/1.2/manual.html # -# The "production" version of this file is default.log4j.properties. +# The "production" version of this file is log4j.properties. # debug.log4j.properties exists will be used instead, if it exists, but is not stored in Subversion. log4j.appender.AllAppender=org.apache.log4j.RollingFileAppender diff --git a/webapp/src/edu/cornell/mannlib/vedit/beans/LoginStatusBean.java b/webapp/src/edu/cornell/mannlib/vedit/beans/LoginStatusBean.java index 04ec6f276..d9a719483 100644 --- a/webapp/src/edu/cornell/mannlib/vedit/beans/LoginStatusBean.java +++ b/webapp/src/edu/cornell/mannlib/vedit/beans/LoginStatusBean.java @@ -10,6 +10,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; @@ -101,13 +102,7 @@ public class LoginStatusBean { } ServletContext ctx = session.getServletContext(); - WebappDaoFactory wadf = (WebappDaoFactory) ctx - .getAttribute("webappDaoFactory"); - if (wadf == null) { - log.error("No WebappDaoFactory"); - return null; - } - + WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory(); UserAccountsDao userAccountsDao = wadf.getUserAccountsDao(); if (userAccountsDao == null) { log.error("No UserAccountsDao"); diff --git a/webapp/src/edu/cornell/mannlib/vedit/controller/BaseEditController.java b/webapp/src/edu/cornell/mannlib/vedit/controller/BaseEditController.java index b99743132..0a0bd6b87 100644 --- a/webapp/src/edu/cornell/mannlib/vedit/controller/BaseEditController.java +++ b/webapp/src/edu/cornell/mannlib/vedit/controller/BaseEditController.java @@ -25,7 +25,9 @@ import edu.cornell.mannlib.vedit.util.FormUtils; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; public class BaseEditController extends VitroHttpServlet { @@ -153,39 +155,32 @@ public class BaseEditController extends VitroHttpServlet { } } - protected String MODEL_ATTR_NAME = "jenaOntModel"; - protected OntModel getOntModel( HttpServletRequest request, ServletContext ctx ) { - + + // TODO: JB - This method gets the UNION FULL model from the session, if there is one, + // TODO and the BASE_TBOX model otherwise. OntModel ontModel = null; - - try { - ontModel = (OntModel) request.getSession().getAttribute(MODEL_ATTR_NAME); + try { + ontModel = ModelAccess.on(request.getSession()).getJenaOntModel(); } catch (Exception e) { // ignoring any problems here - we're not really expecting // this attribute to be populated anyway } if ( ontModel == null ) { - ontModel = (OntModel) ModelContext.getBaseOntModelSelector(ctx).getTBoxModel(); + ontModel = ModelAccess.on(ctx).getOntModel(ModelID.BASE_TBOX); } return ontModel; } - protected WebappDaoFactory getWebappDaoFactory(VitroRequest vreq) { - WebappDaoFactory wadf = (WebappDaoFactory) getServletContext().getAttribute( - "assertionsWebappDaoFactory"); - if (wadf == null) { - log.info("Using vreq.getFullWebappDaoFactory()"); - wadf = vreq.getFullWebappDaoFactory(); - } - return wadf; + protected WebappDaoFactory getWebappDaoFactory() { + return ModelAccess.on(getServletContext()).getBaseWebappDaoFactory(); } - protected WebappDaoFactory getWebappDaoFactory(VitroRequest vreq, String userURI) { - return getWebappDaoFactory(vreq).getUserAwareDaoFactory(userURI); + protected WebappDaoFactory getWebappDaoFactory(String userURI) { + return getWebappDaoFactory().getUserAwareDaoFactory(userURI); } public String getDefaultLandingPage(HttpServletRequest request) { diff --git a/webapp/src/edu/cornell/mannlib/vedit/util/OperationUtils.java b/webapp/src/edu/cornell/mannlib/vedit/util/OperationUtils.java index b679cddb3..809d41eda 100644 --- a/webapp/src/edu/cornell/mannlib/vedit/util/OperationUtils.java +++ b/webapp/src/edu/cornell/mannlib/vedit/util/OperationUtils.java @@ -1,7 +1,7 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ -package edu.cornell.mannlib.vedit.util; - +package edu.cornell.mannlib.vedit.util; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -9,141 +9,145 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vedit.beans.EditProcessObject; - - -public class OperationUtils{ - - private static final Log log = LogFactory.getLog(OperationUtils.class.getName()); - - public static void beanSetAndValidate(Object newObj, String field, String value, EditProcessObject epo){ - Class cls = (epo.getBeanClass() != null) ? epo.getBeanClass() : newObj.getClass(); - Class[] paramList = new Class[1]; - paramList[0] = String.class; - boolean isInt = false; - boolean isBoolean = false; - Method setterMethod = null; - try { - setterMethod = cls.getMethod("set"+field,paramList); - } catch (NoSuchMethodException e) { - //let's try int - paramList[0] = int.class; - try { - setterMethod = cls.getMethod("set"+field,paramList); - isInt = true; - } catch (NoSuchMethodException f) { - //let's try boolean - paramList[0]=boolean.class; - try { - setterMethod = cls.getMethod("set"+field,paramList); - isBoolean = true; - log.debug("found boolean field "+field); - } catch (NoSuchMethodException g) { - log.error("beanSet could not find an appropriate String, int, or boolean setter method for "+field); - } - - } - } - Object[] arglist = new Object[1]; - if (isInt) - arglist[0] = Integer.decode(value); - else if (isBoolean) - arglist[0] = (value.equalsIgnoreCase("TRUE")); - else - arglist[0] = value; - try { - setterMethod.invoke(newObj,arglist); - } catch (Exception e) { - log.error("Couldn't invoke method"); - log.error(e.getMessage()); - log.error(field+" "+arglist[0]); - } - } - - /** - * Takes a bean and clones it using reflection. - * Any fields without standard getter/setter methods will not be copied. - * @param bean - * @return - */ - public static Object cloneBean (Object bean) { - return cloneBean(bean, bean.getClass(), bean.getClass()); - } - - /** - * Takes a bean and clones it using reflection. - * Any fields without standard getter/setter methods will not be copied. - * @param bean - * @return - */ - public static Object cloneBean (Object bean, Class beanClass, Class iface){ - Object newBean = null; - try { - newBean = beanClass.newInstance(); - Method[] beanMeths = iface.getMethods(); - for (int i=0; i cls = (epo.getBeanClass() != null) ? epo.getBeanClass() : newObj + .getClass(); + Class[] paramList = new Class[1]; + paramList[0] = String.class; + boolean isInt = false; + boolean isBoolean = false; + Method setterMethod = null; + try { + setterMethod = cls.getMethod("set" + field, paramList); + } catch (NoSuchMethodException e) { + // let's try int + paramList[0] = int.class; + try { + setterMethod = cls.getMethod("set" + field, paramList); + isInt = true; + } catch (NoSuchMethodException f) { + // let's try boolean + paramList[0] = boolean.class; + try { + setterMethod = cls.getMethod("set" + field, paramList); + isBoolean = true; + log.debug("found boolean field " + field); + } catch (NoSuchMethodException g) { + log.error("beanSet could not find an appropriate String, int, or boolean setter method for " + + field); + } + + } + } + Object[] arglist = new Object[1]; + if (isInt) + arglist[0] = Integer.decode(value); + else if (isBoolean) + arglist[0] = (value.equalsIgnoreCase("TRUE")); + else + arglist[0] = value; + try { + setterMethod.invoke(newObj, arglist); + } catch (Exception e) { + log.error("Couldn't invoke method"); + log.error(e.getMessage()); + log.error(field + " " + arglist[0]); + } + } + + /** + * Takes a bean and clones it using reflection. Any fields without standard + * getter/setter methods will not be copied. + */ + public static Object cloneBean(Object bean) { + if (bean == null) { + throw new NullPointerException("bean may not be null."); + } + return cloneBean(bean, bean.getClass(), bean.getClass()); + } + + /** + * Takes a bean and clones it using reflection. Any fields without standard + * getter/setter methods will not be copied. + */ + public static Object cloneBean(final Object bean, final Class beanClass, + final Class iface) { + if (bean == null) { + throw new NullPointerException("bean may not be null."); + } + if (beanClass == null) { + throw new NullPointerException("beanClass may not be null."); + } + if (iface == null) { + throw new NullPointerException("iface may not be null."); + } + + class CloneBeanException extends RuntimeException { + public CloneBeanException(String message, Throwable cause) { + super(message + " <" + cause.getClass().getSimpleName() + + ">: bean=" + bean + ", beanClass=" + + beanClass.getName() + ", iface=" + iface.getName(), + cause); + } + } + + Object newBean; + try { + newBean = beanClass.getConstructor().newInstance(); + } catch (NoSuchMethodException e) { + throw new CloneBeanException("bean has no 'nullary' constructor.", e); + } catch (InstantiationException e) { + throw new CloneBeanException("tried to create instance of an abstract class.", e); + } catch (IllegalAccessException e) { + throw new CloneBeanException("bean constructor is not accessible.", e); + } catch (InvocationTargetException e) { + throw new CloneBeanException("bean constructor threw an exception.", e); + } catch (Exception e) { + throw new CloneBeanException("failed to instantiate a new bean.", e); + } + + for (Method beanMeth : iface.getMethods()) { + String methName = beanMeth.getName(); + if (!methName.startsWith("get")) { + continue; + } + if (beanMeth.getParameterTypes().length != 0) { + continue; + } + String fieldName = methName.substring(3, methName.length()); + Class returnType = beanMeth.getReturnType(); + + Method setterMethod; + try { + setterMethod = iface.getMethod("set" + fieldName, returnType); + } catch (NoSuchMethodException nsme) { + continue; + } + + Object fieldVal; + try { + fieldVal = beanMeth.invoke(bean, (Object[]) null); + } catch (Exception e) { + throw new CloneBeanException("failed to invoke " + beanMeth, e); + } + + try { + Object[] setArgs = new Object[1]; + setArgs[0] = fieldVal; + setterMethod.invoke(newBean, setArgs); + } catch (Exception e) { + throw new CloneBeanException( + "failed to invoke " + setterMethod, e); + } + } + return newBean; + } + } \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsBlacklisted.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsBlacklisted.java index 21ecf1741..ea00f16d7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsBlacklisted.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsBlacklisted.java @@ -16,18 +16,19 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; -import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.RDFNode; import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.beans.Individual; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; /** * The current user is blacklisted for this reason. @@ -152,7 +153,7 @@ public class IsBlacklisted extends AbstractCommonIdentifier implements return NOT_BLACKLISTED; } - Model model = (Model) context.getAttribute("jenaOntModel"); + OntModel model = ModelAccess.on(context).getJenaOntModel(); queryString = queryString.replaceAll("\\?individualURI", "<" + ind.getURI() + ">"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java index ff5693355..2a45c4769 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java @@ -6,6 +6,7 @@ import javax.servlet.ServletContext; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundleFactory; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; @@ -24,16 +25,7 @@ public abstract class BaseIdentifierBundleFactory implements throw new NullPointerException("ctx may not be null."); } this.ctx = ctx; - - Object wdfObject = ctx.getAttribute("webappDaoFactory"); - if (wdfObject instanceof WebappDaoFactory) { - this.wdf = (WebappDaoFactory) wdfObject; - } else { - throw new IllegalStateException( - "Didn't find a WebappDaoFactory in the context. Found '" - + wdfObject + "' instead."); - } - + this.wdf = ModelAccess.on(ctx).getWebappDaoFactory(); this.uaDao = wdf.getUserAccountsDao(); this.indDao = wdf.getIndividualDao(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java index c98120dec..80aae91d2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java @@ -114,9 +114,11 @@ public class DisplayByRolePermission extends Permission { ObjectPropertyStatement stmt = action.getObjectPropertyStatement(); String subjectUri = stmt.getSubjectURI(); String predicateUri = stmt.getPropertyURI(); + String rangeUri = (stmt.getProperty() == null) ? null + : stmt.getProperty().getRangeVClassURI(); String objectUri = stmt.getObjectURI(); return canDisplayResource(subjectUri) - && canDisplayPredicate(predicateUri) + && canDisplayPredicate(predicateUri, rangeUri) && canDisplayResource(objectUri); } @@ -124,10 +126,14 @@ public class DisplayByRolePermission extends Permission { return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource( resourceUri, this.roleLevel); } - + private boolean canDisplayPredicate(String predicateUri) { + return canDisplayPredicate(predicateUri, null); + } + + private boolean canDisplayPredicate(String predicateUri, String rangeUri) { return PropertyRestrictionPolicyHelper.getBean(ctx) - .canDisplayPredicate(predicateUri, this.roleLevel); + .canDisplayPredicate(predicateUri, rangeUri, this.roleLevel); } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsLoader.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsLoader.java index 8b1f457d5..94608e5a1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsLoader.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsLoader.java @@ -32,10 +32,10 @@ import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; /** @@ -100,8 +100,7 @@ public class PermissionSetsLoader implements ServletContextListener { this.ctx = ctx; this.ss = ss; - this.userAccountsModel = ModelContext.getBaseOntModelSelector(ctx) - .getUserAccountsModel(); + this.userAccountsModel = ModelAccess.on(ctx).getUserAccountsModel(); this.permissionSetType = this.userAccountsModel .getProperty(VitroVocabulary.PERMISSIONSET); @@ -274,8 +273,7 @@ public class PermissionSetsLoader implements ServletContextListener { this.ctx = ctx; this.ss = ss; - WebappDaoFactory wadf = (WebappDaoFactory) ctx - .getAttribute("webappDaoFactory"); + WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory(); if (wadf == null) { throw new IllegalStateException( "No webappDaoFactory on the servlet context"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicy.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicy.java index 9c635a6cf..2b43662e2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicy.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicy.java @@ -2,8 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy; -import java.util.Collections; -import java.util.Set; import java.util.TreeSet; import javax.servlet.ServletContext; @@ -23,8 +21,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; /** @@ -79,7 +77,8 @@ public class RootUserPolicy implements PolicyIface { ss = StartupStatus.getBean(ctx); try { - uaDao = getUserAccountsDao(); + uaDao = ModelAccess.on(ctx).getWebappDaoFactory() + .getUserAccountsDao(); configuredRootUser = getRootEmailFromConfig(); otherRootUsers = getEmailsOfAllRootUsers(); @@ -105,16 +104,6 @@ public class RootUserPolicy implements PolicyIface { } } - private UserAccountsDao getUserAccountsDao() { - WebappDaoFactory wadf = (WebappDaoFactory) ctx - .getAttribute("webappDaoFactory"); - if (wadf == null) { - throw new IllegalStateException( - "No webappDaoFactory on the servlet context"); - } - return wadf.getUserAccountsDao(); - } - private String getRootEmailFromConfig() { String email = ConfigurationProperties.getBean(ctx).getProperty( PROPERTY_ROOT_USER_EMAIL); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java index 6afeb27b0..c79e593ad 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java @@ -8,11 +8,13 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.rdf.model.Model; import edu.cornell.mannlib.vedit.beans.EditProcessObject; import edu.cornell.mannlib.vedit.listener.ChangeListener; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.Property; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; /** * Add this ChangeListener to your EditProcessObject when modifying the @@ -90,9 +92,10 @@ public class PropertyRestrictionListener implements ChangeListener { } private void createAndSetBean() { - OntModel model = (OntModel) ctx.getAttribute("jenaOntModel"); + OntModel model = ModelAccess.on(ctx).getJenaOntModel(); + Model displayModel = ModelAccess.on(ctx).getDisplayModel(); PropertyRestrictionPolicyHelper bean = PropertyRestrictionPolicyHelper - .createBean(model); + .createBean(model, displayModel); PropertyRestrictionPolicyHelper.setBean(ctx, bean); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java index 68ee18b04..dd27d126a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelper.java @@ -17,6 +17,13 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; @@ -26,6 +33,7 @@ import com.hp.hpl.jena.rdf.model.impl.Util; import com.hp.hpl.jena.shared.Lock; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; @@ -96,7 +104,10 @@ public class PropertyRestrictionPolicyHelper { * Initialize the bean with the standard prohibitions and exceptions, and * with the thresholds obtained from the model. */ - public static PropertyRestrictionPolicyHelper createBean(OntModel model) { + public static PropertyRestrictionPolicyHelper createBean(OntModel model, + Model displayModel) { + + Map displayThresholdMap = new HashMap(); Map modifyThresholdMap = new HashMap(); @@ -111,7 +122,7 @@ public class PropertyRestrictionPolicyHelper { PropertyRestrictionPolicyHelper bean = new PropertyRestrictionPolicyHelper( PROHIBITED_NAMESPACES, PERMITTED_EXCEPTIONS, - displayThresholdMap, modifyThresholdMap); + displayThresholdMap, modifyThresholdMap, displayModel); return bean; } @@ -171,6 +182,8 @@ public class PropertyRestrictionPolicyHelper { * the threshold role. */ private final Map modifyThresholdMap; + + private final Model displayModel; /** * Store unmodifiable versions of the inputs. @@ -182,11 +195,13 @@ public class PropertyRestrictionPolicyHelper { Collection modifyProhibitedNamespaces, Collection modifyExceptionsAllowedUris, Map displayThresholdMap, - Map modifyThresholdMap) { + Map modifyThresholdMap, + Model displayModel) { this.modifyProhibitedNamespaces = unmodifiable(modifyProhibitedNamespaces); this.modifyExceptionsAllowedUris = unmodifiable(modifyExceptionsAllowedUris); this.displayThresholdMap = unmodifiable(displayThresholdMap); this.modifyThresholdMap = unmodifiable(modifyThresholdMap); + this.displayModel = displayModel; if (log.isDebugEnabled()) { log.debug("prohibited: " + this.modifyProhibitedNamespaces); @@ -256,18 +271,33 @@ public class PropertyRestrictionPolicyHelper { log.debug("can modify resource '" + resourceUri + "'"); return true; } + + public boolean canDisplayPredicate(String predicateUri, RoleLevel userRole) { + return canDisplayPredicate(predicateUri, null, userRole); + } /** * If display of a predicate is restricted, the user's role must be at least * as high as the restriction level. */ - public boolean canDisplayPredicate(String predicateUri, RoleLevel userRole) { + public boolean canDisplayPredicate(String predicateUri, String rangeUri, RoleLevel userRole) { if (predicateUri == null) { log.debug("can't display predicate: predicateUri was null"); return false; } - - RoleLevel displayThreshold = displayThresholdMap.get(predicateUri); + + RoleLevel displayThreshold = RoleLevel.NOBODY; + if (rangeUri == null) { + displayThreshold = displayThresholdMap.get(predicateUri); + } else { + log.debug("Getting display threshold for " + predicateUri + " " + rangeUri); + displayThreshold = getDisplayThreshold(predicateUri, rangeUri); + if (displayThreshold == null) { + displayThreshold = displayThresholdMap.get(predicateUri); + } + log.debug(displayThreshold); + } + if (isAuthorized(userRole, displayThreshold)) { log.debug("can display predicate: '" + predicateUri + "', userRole=" + userRole + ", thresholdRole=" @@ -279,7 +309,45 @@ public class PropertyRestrictionPolicyHelper { + userRole + ", thresholdRole=" + displayThreshold); return false; } - + + /** + * Gets the role level threshold for displaying a predicate with a particular + * object class + * @param predicateUri + * @param rangeUri + * @return RoleLevel threshold + */ + private RoleLevel getDisplayThreshold(String predicateUri, String rangeUri) { + String query = "PREFIX rdfs: \n" + + "PREFIX config: \n" + + "PREFIX vitro: \n" + + "SELECT ?level WHERE { \n" + +// " ?p rdfs:subPropertyOf ?property . \n" + + " ?context config:configContextFor ?p . \n" + + " ?context config:qualifiedBy ?range . \n" + + " ?context config:hasConfiguration ?configuration . \n" + + " ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?level \n" + + "}"; + Query q = QueryFactory.create(query); + QueryExecution qe = QueryExecutionFactory.create(q, displayModel); + try { + ResultSet rs = qe.execSelect(); + if (!rs.hasNext()) { + return null; + } + while(rs.hasNext()) { + QuerySolution qsoln = rs.nextSolution(); + Resource levelRes = qsoln.getResource("level"); + if (levelRes != null) { + return RoleLevel.getRoleByUri(levelRes.getURI()); + } + } + } finally { + qe.close(); + } + return null; + } + /** * A predicate cannot be modified if its namespace is in the prohibited list * (some exceptions are allowed). @@ -344,14 +412,19 @@ public class PropertyRestrictionPolicyHelper { StartupStatus ss = StartupStatus.getBean(ctx); try { - OntModel model = (OntModel) ctx.getAttribute("jenaOntModel"); + OntModel model = ModelAccess.on(ctx).getJenaOntModel(); if (model == null) { throw new NullPointerException( "jenaOntModel has not been initialized."); } - + Model displayModel = ModelAccess.on(ctx).getDisplayModel(); + if (displayModel == null) { + throw new NullPointerException( + "display model has not been initialized."); + } + PropertyRestrictionPolicyHelper bean = PropertyRestrictionPolicyHelper - .createBean(model); + .createBean(model, displayModel); PropertyRestrictionPolicyHelper.setBean(ctx, bean); } catch (Exception e) { ss.fatal(this, "could not set up PropertyRestrictionPolicyHelper", e); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/DataPropertyComparator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/DataPropertyComparator.java index d6d562384..796edaeb1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/DataPropertyComparator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/DataPropertyComparator.java @@ -44,8 +44,8 @@ public class DataPropertyComparator implements Comparator { } if (datatype == null) { log.warn("Can't compare data property statements: no datatype specified."); - // Perhaps we should throw an error here, but for now we need it to return 0 - return 0; + // Perhaps we should throw an error here, but for now we need it to set the datatype + datatype = XSD.xint.toString(); } if (XSD.xint.toString().equals(datatype)) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClass.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClass.java index 41d4b8799..849cd7f5e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClass.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClass.java @@ -129,6 +129,29 @@ public class VClass extends BaseResourceBean implements Comparable localName = uri.getLocalName(); } + /** + * Constructs the VClass as a deep copy of an existing VClass. + */ + public VClass( VClass vc) { + this.URI = vc.URI; + this.namespace = vc.namespace; + this.localName = vc.localName; + this.myName = vc.myName; + this.myExample = vc.myExample; + this.myDescription = vc.myDescription; + this.myShortDefinition = vc.myShortDefinition; + this.myEntityCount = vc.myEntityCount; + this.displayLimit = vc.displayLimit; + this.displayRank = vc.displayRank; + this.quickEditJsp = vc.quickEditJsp; + this.groupURI = vc.groupURI; + this.group = (vc.group == null) ? null : new VClassGroup(vc.group); + this.customEntryForm = vc.customEntryForm; + this.customDisplayView = vc.customDisplayView; + this.customShortView = vc.customShortView; + this.customSearchView = vc.customSearchView; + } + /** * Sorts alphabetically by name */ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClassGroup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClassGroup.java index 734d02d42..8a975ff3f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClassGroup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClassGroup.java @@ -62,6 +62,15 @@ public class VClassGroup extends LinkedList implements Comparable 1) { - backString = " back"; - } - String name = userAccount.getFirstName(); - if (!StringUtils.isEmpty(name)) { - greeting = name; + loginCount = userAccount.getLoginCount(); + if (StringUtils.isNotEmpty(userAccount.getFirstName())) { + greeting = userAccount.getFirstName(); + } else if (StringUtils.isNotEmpty(userAccount.getEmailAddress())) { + greeting = userAccount.getEmailAddress(); } } - return "Welcome" + backString + ", " + greeting; + return i18n.text("login_welcome_message", greeting, loginCount); } public void redirectCancellingUser(HttpServletResponse response) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Authenticate.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Authenticate.java index df1e5bbca..142d9b4d4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Authenticate.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Authenticate.java @@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.controller.edit; import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MAX_PASSWORD_LENGTH; import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MIN_PASSWORD_LENGTH; +import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.MLevel.ERROR; import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.FORCED_PASSWORD_CHANGE; import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.LOGGED_IN; import static edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State.LOGGING_IN; @@ -37,8 +38,8 @@ import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator.Lo import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginInProcessFlag; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginRedirector; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean; -import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.Message; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.jena.LoginLogoutEvent; public class Authenticate extends VitroHttpServlet { @@ -308,7 +309,7 @@ public class Authenticate extends VitroHttpServlet { + bean); if ((username == null) || username.isEmpty()) { - bean.setMessage(Message.NO_USERNAME); + bean.setMessage(request, ERROR, "error_no_email_address"); return; } @@ -319,22 +320,22 @@ public class Authenticate extends VitroHttpServlet { log.trace("User is " + (user == null ? "null" : user.getUri())); if (user == null) { - bean.setMessage(Message.UNKNOWN_USERNAME, username); + bean.setMessage(request, ERROR, "error_incorrect_credentials"); return; } if ((password == null) || password.isEmpty()) { - bean.setMessage(Message.NO_PASSWORD); + bean.setMessage(request, ERROR, "error_no_password"); return; } if (!getAuthenticator(request).isUserPermittedToLogin(user)) { - bean.setMessage(Message.LOGIN_DISABLED); + bean.setMessage(request, ERROR, "logins_disabled_for_maintenance"); return; } if (!getAuthenticator(request).isCurrentPassword(user, password)) { - bean.setMessage(Message.INCORRECT_PASSWORD); + bean.setMessage(request, ERROR, "error_incorrect_credentials"); return; } @@ -346,7 +347,8 @@ public class Authenticate extends VitroHttpServlet { transitionToLoggedIn(request, user); } catch (LoginNotPermitted e) { // This should have been caught by isUserPermittedToLogin() - bean.setMessage(Message.LOGIN_DISABLED); + bean.setMessage(request, ERROR, + "logins_disabled_for_maintenance"); return; } } @@ -378,19 +380,19 @@ public class Authenticate extends VitroHttpServlet { + ", bean=" + bean); if ((newPassword == null) || newPassword.isEmpty()) { - bean.setMessage(Message.NO_NEW_PASSWORD); + bean.setMessage(request, ERROR, "error_no_new_password"); return; } if (!newPassword.equals(confirm)) { - bean.setMessage(Message.MISMATCH_PASSWORD); + bean.setMessage(request, ERROR, "error_passwords_dont_match"); return; } if ((newPassword.length() < MIN_PASSWORD_LENGTH) || (newPassword.length() > MAX_PASSWORD_LENGTH)) { - bean.setMessage(Message.PASSWORD_LENGTH, MIN_PASSWORD_LENGTH, - MAX_PASSWORD_LENGTH); + bean.setMessage(request, ERROR, "error_password_length", + MIN_PASSWORD_LENGTH, MAX_PASSWORD_LENGTH); return; } @@ -399,7 +401,7 @@ public class Authenticate extends VitroHttpServlet { UserAccount user = getAuthenticator(request).getAccountForInternalAuth( username); if (getAuthenticator(request).isCurrentPassword(user, newPassword)) { - bean.setMessage(Message.USING_OLD_PASSWORD); + bean.setMessage(request, ERROR, "error_previous_password"); return; } @@ -408,7 +410,7 @@ public class Authenticate extends VitroHttpServlet { transitionToLoggedIn(request, user, newPassword); } catch (LoginNotPermitted e) { // This should have been caught by isUserPermittedToLogin() - bean.setMessage(Message.LOGIN_DISABLED); + bean.setMessage(request, ERROR, "logins_disabled_for_maintenance"); return; } } @@ -557,16 +559,7 @@ public class Authenticate extends VitroHttpServlet { return; } - OntModel jenaOntModel = (OntModel) session.getAttribute("jenaOntModel"); - if (jenaOntModel == null) { - jenaOntModel = (OntModel) context.getAttribute("jenaOntModel"); - } - if (jenaOntModel == null) { - log.error("Unable to notify audit model of login event " - + "because no model could be found"); - return; - } - + OntModel jenaOntModel = ModelAccess.on(session).getJenaOntModel(); jenaOntModel.getBaseModel().notifyEvent(event); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DeletePageController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DeletePageController.java index 06ccd95d1..d66f93b2d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DeletePageController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/DeletePageController.java @@ -23,6 +23,7 @@ import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.shared.Lock; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; @@ -38,6 +39,9 @@ public class DeletePageController extends VitroHttpServlet { @Override protected void doPost(HttpServletRequest rawRequest, HttpServletResponse resp) throws ServletException, IOException { + if (!isAuthorizedToDisplayPage(rawRequest, resp, SimplePermission.MANAGE_MENUS.ACTION)) { + return; + } removeStatements = ModelFactory.createDefaultModel(); VitroRequest vreq = new VitroRequest(rawRequest); String pageUri = vreq.getParameter("pageURI"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityRetryController.java index 440848469..114ab1118 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityRetryController.java @@ -79,8 +79,7 @@ public class EntityRetryController extends BaseEditController { } LoginStatusBean loginBean = LoginStatusBean.getBean(request); - WebappDaoFactory myWebappDaoFactory = getWebappDaoFactory( - vreq, loginBean.getUserURI()); + WebappDaoFactory myWebappDaoFactory = getWebappDaoFactory(loginBean.getUserURI()); IndividualDao ewDao = myWebappDaoFactory.getIndividualDao(); epo.setDataAccessObject(ewDao); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Logout.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Logout.java index d052c627d..3ab84257d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Logout.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Logout.java @@ -12,6 +12,7 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LogoutRedirector; +import edu.cornell.mannlib.vitro.webapp.i18n.I18n; /** * Provide a means for programmatic logout. @@ -22,13 +23,14 @@ public class Logout extends HttpServlet { /** This http header holds the referring page. */ private static final String HEADING_REFERRER = "referer"; + @Override public void doPost(HttpServletRequest request, HttpServletResponse response) { try { String referrer = getReferringPage(request); String redirectUrl = LogoutRedirector.getRedirectUrl(request, response, referrer); Authenticator.getInstance(request).recordUserIsLoggedOut(); - DisplayMessage.setMessage(request, "You have logged out."); + DisplayMessage.setMessage(request, I18n.bundle(request).text("logged_out")); response.sendRedirect(redirectUrl); } catch (Exception ex) { @@ -45,6 +47,7 @@ public class Logout extends HttpServlet { return referrer; } + @Override public void doGet(HttpServletRequest request, HttpServletResponse response) { doPost(request, response); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/NamespacePrefixOperationController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/NamespacePrefixOperationController.java index 50e60642b..2015b88e5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/NamespacePrefixOperationController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/NamespacePrefixOperationController.java @@ -24,6 +24,7 @@ import edu.cornell.mannlib.vedit.beans.EditProcessObject; import edu.cornell.mannlib.vedit.controller.BaseEditController; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; public class NamespacePrefixOperationController extends BaseEditController { @@ -68,7 +69,7 @@ public class NamespacePrefixOperationController extends BaseEditController { if (request.getParameter("_cancel") == null) { - OntModel ontModel = (OntModel) getServletContext().getAttribute("jenaOntModel"); + OntModel ontModel = ModelAccess.on(getServletContext()).getJenaOntModel(); String namespaceStr = request.getParameter("namespace"); String prefixStr = request.getParameter("prefix"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RefactorOperationController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RefactorOperationController.java index 57596ac7d..60769e8d9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RefactorOperationController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/RefactorOperationController.java @@ -7,7 +7,6 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import javax.servlet.RequestDispatcher; import javax.servlet.http.HttpServletRequest; @@ -40,7 +39,6 @@ import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.shared.InvalidPropertyURIException; import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.util.ResourceUtils; -import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.util.iterator.ExtendedIterator; import com.hp.hpl.jena.vocabulary.RDF; @@ -50,7 +48,8 @@ import edu.cornell.mannlib.vedit.controller.BaseEditController; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent; import edu.cornell.mannlib.vitro.webapp.servlet.setup.FileGraphSetup; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; @@ -74,7 +73,7 @@ public class RefactorOperationController extends BaseEditController { request.setAttribute("title","Check Datatype Properties"); request.setAttribute("css", ""); - OntModel ontModel = (OntModel) getServletContext().getAttribute("baseOntModel"); + OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); ontModel.enterCriticalSection(Lock.WRITE); ArrayList results = new ArrayList(); @@ -236,10 +235,10 @@ public class RefactorOperationController extends BaseEditController { Model model = null; if (JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL.equals(graphURI)) { - model = ModelContext.getBaseOntModelSelector(getServletContext()).getTBoxModel(); + model = ModelAccess.on(getServletContext()).getOntModel(ModelID.BASE_TBOX); doNotify = true; } else if (JenaDataSourceSetupBase.JENA_DB_MODEL.equals(graphURI)) { - model = ModelContext.getBaseOntModelSelector(getServletContext()).getABoxModel(); + model = ModelAccess.on(getServletContext()).getOntModel(ModelID.BASE_ABOX); doNotify = true; } else { model = dataset.getNamedModel(graphURI); @@ -252,8 +251,7 @@ public class RefactorOperationController extends BaseEditController { dataset.getLock().leaveCriticalSection(); } - renameResourceInModel(ModelContext.getOntModelSelector( - getServletContext()).getUserAccountsModel(), + renameResourceInModel(ModelAccess.on(getServletContext()).getUserAccountsModel(), userURI, oldURIStr, newURIStr, !NOTIFY); // there are no statements to delete, but we want indexes updated appropriately @@ -330,7 +328,7 @@ public class RefactorOperationController extends BaseEditController { private void doMovePropertyStatements(VitroRequest request, HttpServletResponse response, EditProcessObject epo) { String userURI = LoginStatusBean.getBean(request).getUserURI(); - OntModel ontModel = ModelContext.getBaseOntModel(getServletContext()); + OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); Model tempRetractModel = ModelFactory.createDefaultModel(); Model tempAddModel = ModelFactory.createDefaultModel(); @@ -414,7 +412,7 @@ public class RefactorOperationController extends BaseEditController { private void doMoveInstances(VitroRequest request, HttpServletResponse response, EditProcessObject epo) { String userURI = LoginStatusBean.getBean(request).getUserURI(); - OntModel ontModel = ModelContext.getBaseOntModel(getServletContext()); + OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); String oldClassURIStr = (String) epo.getAttribute("VClassURI"); String newClassURIStr = (String) request.getParameter("NewVClassURI"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/ClassHierarchyListingController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/ClassHierarchyListingController.java index 2bab7453e..2fdcc9cef 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/ClassHierarchyListingController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/ClassHierarchyListingController.java @@ -27,6 +27,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; @@ -52,8 +53,8 @@ public class ClassHierarchyListingController extends BaseEditController { try { boolean inferred = (vrequest.getParameter("inferred") != null); - if (vrequest.getAssertionsWebappDaoFactory() != null && !inferred) { - vcDao = vrequest.getAssertionsWebappDaoFactory().getVClassDao(); + if (!inferred) { + vcDao = ModelAccess.on(vrequest).getBaseWebappDaoFactory().getVClassDao(); } else { vcDao = vrequest.getFullWebappDaoFactory().getVClassDao(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/NamespacesListingController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/NamespacesListingController.java index dda705e85..70845da91 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/NamespacesListingController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/NamespacesListingController.java @@ -22,6 +22,7 @@ import edu.cornell.mannlib.vedit.controller.BaseEditController; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; public class NamespacesListingController extends BaseEditController { @@ -34,7 +35,7 @@ public class NamespacesListingController extends BaseEditController { VitroRequest vrequest = new VitroRequest(request); - OntModel ontModel = (OntModel) getServletContext().getAttribute("jenaOntModel"); + OntModel ontModel = ModelAccess.on(getServletContext()).getJenaOntModel(); ArrayList results = new ArrayList(); request.setAttribute("results",results); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/RestrictionsListingController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/RestrictionsListingController.java index 1788dc42c..80dc8262f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/RestrictionsListingController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/listing/jena/RestrictionsListingController.java @@ -33,6 +33,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; @@ -51,8 +52,8 @@ public class RestrictionsListingController extends BaseEditController { epo = super.createEpo(request); - OntModel ontModel = (OntModel) getServletContext().getAttribute("jenaOntModel"); - + OntModel ontModel = ModelAccess.on(getServletContext()).getJenaOntModel(); + ObjectPropertyDao opDao = vrequest.getFullWebappDaoFactory().getObjectPropertyDao(); VClassDao vcDao = vrequest.getFullWebappDaoFactory().getVClassDao(); IndividualDao iDao = vrequest.getFullWebappDaoFactory().getIndividualDao(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BrowseController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BrowseController.java index bf7877b74..ff921ce64 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BrowseController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BrowseController.java @@ -17,6 +17,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; +import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; @@ -46,7 +47,6 @@ public class BrowseController extends FreemarkerHttpServlet { protected ResponseValues processRequest(VitroRequest vreq) { Map body = new HashMap(); - String message = null; String templateName = TEMPLATE_DEFAULT; if ( vreq.getParameter("clearcache") != null ) { @@ -57,25 +57,13 @@ public class BrowseController extends FreemarkerHttpServlet { } List groups = null; - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(getServletContext()); - if ( vcgc == null ) { - log.error("Could not get VClassGroupCache"); - message = "The system is not configured correctly. Please check your logs for error messages."; - } else { - groups =vcgc.getGroups(); - List vcgroups = new ArrayList(groups.size()); - for (VClassGroup group : groups) { - vcgroups.add(new VClassGroupTemplateModel(group)); - } - body.put("classGroups", vcgroups); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); + groups =vcgc.getGroups(); + List vcgroups = new ArrayList(groups.size()); + for (VClassGroup group : groups) { + vcgroups.add(new VClassGroupTemplateModel(group)); } - - if (message != null) { - body.put("message", message); - templateName = Template.TITLED_MESSAGE.toString(); - } - - + body.put("classGroups", vcgroups); return new TemplateResponseValues(templateName, body); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/DeletePropertyController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/DeletePropertyController.java index 39e408a76..cabce6eba 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/DeletePropertyController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/DeletePropertyController.java @@ -17,6 +17,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.RedirectResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; 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.processEdit.EditN3Utils; @@ -200,7 +201,7 @@ public class DeletePropertyController extends FreemarkerHttpServlet { Individual object = EditConfigurationUtils.getIndividual(vreq, objectUri); if(object == null) { - WebappDaoFactory wadf = (WebappDaoFactory) vreq.getSession().getServletContext().getAttribute("webappDaoFactory"); + WebappDaoFactory wadf = ModelAccess.on(vreq.getSession().getServletContext()).getWebappDaoFactory(); object = wadf.getIndividualDao().getIndividualByURI(objectUri); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/HomePageController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/HomePageController.java index 6dfa102d7..22aaaa804 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/HomePageController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/HomePageController.java @@ -9,6 +9,7 @@ import java.util.List; 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; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; @@ -48,6 +49,7 @@ public class HomePageController extends FreemarkerHttpServlet { } }*/ body.put("dataServiceUrlVClassesForVClassGroup", UrlBuilder.getUrl("/dataservice?getVClassesForVClassGroup=1&classgroupUri=")); + body.put("geoFocusMapsEnabled", getGeoFocusMapsFlag(vreq)); return new TemplateResponseValues(BODY_TEMPLATE, body); } @@ -61,4 +63,11 @@ public class HomePageController extends FreemarkerHttpServlet { protected String getPageTemplateName() { return PAGE_TEMPLATE; } + + private boolean getGeoFocusMapsFlag(VitroRequest vreq) { + String property = ConfigurationProperties.getBean(vreq).getProperty( + "homePage.geoFocusMaps"); + return "enabled".equals(property); + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java index 842a6201d..dcbe01f07 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java @@ -36,6 +36,7 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup; import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest; +import edu.cornell.mannlib.vitro.webapp.i18n.I18n; import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil; /** @@ -48,6 +49,9 @@ public class ImageUploadController extends FreemarkerHttpServlet { private static final String ATTRIBUTE_REFERRING_PAGE = "ImageUploadController.referringPage"; + private static final String ERROR_CODE_UNRECOGNIZED_URI = "imageUpload.errorUnrecognizedURI"; + private static final String ERROR_CODE_NO_URI = "imageUpload.errorNoURI"; + /** Limit file size to 6 megabytes. */ public static final int MAXIMUM_FILE_SIZE = 6 * 1024 * 1024; @@ -97,6 +101,14 @@ public class ImageUploadController extends FreemarkerHttpServlet { private static final String URL_HERE = UrlBuilder.getUrl("/uploadImages"); + private static final String TEXT_BUNDLE = "imageUpload"; + private static final String TEXT_STRING_UPLOAD_TITLE = "upload_page_title"; + private static final String TEXT_STRING_UPLOAD_TITLE_WITH_NAME = "upload_page_title_with_name"; + private static final String TEXT_STRING_REPLACE_TITLE = "replace_page_title"; + private static final String TEXT_STRING_REPLACE_TITLE_WITH_NAME = "replace_page_title_with_name"; + private static final String TEXT_STRING_CROP_TITLE = "crop_page_title"; + private static final String TEXT_STRING_CROP_TITLE_WITH_NAME = "crop_page_title_with_name"; + private FileStorage fileStorage; /** @@ -218,7 +230,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { } } catch (UserMistakeException e) { // Can't find the entity? Complain. - return showAddImagePageWithError(vreq, null, e.getMessage()); + return showAddImagePageWithError(vreq, null, e.formatMessage(vreq)); } catch (Exception e) { // We weren't expecting this - log it, and apologize to the user. return new ExceptionResponseValues(e); @@ -274,7 +286,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { return showCropImagePage(vreq, entity, fileInfo.getBytestreamAliasUrl(), size); } catch (UserMistakeException e) { - return showErrorMessage(vreq, entity, e.getMessage()); + return showErrorMessage(vreq, entity, e.formatMessage(vreq)); } } @@ -284,6 +296,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { */ private ResponseValues showErrorMessage(VitroRequest vreq, Individual entity, String message) { + ImageInfo imageInfo = ImageInfo.instanceFromEntityUri( vreq.getFullWebappDaoFactory(), entity); if (imageInfo == null) { @@ -313,7 +326,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { return showExitPage(vreq, entity); } catch (UserMistakeException e) { - return showErrorMessage(vreq, entity, e.getMessage()); + return showErrorMessage(vreq, entity, e.formatMessage(vreq)); } } @@ -350,15 +363,14 @@ public class ImageUploadController extends FreemarkerHttpServlet { throws UserMistakeException { String entityUri = vreq.getParameter(PARAMETER_ENTITY_URI); if (entityUri == null) { - throw new UserMistakeException("No entity URI was provided"); + throw new UserMistakeException(ERROR_CODE_NO_URI); } Individual entity = vreq.getFullWebappDaoFactory().getIndividualDao() .getIndividualByURI(entityUri); if (entity == null) { - throw new UserMistakeException( - "This URI is not recognized as belonging to anyone: '" - + entityUri + "'"); + throw new UserMistakeException(ERROR_CODE_UNRECOGNIZED_URI, + entityUri); } return entity; } @@ -416,7 +428,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { rv.put(BODY_THUMBNAIL_URL, placeholderUrl); rv.put(BODY_FORM_ACTION, formAction); rv.put(BODY_CANCEL_URL, cancelUrl); - rv.put(BODY_TITLE, "Upload image" + forName(entity)); + rv.put(BODY_TITLE, figureUploadPageTitle(vreq, entity)); rv.put(BODY_MAX_FILE_SIZE, MAXIMUM_FILE_SIZE / (1024 * 1024)); rv.put(BODY_THUMBNAIL_HEIGHT, THUMBNAIL_HEIGHT); rv.put(BODY_THUMBNAIL_WIDTH, THUMBNAIL_WIDTH); @@ -442,7 +454,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { rv.put(BODY_DELETE_URL, formAction(entity.getURI(), ACTION_DELETE_EDIT)); rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_UPLOAD)); rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI())); - rv.put(BODY_TITLE, "Replace image" + forName(entity)); + rv.put(BODY_TITLE, figureReplacePageTitle(vreq, entity)); rv.put(BODY_MAX_FILE_SIZE, MAXIMUM_FILE_SIZE / (1024 * 1024)); rv.put(BODY_THUMBNAIL_HEIGHT, THUMBNAIL_HEIGHT); rv.put(BODY_THUMBNAIL_WIDTH, THUMBNAIL_WIDTH); @@ -472,7 +484,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { rv.put(BODY_MAIN_IMAGE_WIDTH, dimensions.width); rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_SAVE)); rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI())); - rv.put(BODY_TITLE, "Crop Photo" + forName(entity)); + rv.put(BODY_TITLE, figureCropPageTitle(vreq, entity)); return rv; } @@ -522,24 +534,59 @@ public class ImageUploadController extends FreemarkerHttpServlet { } /** - * Format the entity's name for display as part of the page title. + * Format the title for the Upload page. */ - private String forName(Individual entity) { + private String figureUploadPageTitle(HttpServletRequest req, + Individual entity) { + return figurePageTitle(req, entity, TEXT_STRING_UPLOAD_TITLE, + TEXT_STRING_UPLOAD_TITLE_WITH_NAME); + } + + /** + * Format the title for the Replace page. + */ + private String figureReplacePageTitle(HttpServletRequest req, + Individual entity) { + return figurePageTitle(req, entity, TEXT_STRING_REPLACE_TITLE, + TEXT_STRING_REPLACE_TITLE_WITH_NAME); + } + + /** + * Format the title for the Crop page. + */ + private String figureCropPageTitle(HttpServletRequest req, Individual entity) { + return figurePageTitle(req, entity, TEXT_STRING_CROP_TITLE, + TEXT_STRING_CROP_TITLE_WITH_NAME); + } + + /** + * Format one of two page titles, depending on whether the entity has a + * name. + */ + private String figurePageTitle(HttpServletRequest req, Individual entity, + String noNameTitleKey, String nameTitleKey) { if (entity != null) { String name = entity.getName(); if (name != null) { - return " for " + name; + return I18n.text(req, TEXT_BUNDLE, nameTitleKey, name); } } - return ""; + return I18n.text(req, TEXT_BUNDLE, noNameTitleKey); } /** * Holds an error message to use as a complaint to the user. */ static class UserMistakeException extends Exception { - UserMistakeException(String message) { + private final Object[] parameters; + + UserMistakeException(String message, Object... parameters) { super(message); + this.parameters = parameters; + } + + public String formatMessage(HttpServletRequest req) { + return I18n.text(req, getMessage(), parameters); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java index 656a0f0a7..e0052b7bd 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java @@ -49,6 +49,18 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServ public class ImageUploadHelper { private static final Log log = LogFactory.getLog(ImageUploadHelper.class); + /* + * Keys to text strings for error messages. + */ + private static final String ERROR_CODE_NO_IMAGE_TO_CROP = "imageUpload.errorNoImageForCropping"; + private static final String ERROR_CODE_IMAGE_TOO_SMALL = "imageUpload.errorImageTooSmall"; + private static final String ERROR_CODE_UNKNOWN = "imageUpload.errorUnknown"; + private static final String ERROR_CODE_FILE_TOO_BIG = "imageUpload.errorFileTooBig"; + private static final String ERROR_CODE_UNRECOGNIZED_FILE_TYPE = "imageUpload.errorUnrecognizedFileType"; + private static final String ERROR_CODE_NO_PHOTO_SELECTED = "imageUpload.errorNoPhotoSelected"; + private static final String ERROR_CODE_BAD_MULTIPART_REQUEST = "imageUpload.errorBadMultipartRequest"; + private static final String ERROR_CODE_FORM_FIELD_MISSING = "imageUpload.errorFormFieldMissing"; + /** * When they upload a new image, store it as this session attribute until * we're ready to attach it to the Individual. @@ -127,35 +139,31 @@ public class ImageUploadHelper { Object exception = request.getAttribute(FILE_UPLOAD_EXCEPTION); if (exception != null) { int limit = MAXIMUM_FILE_SIZE / (1024 * 1024); - throw new UserMistakeException( - "Please upload an image smaller than " + limit - + " megabytes"); + throw new UserMistakeException(ERROR_CODE_FILE_TOO_BIG, limit); } Map> map = (Map>) request .getAttribute(FILE_ITEM_MAP); if (map == null) { - throw new IllegalStateException("Failed to parse the " - + "multi-part request for uploading an image."); + throw new IllegalStateException(ERROR_CODE_BAD_MULTIPART_REQUEST); } List list = map.get(PARAMETER_UPLOADED_FILE); if ((list == null) || list.isEmpty()) { - throw new UserMistakeException("The form did not contain a '" - + PARAMETER_UPLOADED_FILE + "' field."); + throw new UserMistakeException(ERROR_CODE_FORM_FIELD_MISSING, + PARAMETER_UPLOADED_FILE); } FileItem file = list.get(0); if (file.getSize() == 0) { - throw new UserMistakeException("Please browse and select a photo."); + throw new UserMistakeException(ERROR_CODE_NO_PHOTO_SELECTED); } String filename = getSimpleFilename(file); String mimeType = getMimeType(file); if (!RECOGNIZED_FILE_TYPES.containsValue(mimeType)) { log.debug("Unrecognized MIME type: '" + mimeType + "'"); - throw new UserMistakeException("'" + filename - + "' is not a recognized image file type. " - + "Please upload JPEG, GIF, or PNG files only."); + throw new UserMistakeException(ERROR_CODE_UNRECOGNIZED_FILE_TYPE, + filename); } return file; @@ -221,10 +229,8 @@ public class ImageUploadHelper { if ((size.height < THUMBNAIL_HEIGHT) || (size.width < THUMBNAIL_WIDTH)) { - throw new UserMistakeException( - "The uploaded image should be at least " - + THUMBNAIL_HEIGHT + " pixels high and " - + THUMBNAIL_WIDTH + " pixels wide."); + throw new UserMistakeException(ERROR_CODE_IMAGE_TOO_SMALL, + THUMBNAIL_HEIGHT, THUMBNAIL_WIDTH); } return size; @@ -237,8 +243,7 @@ public class ImageUploadHelper { throw e; } catch (Exception e) { log.warn("Unexpected exception in image handling", e); - throw new UserMistakeException("Sorry, we were unable to process " - + "the photo you provided. Please try another photo."); + throw new UserMistakeException(ERROR_CODE_UNKNOWN); } finally { if (source != null) { try { @@ -261,8 +266,7 @@ public class ImageUploadHelper { ATTRIBUTE_TEMP_FILE); if (fileInfo == null) { - throw new UserMistakeException( - "There is no image file to be cropped."); + throw new UserMistakeException(ERROR_CODE_NO_IMAGE_TO_CROP); } return fileInfo; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualListController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualListController.java index 77f1cc601..54b295e6d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualListController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/IndividualListController.java @@ -182,8 +182,19 @@ public class IndividualListController extends FreemarkerHttpServlet { } return rvMap; } - + public static Map getRandomResultsForVClass(String vclassURI, int page, int pageSize, IndividualDao indDao, ServletContext context) { + Map rvMap = new HashMap(); + try{ + List classUris = Collections.singletonList(vclassURI); + IndividualListQueryResults results = SolrQueryUtils.buildAndExecuteRandomVClassQuery(classUris, page, pageSize, context, indDao); + rvMap = getResultsForVClassQuery(results, page, pageSize, ""); + } catch(Throwable th) { + log.error("An error occurred retrieving random results for vclass query", th); + } + return rvMap; + } + //TODO: Get rid of this method and utilize SolrQueryUtils - currently appears to be referenced //only within DataGetterUtils public static long getIndividualCount(List vclassUris, IndividualDao indDao, ServletContext context) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyGroupsController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyGroupsController.java index 1cc66879b..27c9b38b7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyGroupsController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ListPropertyGroupsController.java @@ -73,7 +73,7 @@ public class ListPropertyGroupsController extends FreemarkerHttpServlet { publicName = publicName.replace("\"","\\\""); publicName = publicName.replace("\'","\\\'"); try { - json += "{ \"name\": \"" + publicName + "\", "; + json += "{ \"name\": \"" + publicName + "\", "; } catch (Exception e) { json += "{ \"name\": \"" + publicName + "\", "; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/NavigationController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/NavigationController.java deleted file mode 100644 index 21b96f5eb..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/NavigationController.java +++ /dev/null @@ -1,216 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.controller.freemarker; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.ontology.Individual; -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.rdf.listeners.StatementListener; -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.NodeIterator; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.rdf.model.StmtIterator; - -import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; -import freemarker.template.Configuration; -import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.DISPLAY_ONT_MODEL; - -public class NavigationController extends FreemarkerHttpServlet { - private static final long serialVersionUID = 1L; - private static final Log log = LogFactory.getLog(NavigationController.class.getName()); - - //private Map urlPatternToURI; - private NavigationURLPatternListener urlPatterns; - - @Override - public void init(ServletConfig config) throws ServletException { - super.init(config); - OntModel displayOntModel = (OntModel)config.getServletContext().getAttribute(DISPLAY_ONT_MODEL); - this.urlPatterns = new NavigationURLPatternListener( ); - displayOntModel.getBaseModel().register( urlPatterns ); - } - - @Override - protected ResponseValues processRequest(VitroRequest vreq) { - OntModel displayOntModel = (OntModel)getServletContext().getAttribute(DISPLAY_ONT_MODEL); - OntModel jenaOntModel = (OntModel)getServletContext().getAttribute("jenaOntModel"); - - //figure out what is being requested - Individual ind = urlPatterns.getDisplayIndividual(vreq.getPathInfo(),displayOntModel); - Map values = getValues(ind, displayOntModel,jenaOntModel, getValuesFromRequest(/*?*/) ); - String template = getTemplate(ind, displayOntModel); - - return new TemplateResponseValues(template, values); - } - - private MapgetValuesFromRequest(){ - // TODO: figure out how to get request for FreeMarkerHttpServlet. - return Collections.emptyMap(); - } - - private String getTemplate(Individual ind, OntModel displayOntModel) { - if( ind == null ) return "defaultBody"; - - // check vitroDisplay:requiresBodyTemplate - displayOntModel.enterCriticalSection(Model.READ); - StmtIterator it = displayOntModel.listStatements(ind, DisplayVocabulary.REQUIRES_BODY_TEMPLATE, (RDFNode) null); - //NodeIterator it = ind.listPropertyValues(DisplayVocabulary.REQUIRES_BODY_TEMPLATE); - try{ - while(it.hasNext()){ - Statement stmt = it.nextStatement(); - if( stmt.getObject().isLiteral() ){ - String template = ((Literal)stmt.getObject().as(Literal.class)).getLexicalForm(); - if( template != null && template.length() > 0 ){ - return template; - } - } - } - }finally{ - it.close(); - displayOntModel.leaveCriticalSection(); - } - return "defaultBody"; - } - - Map getValues(Individual ind, OntModel displayOntModel, OntModel assertionModel, Map baseValues){ - if( ind == null ) return Collections.emptyMap(); - - /* Figure out what ValueFactories are specified in the display ontology for this individual. */ - Set valueFactories = new HashSet(); - displayOntModel.enterCriticalSection(Model.READ); - StmtIterator stmts = ind.listProperties(DisplayVocabulary.REQUIRES_VALUES); - try{ - while(stmts.hasNext()){ - Statement stmt = stmts.nextStatement(); - RDFNode obj = stmt.getObject(); - valueFactories.addAll(getValueFactory(obj,displayOntModel)); - } - }finally{ - stmts.close(); - displayOntModel.leaveCriticalSection(); - } - - /* Get values from the ValueFactories. */ - HashMap values = new HashMap(); - values.putAll(baseValues); - for(ValueFactory vf : valueFactories){ - values.putAll( vf.getValues(assertionModel, values)); - } - return values; - } - - protected Set getValueFactory( RDFNode valueNode, OntModel displayOntModel) { - //maybe use jenabean or owl2java for this? - if( valueNode.isResource() ){ - Resource res = (Resource)valueNode.as(Resource.class); - Statement stmt = res.getProperty(DisplayVocabulary.JAVA_CLASS_NAME); - if( stmt == null || !stmt.getObject().isLiteral() ){ - log.debug("Cannot build value factory: java class was " + stmt.getObject()); - return Collections.emptySet(); - } - String javaClassName = ((Literal)stmt.getObject().as(Literal.class)).getLexicalForm(); - if( javaClassName == null || javaClassName.length() == 0 ){ - log.debug("Cannot build value factory: no java class was set."); - return Collections.emptySet(); - } - Class clazz; - Object newObj; - try { - clazz = Class.forName(javaClassName); - } catch (ClassNotFoundException e) { - log.debug("Cannot build value factory: no class found for " + javaClassName); - return Collections.emptySet(); - } - try { - newObj = clazz.newInstance(); - } catch (Exception e) { - log.debug("Cannot build value factory: exception while creating object of java class " + javaClassName + " " + e.getMessage()); - return Collections.emptySet(); - } - if( newObj instanceof ValueFactory){ - ValueFactory valueFactory = (ValueFactory)newObj; - return Collections.singleton( valueFactory ); - }else{ - log.debug("Cannot build value factory: " + javaClassName + " does not implement " + ValueFactory.class.getName() ); - return Collections.emptySet(); - } - }else{ - log.debug("Cannot build value factory for " + valueNode); - return Collections.emptySet(); - } - } - - interface ValueFactory { - void configure( Map config); - Map getValues(OntModel model, Map values); - } - - private class NavigationURLPatternListener extends StatementListener { - private Map urlPatternToURI; - - public synchronized Map getUrlPatternToURIMap(){ - if( urlPatternToURI == null || urlPatternToURI.isEmpty() ){ - this.urlPatternToURI = buildUrlPatternToURI(); - } - return urlPatternToURI; - } - - protected synchronized void invalidateURLPatternMap(){ - this.urlPatternToURI = null; - } - - public Individual getDisplayIndividual( String pathInfo , OntModel displayModel){ - Map map = getUrlPatternToURIMap(); - for( Pattern regex : map.keySet()){ - Matcher m = regex.matcher(pathInfo); - if(m.matches() ){ - return displayModel.getIndividual(map.get(regex)); - } - } - return null; - } - - protected synchronized Map buildUrlPatternToURI(){ - OntModel displayModel = (OntModel)getServletContext().getAttribute("displayOntModel"); - Map map = new HashMap(); - StmtIterator stmts = displayModel.listStatements(null, DisplayVocabulary.URL_MAPPING,(Literal)null); - while(stmts.hasNext()){ - Statement stmt = stmts.nextStatement(); - if( stmt.getSubject().isURIResource() && stmt.getObject().isLiteral()){ - Resource r = (Resource)stmt.getSubject().as( Resource.class); - Pattern regex = Pattern.compile(stmt.getLiteral().getLexicalForm()); - map.put(regex,r.getURI()); - } - } - return map; - } - - @Override - public void addedStatement(Statement s) { - invalidateURLPatternMap(); - } - @Override - public void removedStatement(Statement s) { - invalidateURLPatternMap(); - } - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java index f43113d8a..80994386c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/UrlBuilder.java @@ -303,7 +303,7 @@ public class UrlBuilder { } public static String urlEncode(String str) { - String encoding = "ISO-8859-1"; + String encoding = "UTF-8"; String encodedUrl = null; try { encodedUrl = URLEncoder.encode(str, encoding); @@ -314,7 +314,7 @@ public class UrlBuilder { } public static String urlDecode(String str) { - String encoding = "ISO-8859-1"; + String encoding = "UTF-8"; String decodedUrl = null; try { decodedUrl = URLDecoder.decode(str, encoding); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualResponseBuilder.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualResponseBuilder.java index ac39c3b10..e63791df5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualResponseBuilder.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/individual/IndividualResponseBuilder.java @@ -180,7 +180,7 @@ class IndividualResponseBuilder { private boolean getprofilePageTypesFlag() { String property = ConfigurationProperties.getBean(vreq).getProperty( - "MultiViews.profilePageTypes"); + "multiViews.profilePageTypes"); return "enabled".equals(property); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaAdminActions.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaAdminActions.java index 90d2398b1..3038521c6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaAdminActions.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaAdminActions.java @@ -18,12 +18,10 @@ import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.iri.IRI; import com.hp.hpl.jena.iri.IRIFactory; -import com.hp.hpl.jena.iri.Violation; import com.hp.hpl.jena.ontology.AllValuesFromRestriction; import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.ontology.OntResource; import com.hp.hpl.jena.ontology.Restriction; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; @@ -35,11 +33,9 @@ import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.shared.Lock; -import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDFS; @@ -47,6 +43,7 @@ import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vedit.controller.BaseEditController; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; public class JenaAdminActions extends BaseEditController { @@ -59,7 +56,7 @@ public class JenaAdminActions extends BaseEditController { if (iri.hasViolation(false) ) { log.error("Bad URI: "+uri); log.error( "Only well-formed absolute URIrefs can be included in RDF/XML output: " - + ((Violation)iri.violations(false).next()).getShortMessage()); + + iri.violations(false).next().getShortMessage()); return true; } else { return false; @@ -71,8 +68,7 @@ public class JenaAdminActions extends BaseEditController { private static final String AKT_PORTAL = "http://www.aktors.org/ontology/portal#"; private void copyStatements(Model src, Model dest, Resource subj, Property pred, RDFNode obj) { - for (Iterator i = src.listStatements(subj,pred,obj); i.hasNext();) { - Statement stmt = (Statement) i.next(); + for (Statement stmt : src.listStatements(subj,pred,obj).toList()) { String subjNs = stmt.getSubject().getNameSpace(); if (subjNs == null || (! (subjNs.equals(VITRO) || subjNs.equals(AKT_SUPPORT) || subjNs.equals(AKT_PORTAL) ) ) ) { if (stmt.getObject().isLiteral()) { @@ -90,14 +86,11 @@ public class JenaAdminActions extends BaseEditController { /** * This doesn't really print just the TBox. It takes a copy of the model, removes all the individuals, and writes the result. - * @param response */ private void outputTbox(HttpServletResponse response) { - OntModel memoryModel = (OntModel) getServletContext().getAttribute("baseOntModel"); + OntModel memoryModel = ModelAccess.on(getServletContext()).getBaseOntModel(); try { OntModel tempOntModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM); - Property DescriptionProp = ResourceFactory.createProperty(VitroVocabulary.DESCRIPTION_ANNOT); - Property ExampleProp = ResourceFactory.createProperty(VitroVocabulary.EXAMPLE_ANNOT); memoryModel.enterCriticalSection(Lock.READ); try { copyStatements(memoryModel,tempOntModel,null,RDF.type,OWL.Class); @@ -109,8 +102,6 @@ public class JenaAdminActions extends BaseEditController { copyStatements(memoryModel,tempOntModel,null,RDFS.domain,null); copyStatements(memoryModel,tempOntModel,null,RDFS.range,null); copyStatements(memoryModel,tempOntModel,null,OWL.inverseOf,null); - //copyStatements(memoryModel,tempOntModel,null,DescriptionProp,null); - //copyStatements(memoryModel,tempOntModel,null,ExampleProp,null); } finally { memoryModel.leaveCriticalSection(); } @@ -130,28 +121,24 @@ public class JenaAdminActions extends BaseEditController { Model taxonomyModel = ModelFactory.createDefaultModel(); try { HashSet typeSet = new HashSet(); - for (Iterator classIt = ontModel.listStatements((Resource)null,RDF.type,(RDFNode)null); classIt.hasNext();) { - Statement stmt = (Statement) classIt.next(); + for (Statement stmt : ontModel.listStatements((Resource)null,RDF.type,(RDFNode)null).toList()) { if (stmt.getObject().isResource()) { - Resource ontClass = (Resource) stmt.getObject(); - typeSet.add(ontClass); + typeSet.add((Resource) stmt.getObject()); } } - for (Iterator classIt = ontModel.listClasses(); classIt.hasNext();) { - Resource classRes = (Resource) classIt.next(); + for (Resource classRes : ontModel.listClasses().toList()) { typeSet.add(classRes); } - for (Iterator typeIt = typeSet.iterator(); typeIt.hasNext();) { - Resource ontClass = typeIt.next(); - if (!ontClass.isAnon()) { // Only query for named classes - System.out.println("Describing "+ontClass.getURI()); - // We want a subgraph describing this class, including related BNodes - String queryStr = "DESCRIBE <"+ontClass.getURI()+">"; - Query describeQuery = QueryFactory.create(queryStr); - QueryExecution qe = QueryExecutionFactory.create(describeQuery,ontModel); - qe.execDescribe(taxonomyModel); - } + for (Resource ontClass : typeSet) { + if (!ontClass.isAnon()) { // Only query for named classes + System.out.println("Describing "+ontClass.getURI()); + // We want a subgraph describing this class, including related BNodes + String queryStr = "DESCRIBE <"+ontClass.getURI()+">"; + Query describeQuery = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.create(describeQuery,ontModel); + qe.execDescribe(taxonomyModel); } + } } finally { ontModel.leaveCriticalSection(); } @@ -171,10 +158,10 @@ public class JenaAdminActions extends BaseEditController { private String testWriteXML() { StringBuffer output = new StringBuffer(); output.append("Test Write XML
\n");
-		Model model = (Model) getServletContext().getAttribute("jenaOntModel");
+		OntModel model = ModelAccess.on(getServletContext()).getJenaOntModel();
 		Model tmp = ModelFactory.createDefaultModel();
 		boolean valid = true;
-		for (Statement stmt : ((List)model.listStatements().toList()) ) {
+		for (Statement stmt : model.listStatements().toList() ) {
 			tmp.add(stmt);
 				StringWriter writer = new StringWriter();
 				try {
@@ -201,17 +188,15 @@ public class JenaAdminActions extends BaseEditController {
 
     private void printRestrictions() {
     	OntModel memoryModel = (OntModel) getServletContext().getAttribute("pelletOntModel");
-    	for (Iterator i = memoryModel.listRestrictions(); i.hasNext(); ) {
-    		Restriction rest = (Restriction) i.next();
+    	for (Restriction rest : memoryModel.listRestrictions().toList() ) {
     		//System.out.println();
     		if (rest.isAllValuesFromRestriction()) {
     			log.trace("All values from: ");
     			AllValuesFromRestriction avfr = rest.asAllValuesFromRestriction();
     			Resource res = avfr.getAllValuesFrom();
     			if (res.canAs(OntClass.class)) {
-    				OntClass resClass = (OntClass) res.as(OntClass.class);
-    				for (Iterator resInstIt = resClass.listInstances(); resInstIt.hasNext(); ) {
-    					Resource inst = (Resource) resInstIt.next();
+    				OntClass resClass = res.as(OntClass.class);
+    				for (Resource inst : resClass.listInstances().toList() ) {
     					log.trace("    -"+inst.getURI());
     				}
     			}
@@ -221,8 +206,7 @@ public class JenaAdminActions extends BaseEditController {
     			log.trace("Has value: ");
     		}
     		log.trace("On property "+rest.getOnProperty().getURI());
-    		for (Iterator indIt = rest.listInstances(); indIt.hasNext(); ) {
-    			Resource inst = (Resource) indIt.next();
+    		for (Resource inst : rest.listInstances().toList() ) {
     			log.trace("     "+inst.getURI());
     		}
     		
@@ -230,12 +214,11 @@ public class JenaAdminActions extends BaseEditController {
     }
     
     private void removeLongLiterals() {
-    	OntModel memoryModel = (OntModel) getServletContext().getAttribute("jenaOntModel");
+		OntModel memoryModel = ModelAccess.on(getServletContext()).getJenaOntModel();
     	memoryModel.enterCriticalSection(Lock.WRITE);
     	try {
     		List statementsToRemove = new LinkedList();
-    		for (Iterator i = memoryModel.listStatements(null,null,(Literal)null); i.hasNext(); ) {
-    			Statement stmt = (Statement) i.next();
+    		for (Statement stmt :  memoryModel.listStatements(null,null,(Literal)null).toList() ) {
     			if (stmt.getObject().isLiteral()) {
     				Literal lit = (Literal) stmt.getObject();
     				if ( lit.getString().length() > 24) {
@@ -252,7 +235,8 @@ public class JenaAdminActions extends BaseEditController {
     	}
     }
     
-    public void doGet(HttpServletRequest req, HttpServletResponse response) {
+    @Override
+	public void doGet(HttpServletRequest req, HttpServletResponse response) {
         if (!isAuthorizedToDisplayPage(req, response, SimplePermission.USE_MISCELLANEOUS_ADMIN_PAGES.ACTIONS)) {
         	return;
         }
@@ -273,17 +257,16 @@ public class JenaAdminActions extends BaseEditController {
 		}
         
         if (actionStr.equals("checkURIs")) { 
-        	OntModel memoryModel = (OntModel) getServletContext().getAttribute("jenaOntModel");
-        	ClosableIterator stmtIt = memoryModel.listStatements();
+    		OntModel memoryModel = ModelAccess.on(getServletContext()).getJenaOntModel();
+        	StmtIterator stmtIt = memoryModel.listStatements();
         	try {
-	        	for (Iterator i = stmtIt; i.hasNext(); ) {
+        		for (Statement stmt : stmtIt.toList() ) {
 	        		boolean sFailed = false;
 	        		boolean pFailed = false;
 	        		boolean oFailed = false;
 	        		String sURI = "";
 	        		String pURI = "???";
 	        		String oURI = "";
-	        		Statement stmt = (Statement) i.next();
 	        		if (stmt.getSubject().getURI() != null) {
 	        			sFailed = checkURI(sURI = stmt.getSubject().getURI());
 	        		}
@@ -305,23 +288,19 @@ public class JenaAdminActions extends BaseEditController {
         if (actionStr.equals("output")) {
             OntModel memoryModel = null;
 	    if (request.getParameter("assertionsOnly") != null) {
-	    	memoryModel = (OntModel) getServletContext().getAttribute("baseOntModel");
+	        memoryModel = ModelAccess.on(getServletContext()).getBaseOntModel();
 	    	System.out.println("baseOntModel");
 	    } else if (request.getParameter("inferences") != null) {
-	    	memoryModel = (OntModel) getServletContext().getAttribute("inferenceOntModel");
+	    	memoryModel = ModelAccess.on(getServletContext()).getInferenceOntModel();
 	    	System.out.println("inferenceOntModel");
 	    } else if (request.getParameter("pellet") != null) {
 	    	memoryModel = (OntModel) getServletContext().getAttribute("pelletOntModel");
 	    	System.out.println("pelletOntModel");
 	    } else {
-	    	memoryModel = (OntModel) getServletContext().getAttribute("jenaOntModel");
+			memoryModel = ModelAccess.on(getServletContext()).getJenaOntModel();
 	    	System.out.println("jenaOntModel");
 	    }  
-	    int subModelCount = 0;
-	    for (Iterator subIt = memoryModel.listSubModels(); subIt.hasNext();) {
-	    	subIt.next();
-	    	++subModelCount;
-	    }
+	    int subModelCount = memoryModel.listSubModels().toList().size();
 	    System.out.println("Submodels: "+subModelCount);
 	        try {
 	            //response.setContentType("application/rdf+xml");
@@ -339,42 +318,8 @@ public class JenaAdminActions extends BaseEditController {
         	removeLongLiterals();
         }
         
-        if (actionStr.equals("isIsomorphic")) {
-            OntModel memoryModel = (OntModel) getServletContext().getAttribute("jenaOntModel");
-            OntModel persistentModel = (OntModel) getServletContext().getAttribute("jenaPersistentOntModel");
-            if ((memoryModel != null) && (persistentModel != null)) {
-                long startTime = System.currentTimeMillis();
-                if (memoryModel.isIsomorphicWith(persistentModel)) {
-                    log.trace("In-memory and persistent models are isomorphic");
-                } else {
-                    log.trace("In-memory and persistent models are NOT isomorphic");
-                    log.trace("In-memory model has "+memoryModel.size()+" statements");
-                    log.trace("Persistent model has "+persistentModel.size()+" statements");
-                    Model diff = memoryModel.difference(persistentModel);
-                    ClosableIterator stmtIt = diff.listStatements();
-                    log.trace("Delta = "+diff.size()+" statments");
-                    while (stmtIt.hasNext()) {
-                        Statement s = (Statement) stmtIt.next();
-                        try {
-                            log.trace(s.getSubject().getURI()+" : "+s.getPredicate().getURI()); // + ((Literal)s.getObject()).getString());
-                        } catch (ClassCastException cce) {}
-                    }
-                }
-                log.trace((System.currentTimeMillis()-startTime)/1000+" seconds to check isomorphism");
-            }
-        } else if (actionStr.equals("removeUntypedResources")) {
-            OntModel memoryModel = (OntModel) getServletContext().getAttribute("jenaOntModel");
-            OntModel persistentModel = (OntModel) getServletContext().getAttribute("jenaPersistentOntModel");
-            ClosableIterator rIt = memoryModel.listSubjects();
-            clean(rIt,memoryModel);
-            ClosableIterator oIt = memoryModel.listObjects();
-            clean(oIt,memoryModel);
-            ClosableIterator rrIt = persistentModel.listSubjects();
-            clean(rIt,persistentModel);
-            ClosableIterator ooIt = persistentModel.listObjects();
-            clean(oIt,persistentModel);
-        } else if (actionStr.equals("outputTaxonomy")) {
-        	OntModel ontModel = (OntModel) getServletContext().getAttribute("baseOntModel");
+        if (actionStr.equals("outputTaxonomy")) {
+            OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel();
         	Model taxonomyModel = extractTaxonomy(ontModel);
         	try {
         		taxonomyModel.write(response.getOutputStream());
@@ -385,32 +330,8 @@ public class JenaAdminActions extends BaseEditController {
     }
 
 
-    private void clean(ClosableIterator rIt, OntModel model) {
-        try {
-            while (rIt.hasNext()) {
-                try {
-                    OntResource r = (OntResource) rIt.next();
-                    try {
-                        Resource t = r.getRDFType();
-                        if (t == null) {
-                            r.remove();
-                        }
-                    } catch (Exception e) {
-                        r.remove();
-                    }
-                } catch (ClassCastException cce) {
-                    Resource r = (Resource) rIt.next();
-                    model.removeAll(r,null,null);
-                    model.removeAll(null,null,r);
-                }
-            }
-        } finally {
-            rIt.close();
-        }
-    }
-
-
-    public void doPost(HttpServletRequest request, HttpServletResponse response) {
+    @Override
+	public void doPost(HttpServletRequest request, HttpServletResponse response) {
         doGet(request ,response);
     }
 
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaExportController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaExportController.java
index ab666c61f..b034ea5d9 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaExportController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaExportController.java
@@ -5,8 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.jena;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -30,8 +28,9 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
 import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
 import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
 import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
+import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
+import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaModelUtils;
-import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
@@ -121,8 +120,7 @@ public class JenaExportController extends BaseEditController {
 		if( "abox".equals(subgraphParam)){
 			model = ModelFactory.createDefaultModel();
 			if("inferred".equals(assertedOrInferredParam)){
-				model = ModelContext.getInferenceOntModelSelector(
-						getServletContext()).getABoxModel();
+				model = ModelAccess.on(getServletContext()).getOntModel(ModelID.INFERRED_ABOX);
 			}
 			else if("full".equals(assertedOrInferredParam)){
 			    outputSparqlConstruct(ABOX_FULL_CONSTRUCT, formatParam, response);
@@ -137,10 +135,9 @@ public class JenaExportController extends BaseEditController {
 		        // so we'll extract the whole ontology and then include
 		        // only those statements that are in the inferred graph
 		        Model tempModel = xutil.extractTBox(
-		                ModelContext.getUnionOntModelSelector(
-		                        getServletContext()).getTBoxModel(), ontologyURI);
-		        Model inferenceModel = ModelContext.getInferenceOntModelSelector(
-                        getServletContext()).getTBoxModel();
+		        		ModelAccess.on(getServletContext()).getOntModel(ModelID.UNION_TBOX),
+		                ontologyURI);
+		        Model inferenceModel = ModelAccess.on(getServletContext()).getOntModel(ModelID.INFERRED_TBOX);
 		        inferenceModel.enterCriticalSection(Lock.READ);
 		        try {
     		        model = tempModel.intersection(inferenceModel);
@@ -149,12 +146,11 @@ public class JenaExportController extends BaseEditController {
 		        }
 		    } else if ("full".equals(assertedOrInferredParam)) {
                 model = xutil.extractTBox(
-                        ModelContext.getUnionOntModelSelector(
-                                getServletContext()).getTBoxModel(), ontologyURI);		        
+                		ModelAccess.on(getServletContext()).getOntModel(ModelID.UNION_TBOX),
+                        ontologyURI);		        
 		    } else {
                 model = xutil.extractTBox(
-                        ModelContext.getBaseOntModelSelector(
-                                getServletContext()).getTBoxModel(), ontologyURI);              		        
+                        ModelAccess.on(getServletContext()).getOntModel(ModelID.BASE_TBOX), ontologyURI);              		        
 		    }
 			
 		}
@@ -162,10 +158,8 @@ public class JenaExportController extends BaseEditController {
 			if("inferred".equals(assertedOrInferredParam)){
 				ontModel = xutil.extractTBox(
 						dataset, ontologyURI, INFERENCE_GRAPH);
-				ontModel.addSubModel(ModelContext.getInferenceOntModelSelector(
-						getServletContext()).getABoxModel());
-				ontModel.addSubModel(ModelContext.getInferenceOntModelSelector(
-						getServletContext()).getTBoxModel());
+				ontModel.addSubModel(ModelAccess.on(getServletContext()).getOntModel(ModelID.INFERRED_ABOX));
+				ontModel.addSubModel(ModelAccess.on(getServletContext()).getOntModel(ModelID.INFERRED_TBOX));
 			}
 			else if("full".equals(assertedOrInferredParam)){
 			    outputSparqlConstruct(FULL_FULL_CONSTRUCT, formatParam, response);
@@ -283,9 +277,6 @@ public class JenaExportController extends BaseEditController {
 		}
 	}
 	
-	static final String FULL_ONT_MODEL_ATTR = "jenaOntModel";
-	static final String ASSERTIONS_ONT_MODEL_ATTR = "baseOntModel";
-	static final String INFERENCES_ONT_MODEL_ATTR = "inferenceOntModel";
 	static final String FULL_GRAPH = "?g";
 	static final String ASSERTIONS_GRAPH = "";
 	static final String INFERENCE_GRAPH = "";
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java
index 6d1b2c346..2fe7d3e6f 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/JenaIngestController.java
@@ -67,8 +67,9 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
 import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
 import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
 import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
+import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
+import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID;
 import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
-import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaModelMaker;
@@ -79,8 +80,8 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
 import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
+import edu.cornell.mannlib.vitro.webapp.servlet.setup.ContentModelSetup;
 import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
-import edu.cornell.mannlib.vitro.webapp.servlet.setup.WebappDaoSetup;
 import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
 import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils;
 import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils.MergeResult;
@@ -520,7 +521,7 @@ public class JenaIngestController extends BaseEditController {
             vreq.setAttribute("title", "Choose Workflow Step");
             vreq.setAttribute("bodyJsp", WORKFLOW_STEP_JSP);
         } else {
-            OntModel jenaOntModel = (OntModel) getServletContext().getAttribute("jenaOntModel");
+    		OntModel jenaOntModel = ModelAccess.on(getServletContext()).getJenaOntModel();
             jenaOntModel.enterCriticalSection(Lock.READ);
             List savedQueryList = new LinkedList();
             try {
@@ -537,7 +538,7 @@ public class JenaIngestController extends BaseEditController {
     
     private void processExecuteSparqlRequest(VitroRequest vreq, ModelMaker maker, String modelType) {
         String sparqlQueryStr = vreq.getParameter("sparqlQueryStr");
-        OntModel jenaOntModel = (OntModel) getServletContext().getAttribute("jenaOntModel");
+		OntModel jenaOntModel = ModelAccess.on(getServletContext()).getJenaOntModel();
         jenaOntModel.enterCriticalSection(Lock.READ);
         List savedQueryList = new LinkedList();
         try {
@@ -660,10 +661,8 @@ public class JenaIngestController extends BaseEditController {
               /*
                * get baseOnt and infOnt models
                */
-              OntModel baseOntModel = ModelContext.getBaseOntModel(
-                      getServletContext());
-              OntModel tboxOntModel = ModelContext.getUnionOntModelSelector(
-                      getServletContext()).getTBoxModel();
+              OntModel baseOntModel = ModelAccess.on(getServletContext()).getBaseOntModel();
+              OntModel tboxOntModel = ModelAccess.on(getServletContext()).getOntModel(ModelID.UNION_TBOX);
               
               /*
                * calling method that does the merge operation.
@@ -826,10 +825,10 @@ public class JenaIngestController extends BaseEditController {
             return;
         }
         Model m = modelMaker.getModel(modelName);
-        ModelContext.getBaseOntModelSelector(getServletContext()).getTBoxModel().addSubModel(m);
-        ModelContext.getBaseOntModelSelector(getServletContext()).getABoxModel().addSubModel(m);
-        ModelContext.getUnionOntModelSelector(getServletContext()).getABoxModel().addSubModel(m);
-        ModelContext.getUnionOntModelSelector(getServletContext()).getTBoxModel().addSubModel(m);
+        ModelAccess.on(getServletContext()).getOntModel(ModelID.BASE_ABOX).addSubModel(m);
+        ModelAccess.on(getServletContext()).getOntModel(ModelID.BASE_TBOX).addSubModel(m);
+        ModelAccess.on(getServletContext()).getOntModel(ModelID.UNION_ABOX).addSubModel(m);
+        ModelAccess.on(getServletContext()).getOntModel(ModelID.UNION_TBOX).addSubModel(m);
         attachedModels.put(modelName, m);
         log.info("Attached " + modelName + " (" + m.hashCode() + ") to webapp");
     }
@@ -839,10 +838,10 @@ public class JenaIngestController extends BaseEditController {
         if (m == null) {
             return;
         }
-        ModelContext.getBaseOntModelSelector(getServletContext()).getTBoxModel().removeSubModel(m);
-        ModelContext.getBaseOntModelSelector(getServletContext()).getABoxModel().removeSubModel(m);
-        ModelContext.getUnionOntModelSelector(getServletContext()).getABoxModel().removeSubModel(m);
-        ModelContext.getUnionOntModelSelector(getServletContext()).getTBoxModel().removeSubModel(m);
+        ModelAccess.on(getServletContext()).getOntModel(ModelID.BASE_ABOX).removeSubModel(m);
+        ModelAccess.on(getServletContext()).getOntModel(ModelID.BASE_TBOX).removeSubModel(m);
+        ModelAccess.on(getServletContext()).getOntModel(ModelID.UNION_ABOX).removeSubModel(m);
+        ModelAccess.on(getServletContext()).getOntModel(ModelID.UNION_TBOX).removeSubModel(m);
         attachedModels.remove(modelName);
         log.info("Detached " + modelName + " (" + m.hashCode() + ") from webapp");
     }
@@ -910,7 +909,7 @@ public class JenaIngestController extends BaseEditController {
     }
     
     private long doExecuteSparql(VitroRequest vreq) {
-        OntModel jenaOntModel = (OntModel) getServletContext().getAttribute("jenaOntModel");
+		OntModel jenaOntModel = ModelAccess.on(getServletContext()).getJenaOntModel();
         OntModel source = null;
         if ("pellet".equals(vreq.getParameter("reasoning"))) {
             source = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);
@@ -984,7 +983,7 @@ public class JenaIngestController extends BaseEditController {
         log.debug("Connecting to DB at "+jdbcUrl);
         StoreDesc storeDesc = new StoreDesc(LayoutType.LayoutTripleNodesHash,dbTypeObj) ; 
         ServletContext ctx = vreq.getSession().getServletContext();
-        DataSource bds = WebappDaoSetup.makeBasicDataSource(
+        DataSource bds = ContentModelSetup.makeBasicDataSource(
                 driver, jdbcUrl, username, password, ctx);
         try {
             VitroJenaSDBModelMaker vsmm = new VitroJenaSDBModelMaker(storeDesc, bds);
@@ -1193,8 +1192,7 @@ public class JenaIngestController extends BaseEditController {
             Model baseOntModel = RDFServiceGraph.createRDFServiceModel
                     (new RDFServiceGraph(
                             rdfService, JenaDataSourceSetupBase.JENA_DB_MODEL));
-            OntModel ontModel = (OntModel)
-            getServletContext().getAttribute("jenaOntModel");
+    		OntModel ontModel = ModelAccess.on(getServletContext()).getJenaOntModel();
             List urisToChange = new LinkedList();        
             ontModel.enterCriticalSection(Lock.READ);
             try {
@@ -1312,26 +1310,11 @@ public class JenaIngestController extends BaseEditController {
 
     public static Model getModel(String name, HttpServletRequest request, ServletContext context) {
         if ("vitro:jenaOntModel".equals(name)) {
-            Object sessionOntModel = request.getSession().getAttribute("jenaOntModel");
-            if (sessionOntModel != null && sessionOntModel instanceof OntModel) {
-                return (OntModel) sessionOntModel;
-            } else {
-                return (OntModel) context.getAttribute("jenaOntModel");
-            }
+            return ModelAccess.on(request.getSession()).getJenaOntModel();
         } else if ("vitro:baseOntModel".equals(name)) {
-            Object sessionOntModel = request.getSession().getAttribute("baseOntModel");
-            if (sessionOntModel != null && sessionOntModel instanceof OntModel) {
-                return (OntModel) sessionOntModel;
-            } else {
-                return (OntModel) context.getAttribute("baseOntModel");
-            }
+            return ModelAccess.on(request.getSession()).getBaseOntModel();
         } else if ("vitro:inferenceOntModel".equals(name)) {
-            Object sessionOntModel = request.getSession().getAttribute("inferenceOntModel");
-            if (sessionOntModel != null && sessionOntModel instanceof OntModel) {
-                return (OntModel) sessionOntModel;
-            } else {
-                return (OntModel) context.getAttribute("inferenceOntModel");
-            }
+        	return ModelAccess.on(request.getSession()).getInferenceOntModel();
         } else {
             return getVitroJenaModelMaker(request,context).getModel(name);
         }
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java
index ab7052233..7d7fd8459 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/jena/RDFUploadController.java
@@ -34,9 +34,10 @@ import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
 import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
 import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
 import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
+import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
+import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID;
 import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaModelUtils;
-import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent;
@@ -170,14 +171,12 @@ public class RDFUploadController extends JenaIngestController {
 
             JenaModelUtils xutil = new JenaModelUtils();
             
-            OntModel tboxModel = getTBoxModel(
-                    request.getSession(), getServletContext());
+            OntModel tboxModel = getTBoxModel(request.getSession());
             OntModel aboxModel = getABoxModel(
                     request.getSession(), getServletContext());
             OntModel tboxChangeModel = null;
             Model aboxChangeModel = null;
-            OntModelSelector ontModelSelector = ModelContext.getOntModelSelector(
-                    getServletContext());
+            OntModelSelector ontModelSelector = ModelAccess.on(getServletContext()).getOntModelSelector();
             
             if (tboxModel != null) {
                 boolean AGGRESSIVE = true;
@@ -428,17 +427,8 @@ public class RDFUploadController extends JenaIngestController {
          return ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, abox);
      }    
 
-     private OntModel getTBoxModel(HttpSession session, ServletContext ctx) {   
-         if (session != null 
-                 && session.getAttribute("baseOntModelSelector")
-                         instanceof OntModelSelector) {
-             return ((OntModelSelector) 
-                     session.getAttribute("baseOntModelSelector"))
-                     .getTBoxModel();   
-         } else {
-             return ((OntModelSelector) 
-                     ctx.getAttribute("baseOntModelSelector")).getTBoxModel();
-         }
+     private OntModel getTBoxModel(HttpSession session) { 
+    	 return ModelAccess.on(session).getOntModel(ModelID.BASE_TBOX);
      }    
      
     private static final Log log = LogFactory.getLog(
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetRandomSolrIndividualsByVClass.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetRandomSolrIndividualsByVClass.java
new file mode 100644
index 000000000..5e4c268dd
--- /dev/null
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetRandomSolrIndividualsByVClass.java
@@ -0,0 +1,84 @@
+/* $This file is distributed under the terms of the license in /doc/license.txt$ */
+
+package edu.cornell.mannlib.vitro.webapp.controller.json;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import edu.cornell.mannlib.vitro.webapp.beans.Individual;
+import edu.cornell.mannlib.vitro.webapp.beans.VClass;
+import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
+import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
+import edu.cornell.mannlib.vitro.webapp.services.shortview.ShortViewService;
+import edu.cornell.mannlib.vitro.webapp.services.shortview.ShortViewService.ShortViewContext;
+import edu.cornell.mannlib.vitro.webapp.services.shortview.ShortViewServiceSetup;
+import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.IndividualTemplateModel;
+
+/**
+ * Does a Solr search for individuals, and uses the short view to render each of
+ * the results.
+ */
+public class GetRandomSolrIndividualsByVClass extends GetSolrIndividualsByVClass {
+	private static final Log log = LogFactory
+			.getLog(GetRandomSolrIndividualsByVClass.class);
+
+	protected GetRandomSolrIndividualsByVClass(VitroRequest vreq) {
+		super(vreq);
+	}
+
+	/**
+	 * Search for individuals by VClass. 
+	 */
+	@Override
+	protected JSONObject process() throws Exception {
+		JSONObject rObj = null;
+		
+		//This gets the first vclass value and sets that as display type.
+		List vclassIds = super.getVclassIds(vreq);
+		String vclassId = vclassIds.get(0);
+		vreq.setAttribute("queryType", "random");
+//		vreq.setAttribute("displayType", vclassId);
+		
+		//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;
+	}
+	
+	/**
+	 * Look through the return object. For each individual, render the short
+	 * view and insert the resulting HTML into the object.
+	 */
+	private void addShortViewRenderings(JSONObject rObj) throws JSONException {
+		JSONArray individuals = rObj.getJSONArray("individuals");
+		String vclassName = rObj.getJSONObject("vclass").getString("name");
+		for (int i = 0; i < individuals.length(); i++) {
+			JSONObject individual = individuals.getJSONObject(i);
+			individual.put("shortViewHtml",
+					renderShortView(individual.getString("URI"), vclassName));
+		}
+	}
+
+	private String renderShortView(String individualUri, String vclassName) {
+		IndividualDao iDao = vreq.getWebappDaoFactory().getIndividualDao();
+		Individual individual = iDao.getIndividualByURI(individualUri);
+
+		Map modelMap = new HashMap();
+		modelMap.put("individual",
+				new IndividualTemplateModel(individual, vreq));
+		modelMap.put("vclass", vclassName);
+
+		ShortViewService svs = ShortViewServiceSetup.getService(ctx);
+		return svs.renderShortView(individual, ShortViewContext.BROWSE,
+				modelMap, vreq);
+	}
+}
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetSolrIndividualsByVClass.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetSolrIndividualsByVClass.java
index 154753322..0d40e6026 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetSolrIndividualsByVClass.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetSolrIndividualsByVClass.java
@@ -24,6 +24,7 @@ public class GetSolrIndividualsByVClass extends JsonObjectProducer {
 	protected JSONObject process() throws Exception {
         VClass vclass=null;
         
+        String queryType = (String) vreq.getAttribute("queryType");
         String vitroClassIdStr = vreq.getParameter("vclassId");            
         if ( vitroClassIdStr != null && !vitroClassIdStr.isEmpty()){                             
             vclass = vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(vitroClassIdStr);
@@ -35,8 +36,13 @@ public class GetSolrIndividualsByVClass extends JsonObjectProducer {
             log.debug("parameter vclassId URI parameter expected ");
             throw new Exception("parameter vclassId URI parameter expected ");
         }
+        
         vreq.setAttribute("displayType", vitroClassIdStr);
-        return JsonServlet.getSolrIndividualsByVClass(vclass.getURI(), vreq, ctx);
+        if ( queryType != null && queryType.equals("random")){
+            return JsonServlet.getRandomSolrIndividualsByVClass(vclass.getURI(), vreq, ctx);             
+        } else {
+            return JsonServlet.getSolrIndividualsByVClass(vclass.getURI(), vreq, ctx);
+        }
     }
 
 }
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetVClassesForVClassGroup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetVClassesForVClassGroup.java
index 62502fbb7..1031ac56a 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetVClassesForVClassGroup.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/GetVClassesForVClassGroup.java
@@ -11,6 +11,7 @@ import org.json.JSONObject;
 import edu.cornell.mannlib.vitro.webapp.beans.VClass;
 import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
 import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
+import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest;
 import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache;
 
 /**
@@ -32,7 +33,7 @@ public class GetVClassesForVClassGroup extends JsonObjectProducer {
             throw new Exception("no URI passed for classgroupUri");
         }
         
-        VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(ctx);
+        VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq);
         VClassGroup vcg = vcgc.getGroup(vcgUri);
         if( vcg == null ){
             throw new Exception("Could not find vclassgroup: " + vcgUri);
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServlet.java
index be3c2eb01..2fbd9d09f 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServlet.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServlet.java
@@ -72,7 +72,10 @@ public class JsonServlet extends VitroHttpServlet {
             new GetDataForPage(vreq).process(resp);
         }else if( vreq.getParameter("getRenderedSolrIndividualsByVClass") != null ){
             new GetRenderedSolrIndividualsByVClass(vreq).process(resp);
+        }else if( vreq.getParameter("getRandomSolrIndividualsByVClass") != null ){
+            new GetRandomSolrIndividualsByVClass(vreq).process(resp);
         }
+        
     }
     
 
@@ -135,7 +138,35 @@ public class JsonServlet extends VitroHttpServlet {
             return value;            
     }
     
+    public static JSONObject getRandomSolrIndividualsByVClass(String vclassURI, HttpServletRequest req, ServletContext context) throws Exception {
+        VitroRequest vreq = new VitroRequest(req);        
+        
+        Map map = getRandomSolrVClassResults(vclassURI, vreq, context);
+        //last parameter indicates single vclass instead of multiple vclasses
+        return processVClassResults(map, vreq, context, false);                    
+    }
 
+     //Including version for Random Solr query for Vclass Intersections
+     private static Map getRandomSolrVClassResults(String vclassURI, VitroRequest vreq, ServletContext context){
+         log.debug("Retrieving random Solr intersection results for " + vclassURI);
+
+         int page = IndividualListController.getPageParameter(vreq);
+         int pageSize = Integer.parseInt(vreq.getParameter("pageSize"));
+         log.debug("page and pageSize parameters = " + page + " and " + pageSize);
+         Map map = null;
+         try {
+ 	         map = IndividualListController.getRandomResultsForVClass(
+ 	                 vclassURI, 
+ 	                 page, 
+ 	                 pageSize, 
+ 	                 vreq.getWebappDaoFactory().getIndividualDao(), 
+ 	                 context);  
+         } catch(Exception ex) {
+         	log.error("Error in retrieval of search results for VClass " + vclassURI, ex);
+         }
+
+         return map;
+    }
     
 
 }
diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/login/LoginProcessBean.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/login/LoginProcessBean.java
index 5c4c5017c..9a2e6c456 100644
--- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/login/LoginProcessBean.java
+++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/login/LoginProcessBean.java
@@ -2,7 +2,6 @@
 
 package edu.cornell.mannlib.vitro.webapp.controller.login;
 
-import java.text.MessageFormat;
 import java.util.Arrays;
 
 import javax.servlet.http.HttpServletRequest;
@@ -11,6 +10,8 @@ import javax.servlet.http.HttpSession;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import edu.cornell.mannlib.vitro.webapp.i18n.I18n;
+
 /**
  * Where are we in the process of logging on? What message should we show to the
  * user?
@@ -110,60 +111,32 @@ public class LoginProcessBean {
 	}
 
 	public static class Message {
-		public static final Message NO_MESSAGE = new Message("", MLevel.NONE);
+		public static final Message NO_MESSAGE = new Message();
 
-		public static final Message PASSWORD_CHANGE_SAVED = new Message(
-				"Your password has been saved.
" + "Please log in.", - MLevel.INFO); - - public static final Message NO_USERNAME = new Message( - "Please enter your email address.", MLevel.ERROR); - - public static final Message NO_PASSWORD = new Message( - "Please enter your password.", MLevel.ERROR); - - public static final Message UNKNOWN_USERNAME = new Message( - "The email or password you entered is incorrect.", MLevel.ERROR); - - public static final Message LOGIN_DISABLED = new Message( - "User logins are temporarily disabled while the system is being maintained.", - MLevel.ERROR); - - public static final Message INCORRECT_PASSWORD = new Message( - "The email or password you entered is incorrect.", MLevel.ERROR); - - public static final Message NO_NEW_PASSWORD = new Message( - "Please enter your new password.", MLevel.ERROR); - - public static final Message MISMATCH_PASSWORD = new Message( - "The passwords entered do not match.", MLevel.ERROR); - - public static final Message PASSWORD_LENGTH = new Message( - "Please enter a password between {0} and {1} characters in length.", - MLevel.ERROR); - - public static final Message USING_OLD_PASSWORD = new Message( - "Your new password cannot match the current one.", MLevel.ERROR); - - private final String format; + private final String text; private final MLevel messageLevel; - public Message(String format, MLevel messageLevel) { - this.format = format; - this.messageLevel = messageLevel; + public Message() { + this.messageLevel = MLevel.NONE; + this.text = ""; } - + + public Message(HttpServletRequest req, MLevel messageLevel, String textKey, Object... parameters) { + this.messageLevel = messageLevel; + this.text = I18n.bundle(req).text(textKey, parameters); + } + public MLevel getMessageLevel() { return this.messageLevel; } - public String formatMessage(Object[] args) { - return new MessageFormat(this.format).format(args); + public String getText() { + return text; } @Override public String toString() { - return "Message[" + messageLevel + ", '" + format + "']"; + return "Message[" + messageLevel + ", '" + text + "']"; } } @@ -210,10 +183,15 @@ public class LoginProcessBean { } } - public void setMessage(Message message, Object... args) { + public void setMessage(Message message) { synchronized (messageSynchronizer) { this.message = message; - this.messageArguments = args; + } + } + + public void setMessage(HttpServletRequest req, MLevel level, String textKey, Object... parameters) { + synchronized (messageSynchronizer) { + this.message = new Message(req, level, textKey, parameters); } } @@ -221,7 +199,7 @@ public class LoginProcessBean { synchronized (messageSynchronizer) { String text = ""; if (message.getMessageLevel() == MLevel.INFO) { - text = message.formatMessage(messageArguments); + text = message.getText(); clearMessage(); } return text; @@ -232,7 +210,7 @@ public class LoginProcessBean { synchronized (messageSynchronizer) { String text = ""; if (message.getMessageLevel() == MLevel.ERROR) { - text = message.formatMessage(messageArguments); + text = message.getText(); clearMessage(); } return text; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/DisplayVocabulary.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/DisplayVocabulary.java index 5d5defc36..4a832d784 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/DisplayVocabulary.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/DisplayVocabulary.java @@ -115,13 +115,6 @@ public class DisplayVocabulary { public static final String USE_TBOX_MODEL_PARAM = "useThisTboxModel"; public static final String USE_DISPLAY_MODEL_PARAM = "useThisDisplayModel"; - //Attribute values used to store display tbox/display display model in servlet context - public static final String CONTEXT_DISPLAY_TBOX = "displayOntModelTBOX"; - public static final String CONTEXT_DISPLAY_DISPLAY = "displayOntModelDisplayModel"; - - /** Key for display model in request, session or context attributes */ - public static final String DISPLAY_ONT_MODEL = "displayOntModel"; - //URL for menu management public static final String PROCESS_MENU_MANAGEMENT_URL = "/menuManagementEdit"; public static final String REORDER_MENU_URL = PROCESS_MENU_MANAGEMENT_URL + "?cmd=Reorder&" + SWITCH_TO_DISPLAY_MODEL + "=true"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ModelAccess.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ModelAccess.java new file mode 100644 index 000000000..482fd5df6 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ModelAccess.java @@ -0,0 +1,322 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao; + +import java.util.EnumMap; +import java.util.Map; + +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; + +import com.hp.hpl.jena.ontology.OntModel; + +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; + +/** + * Hierarchical storage for models. TODO + * + * Could this be extended? Could it be used to replace or implement these + * methods? + * + *
+ * VitroRequest.getAssertionsWebappDaoFactory()
+ * VitroRequest.getFullWebappDaoFactory()
+ * VitroRequest.getRDFService()
+ * VitroRequest.getUnfilteredRDFService()
+ * VitroRequest.getWebappDaoFactory()
+ * VitroRequest.getWriteModel()
+ * vreq.setUnfilteredWebappDaoFactory(wadf);
+ * 
+ * OntModelSelector.getABoxModel
+ * OntModelSelector.getFullModel()
+ * OntModelSelector.getTBoxModel()
+ * VitroModelSource.getModel(URL)
+ * VitroModelSource.getModel(URL, loadIfAbsent)
+ * VitroModelSource.openModel(name)
+ * VitroModelSource.openModelIfPresent(string)
+ * ServletContext.getAttribute("pelletOntModel")
+ * VitroJenaModelMaker
+ * VitroJenaSpecialModelMaker
+ * JenaDataSourceSetupBase.getApplicationDataSource(ctx)
+ * JenaDataSourceSetupBase.getStartupDataset()
+ * HttpSession.getAttribute("jenaAuditModel")
+ * 
+ */ + +public class ModelAccess { + private static final Log log = LogFactory.getLog(ModelAccess.class); + + /** These attributes should only be accessed through this class. */ + private static final String ATTRIBUTE_NAME = ModelAccess.class.getName(); + + public enum ModelID { + APPLICATION_METADATA, + + USER_ACCOUNTS, + + DISPLAY, DISPLAY_DISPLAY, DISPLAY_TBOX, + + BASE_ABOX, BASE_TBOX, BASE_FULL, + + INFERRED_ABOX, INFERRED_TBOX, INFERRED_FULL, + + UNION_ABOX, UNION_TBOX, UNION_FULL + } + + public enum FactoryID { + BASE, UNION + } + + private enum Scope { + CONTEXT, SESSION, REQUEST + } + + // ---------------------------------------------------------------------- + // Factory methods + // ---------------------------------------------------------------------- + + public static ModelAccess on(HttpServletRequest req) { + Object o = req.getAttribute(ATTRIBUTE_NAME); + if (o instanceof ModelAccess) { + return (ModelAccess) o; + } else { + ModelAccess parent = on(req.getSession()); + ModelAccess ma = new ModelAccess(Scope.REQUEST, parent); + req.setAttribute(ATTRIBUTE_NAME, ma); + return ma; + } + } + + public static ModelAccess on(HttpSession session) { + Object o = session.getAttribute(ATTRIBUTE_NAME); + if (o instanceof ModelAccess) { + return (ModelAccess) o; + } else { + ModelAccess parent = on(session.getServletContext()); + ModelAccess ma = new ModelAccess(Scope.SESSION, parent); + session.setAttribute(ATTRIBUTE_NAME, ma); + return ma; + } + } + + public static ModelAccess on(ServletContext ctx) { + Object o = ctx.getAttribute(ATTRIBUTE_NAME); + if (o instanceof ModelAccess) { + return (ModelAccess) o; + } else { + ModelAccess ma = new ModelAccess(Scope.CONTEXT, null); + ctx.setAttribute(ATTRIBUTE_NAME, ma); + return ma; + } + } + + // ---------------------------------------------------------------------- + // The instance + // ---------------------------------------------------------------------- + + private final Scope scope; + private final ModelAccess parent; + private final Map modelMap = new EnumMap<>(ModelID.class); + private final Map factoryMap = new EnumMap<>( + FactoryID.class); + + public ModelAccess(Scope scope, ModelAccess parent) { + this.scope = scope; + this.parent = parent; + } + + // ---------------------------------------------------------------------- + // Accessing the models + // ---------------------------------------------------------------------- + + public OntModel getApplicationMetadataModel() { + return getOntModel(ModelID.APPLICATION_METADATA); + } + + public void setUserAccountsModel(OntModel m) { + setOntModel(ModelID.USER_ACCOUNTS, m); + } + + public OntModel getUserAccountsModel() { + return getOntModel(ModelID.USER_ACCOUNTS); + } + + public void setDisplayModel(OntModel m) { + setOntModel(ModelID.DISPLAY, m); + } + + public OntModel getDisplayModel() { + return getOntModel(ModelID.DISPLAY); + } + + public void setJenaOntModel(OntModel m) { + setOntModel(ModelID.UNION_FULL, m); + } + + public OntModel getJenaOntModel() { + return getOntModel(ModelID.UNION_FULL); + } + + public void setBaseOntModel(OntModel m) { + setOntModel(ModelID.BASE_FULL, m); + } + + public OntModel getBaseOntModel() { + return getOntModel(ModelID.BASE_FULL); + } + + public OntModel getInferenceOntModel() { + return getOntModel(ModelID.INFERRED_FULL); + } + + public void setOntModel(ModelID id, OntModel ontModel) { + if (ontModel == null) { + modelMap.remove(id); + } else { + modelMap.put(id, ontModel); + } + } + + public void removeOntModel(ModelID id) { + setOntModel(id, null); + } + + public OntModel getOntModel(ModelID id) { + if (modelMap.containsKey(id)) { + log.debug("Using " + id + " model from " + scope); + return modelMap.get(id); + } else if (parent != null) { + return parent.getOntModel(id); + } else { + log.warn("No model found for " + id); + return null; + } + } + + // ---------------------------------------------------------------------- + // Accessing the Webapp DAO factories. + // ---------------------------------------------------------------------- + + public void setWebappDaoFactory(WebappDaoFactory wadf) { + setWebappDaoFactory(FactoryID.UNION, wadf); + } + + public WebappDaoFactory getWebappDaoFactory() { + return getWebappDaoFactory(FactoryID.UNION); + } + + public void setBaseWebappDaoFactory(WebappDaoFactory wadf) { + setWebappDaoFactory(FactoryID.BASE, wadf); + } + + public WebappDaoFactory getBaseWebappDaoFactory() { + return getWebappDaoFactory(FactoryID.BASE); + } + + public void setWebappDaoFactory(FactoryID id, WebappDaoFactory wadf) { + if (wadf == null) { + factoryMap.remove(id); + } else { + factoryMap.put(id, wadf); + } + } + + public void removeWebappDaoFactory(FactoryID id) { + setWebappDaoFactory(id, null); + } + + public WebappDaoFactory getWebappDaoFactory(FactoryID id) { + if (factoryMap.containsKey(id)) { + log.debug("Using " + id + " DAO factory from " + scope); + return factoryMap.get(id); + } else if (parent != null) { + return parent.getWebappDaoFactory(id); + } else { + log.warn("No DAO factory found for " + id); + return null; + } + } + + // ---------------------------------------------------------------------- + // Accessing the OntModelSelectors + // ---------------------------------------------------------------------- + + public OntModelSelector getOntModelSelector() { + return getUnionOntModelSelector(); + } + + public OntModelSelector getBaseOntModelSelector() { + return new FacadeOntModelSelector(this, ModelID.BASE_ABOX, + ModelID.BASE_TBOX, ModelID.BASE_FULL); + } + + public OntModelSelector getInferenceOntModelSelector() { + return new FacadeOntModelSelector(this, ModelID.INFERRED_ABOX, + ModelID.INFERRED_TBOX, ModelID.INFERRED_FULL); + } + + public OntModelSelector getUnionOntModelSelector() { + return new FacadeOntModelSelector(this, ModelID.UNION_ABOX, + ModelID.UNION_TBOX, ModelID.UNION_FULL); + } + + // ---------------------------------------------------------------------- + // Helper classes + // ---------------------------------------------------------------------- + + /** + * This OntModelSelector doesn't actually hold any OntModels. Instead, it + * links back to the ModelAccess that it was created from. So, if you change + * a model on the ModelAccess, it will change on the OntModelSelector also. + * Even if the OntModelSelector was created first. + */ + private static class FacadeOntModelSelector implements OntModelSelector { + private final ModelAccess parent; + private final ModelID aboxID; + private final ModelID tboxID; + private final ModelID fullID; + + public FacadeOntModelSelector(ModelAccess parent, ModelID aboxID, + ModelID tboxID, ModelID fullID) { + this.parent = parent; + this.aboxID = aboxID; + this.tboxID = tboxID; + this.fullID = fullID; + } + + @Override + public OntModel getABoxModel() { + return parent.getOntModel(aboxID); + } + + @Override + public OntModel getTBoxModel() { + return parent.getOntModel(tboxID); + } + + @Override + public OntModel getFullModel() { + return parent.getOntModel(fullID); + } + + @Override + public OntModel getApplicationMetadataModel() { + return parent.getOntModel(ModelID.APPLICATION_METADATA); + } + + @Override + public OntModel getUserAccountsModel() { + return parent.getOntModel(ModelID.USER_ACCOUNTS); + } + + @Override + public OntModel getDisplayModel() { + return parent.getOntModel(ModelID.DISPLAY); + } + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDao.java index 6570984ee..5327d3df2 100755 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDao.java @@ -13,7 +13,9 @@ public interface ObjectPropertyDao extends PropertyDao { public abstract List getAllObjectProperties(); - public ObjectProperty getObjectPropertyByURI(String objectPropertyURI); + public ObjectProperty getObjectPropertyByURI(String objectPropertyURI); + + public ObjectProperty getObjectPropertyByURIAndRangeURI(String objectPropertyURI, String rangeURI); public List getObjectPropertiesForObjectPropertyStatements(List /*of ObjectPropertyStatement */ objectPropertyStatements); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDao.java index 93d52f2ac..34bd23d46 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDao.java @@ -41,7 +41,7 @@ public interface ObjectPropertyStatementDao { public Map getMostSpecificTypesInClassgroupsForIndividual(String subjectUri); List> getObjectPropertyStatementsForIndividualByProperty( - String subjectUri, String propertyUri, String objectKey, + String subjectUri, String propertyUri, String objectKey, String rangeUri, String queryString, Set constructQueryStrings, String sortDirection); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassGroupsForRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassGroupsForRequest.java new file mode 100644 index 000000000..753e695e0 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassGroupsForRequest.java @@ -0,0 +1,93 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +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.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; +import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; + +/** + * A request-based image of the VClassGroupCache. That means that the names of + * the classes and groups are in the correct language for this request. + */ +public class VClassGroupsForRequest { + private static final Log log = LogFactory + .getLog(VClassGroupsForRequest.class); + + private final HttpServletRequest req; + private final Map groupMap = new LinkedHashMap<>(); + private final Map classMap = new HashMap<>(); + + public VClassGroupsForRequest(HttpServletRequest req, VClassGroupCache cache) { + this.req = req; + + for (VClassGroup vcGroup : cache.getGroups()) { + loadGroup(vcGroup); + } + + if (log.isDebugEnabled()) { + log.debug("groups: " + groupMap); + log.debug("classes: " + classMap); + } + } + + private void loadGroup(VClassGroup vcg) { + VClassGroup newVcg = new VClassGroup(vcg); + newVcg.setPublicName(getNameForGroup(vcg)); + groupMap.put(newVcg.getURI(), newVcg); + + for (VClass vClass : vcg) { + loadClass(vClass, newVcg); + } + } + + private String getNameForGroup(VClassGroup vcGroup) { + VClassGroup g = ModelAccess.on(req).getWebappDaoFactory() + .getVClassGroupDao().getGroupByURI(vcGroup.getURI()); + return (g == null) ? vcGroup.getPublicName() : g.getPublicName(); + } + + private void loadClass(VClass vc, VClassGroup newVcg) { + VClass newVc = new VClass(vc); + newVc.setName(getNameForVClass(vc)); + newVc.setGroup(newVcg); + newVcg.add(newVc); + classMap.put(newVc.getURI(), newVc); + } + + private String getNameForVClass(VClass vClass) { + VClass vc = ModelAccess.on(req).getWebappDaoFactory().getVClassDao() + .getVClassByURI(vClass.getURI()); + return (vc == null) ? vClass.getName() : vc.getName(); + } + + public VClassGroup getGroup(String vClassGroupURI) { + VClassGroup vcg = groupMap.get(vClassGroupURI); + log.debug("getGroup(" + vClassGroupURI + ") = " + vcg); + return vcg; + } + + public List getGroups() { + ArrayList groups = new ArrayList<>(groupMap.values()); + log.debug("getGroups() returned " + groups.size() + " groups."); + return groups; + } + + public VClass getCachedVClass(String classUri) { + VClass vc = classMap.get(classUri); + log.debug("getCachedVClass(" + classUri + ") = " + vc); + return vc; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryConfig.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryConfig.java index 72d14454b..aea5acc1c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryConfig.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryConfig.java @@ -12,6 +12,7 @@ public class WebappDaoFactoryConfig { private List preferredLanguages; private String defaultNamespace; private Set nonUserNamespaces; + private boolean isUnderlyingStoreReasoned = false; public WebappDaoFactoryConfig() { preferredLanguages = Arrays.asList("en-US", "en", "EN"); @@ -44,4 +45,12 @@ public class WebappDaoFactoryConfig { this.nonUserNamespaces = nonUserNamespaces; } + public void setUnderlyingStoreReasoned(boolean isReasoned) { + this.isUnderlyingStoreReasoned = isReasoned; + } + + public boolean isUnderlyingStoreReasoned() { + return this.isUnderlyingStoreReasoned; + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/DataPropertyDaoFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/DataPropertyDaoFiltering.java index 819f84f65..bd3a10c23 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/DataPropertyDaoFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/DataPropertyDaoFiltering.java @@ -8,12 +8,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import net.sf.jga.fn.UnaryFunctor; import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; import edu.cornell.mannlib.vitro.webapp.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; @@ -31,21 +28,12 @@ class DataPropertyDaoFiltering extends BaseFiltering implements DataPropertyDao{ this.filters = filters; } - public void deleteDataProperty(DataProperty dataProperty) { - innerDataPropertyDao.deleteDataProperty(dataProperty); - } + // ---------------------------------------------------------------------- + // Filtered operations + // ---------------------------------------------------------------------- - - public void deleteDataProperty(String dataPropertyURI) { - innerDataPropertyDao.deleteDataProperty(dataPropertyURI); - } - - public boolean annotateDataPropertyAsExternalIdentifier(String dataPropertyURI) { - return innerDataPropertyDao.annotateDataPropertyAsExternalIdentifier(dataPropertyURI); - } - - - public void fillDataPropertiesForIndividual(Individual individual) { + @Override + public void fillDataPropertiesForIndividual(Individual individual) { innerDataPropertyDao.fillDataPropertiesForIndividual(individual); List props = individual.getDataPropertyList(); if(props != null && props.size() > 0){ @@ -53,21 +41,23 @@ class DataPropertyDaoFiltering extends BaseFiltering implements DataPropertyDao{ } } - - public List getAllDataProperties() { + @Override + public List getAllDataProperties() { return filter(innerDataPropertyDao.getAllDataProperties(), filters.getDataPropertyFilter()); } - public List getAllExternalIdDataProperties() { + @Override + public List getAllExternalIdDataProperties() { return filter(innerDataPropertyDao.getAllDataProperties(), filters.getDataPropertyFilter()); } - + @Override public List getDataPropertiesForVClass(String classURI) { return filter(innerDataPropertyDao.getDataPropertiesForVClass(classURI), filters.getDataPropertyFilter()); } + @Override public Collection getAllPossibleDatapropsForIndividual(String individualURI) { List filteredProps = new ArrayList(); for (DataProperty dp: innerDataPropertyDao.getAllPossibleDatapropsForIndividual(individualURI)) { @@ -79,125 +69,137 @@ class DataPropertyDaoFiltering extends BaseFiltering implements DataPropertyDao{ return filteredProps; } + // ---------------------------------------------------------------------- + // Unfiltered operations + // ---------------------------------------------------------------------- + + @Override + public void deleteDataProperty(DataProperty dataProperty) { + innerDataPropertyDao.deleteDataProperty(dataProperty); + } + + @Override + public void deleteDataProperty(String dataPropertyURI) { + innerDataPropertyDao.deleteDataProperty(dataPropertyURI); + } + + @Override + public boolean annotateDataPropertyAsExternalIdentifier(String dataPropertyURI) { + return innerDataPropertyDao.annotateDataPropertyAsExternalIdentifier(dataPropertyURI); + } + + @Override public String getRequiredDatatypeURI(Individual individual, DataProperty dataProperty) { return innerDataPropertyDao.getRequiredDatatypeURI(individual, dataProperty); } + @Override public DataProperty getDataPropertyByURI(String dataPropertyURI) { - DataProperty prop = innerDataPropertyDao.getDataPropertyByURI(dataPropertyURI); - if( prop != null ){ - Boolean acceptable = filters.getDataPropertyFilter().fn(prop); - if( acceptable == Boolean.TRUE ) - return prop; - else - return null; - } - return null; + return innerDataPropertyDao.getDataPropertyByURI(dataPropertyURI); } - + @Override public String insertDataProperty(DataProperty dataProperty) throws InsertException { return innerDataPropertyDao.insertDataProperty(dataProperty); } - + @Override public void updateDataProperty(DataProperty dataProperty) { innerDataPropertyDao.updateDataProperty(dataProperty); } - public void addSuperproperty(ObjectProperty property, ObjectProperty superproperty) { - innerDataPropertyDao.addSuperproperty(property, superproperty); - } - + @Override public void addSuperproperty(String propertyURI, String superpropertyURI) { innerDataPropertyDao.addSuperproperty(propertyURI, superpropertyURI); } - public void removeSuperproperty(ObjectProperty property, ObjectProperty superproperty) { - innerDataPropertyDao.removeSuperproperty(property, superproperty); - } - + @Override public void removeSuperproperty(String propertyURI, String superpropertyURI) { innerDataPropertyDao.removeSuperproperty(propertyURI, superpropertyURI); } - public void addSubproperty(ObjectProperty property, ObjectProperty subproperty) { - innerDataPropertyDao.addSubproperty(property, subproperty); - } - + @Override public void addSubproperty(String propertyURI, String subpropertyURI) { innerDataPropertyDao.addSubproperty(propertyURI, subpropertyURI); } - public void removeSubproperty(ObjectProperty property, ObjectProperty subproperty) { - innerDataPropertyDao.removeSubproperty(property, subproperty); - } - + @Override public void removeSubproperty(String propertyURI, String subpropertyURI) { innerDataPropertyDao.removeSubproperty(propertyURI, subpropertyURI); } + @Override public List getSubPropertyURIs(String propertyURI) { return innerDataPropertyDao.getSubPropertyURIs(propertyURI); } + @Override public List getAllSubPropertyURIs(String propertyURI) { return innerDataPropertyDao.getAllSubPropertyURIs(propertyURI); } + @Override public List getSuperPropertyURIs(String propertyURI, boolean direct) { return innerDataPropertyDao.getSuperPropertyURIs(propertyURI, direct); } + @Override public List getAllSuperPropertyURIs(String propertyURI) { return innerDataPropertyDao.getAllSuperPropertyURIs(propertyURI); } + @Override public List getRootDataProperties() { return innerDataPropertyDao.getRootDataProperties(); } + @Override public void addSubproperty(Property property, Property subproperty) { innerDataPropertyDao.addSubproperty(property, subproperty); } + @Override public void addSuperproperty(Property property, Property superproperty) { innerDataPropertyDao.addSuperproperty(property, superproperty); } + @Override public void removeSubproperty(Property property, Property subproperty) { innerDataPropertyDao.removeSubproperty(property, subproperty); } + @Override public void removeSuperproperty(Property property, Property superproperty) { innerDataPropertyDao.removeSuperproperty(property, superproperty); } - public void addEquivalentProperty(String propertyURI, - String equivalentPropertyURI) { + @Override + public void addEquivalentProperty(String propertyURI, String equivalentPropertyURI) { innerDataPropertyDao.addEquivalentProperty(propertyURI, equivalentPropertyURI); } - public void addEquivalentProperty(Property property, - Property equivalentProperty) { + @Override + public void addEquivalentProperty(Property property, Property equivalentProperty) { innerDataPropertyDao.addEquivalentProperty(property, equivalentProperty); } + @Override public List getEquivalentPropertyURIs(String propertyURI) { return innerDataPropertyDao.getEquivalentPropertyURIs(propertyURI); } - public void removeEquivalentProperty(String propertyURI, - String equivalentPropertyURI) { + @Override + public void removeEquivalentProperty(String propertyURI, String equivalentPropertyURI) { innerDataPropertyDao.removeEquivalentProperty(propertyURI, equivalentPropertyURI); } - public void removeEquivalentProperty(Property property, - Property equivalentProperty) { + @Override + public void removeEquivalentProperty(Property property, Property equivalentProperty) { innerDataPropertyDao.removeEquivalentProperty(property, equivalentProperty); } - public List getClassesWithRestrictionOnProperty(String propertyURI) { + @Override + public List getClassesWithRestrictionOnProperty(String propertyURI) { return innerDataPropertyDao.getClassesWithRestrictionOnProperty(propertyURI); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/IndividualFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/IndividualFiltering.java index 376445742..bb4b902ee 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/IndividualFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/IndividualFiltering.java @@ -15,6 +15,8 @@ import java.util.Map; import net.sf.jga.algorithms.Filter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.json.JSONException; import org.json.JSONObject; @@ -29,7 +31,6 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters; -import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch; /** * A Individual object that will delegate to an inner Individual @@ -42,6 +43,8 @@ import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch; public class IndividualFiltering implements Individual { private final Individual _innerIndividual; private final VitroFilters _filters; + + private static final Log log = LogFactory.getLog(IndividualFiltering.class); public IndividualFiltering(Individual individual, VitroFilters filters) { super(); @@ -143,10 +146,18 @@ public class IndividualFiltering implements Individual { // I'd rather filter on the actual ObjectPropertyStatements here, but // Individual.getPopulatedObjectPropertyList doesn't actually populate // the ObjectProperty with statements. - jblake + + // bjl23: disabling this filtering because the individual statements are + // filtered later, and we need to allow for the possibility that a particular + // predicate + range class combination is allowed even if the predicate is + // hidden on its own. + + // Will revisit filtering at this level if it turns out to be truly necessary. + List outOProps = new ArrayList(); List oProps = _innerIndividual.getPopulatedObjectPropertyList(); for (ObjectProperty op: oProps) { - if (_filters.getObjectPropertyStatementFilter().fn( + if (true || _filters.getObjectPropertyStatementFilter().fn( new ObjectPropertyStatementImpl(this._innerIndividual.getURI(), op.getURI(), SOME_LITERAL))) { outOProps.add(op); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyDaoFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyDaoFiltering.java index f12c64858..7e8704582 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyDaoFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyDaoFiltering.java @@ -48,6 +48,11 @@ class ObjectPropertyDaoFiltering extends BaseFiltering implements ObjectProperty ObjectProperty newOprop=innerObjectPropertyDao.getObjectPropertyByURI(objectPropertyURI); return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters); } + + public ObjectProperty getObjectPropertyByURIAndRangeURI(String objectPropertyURI, String rangeURI) { + ObjectProperty newOprop=innerObjectPropertyDao.getObjectPropertyByURIAndRangeURI(objectPropertyURI, rangeURI); + return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters); + } public List getStatementsUsingObjectProperty(ObjectProperty op) { return ObjectPropertyStatementDaoFiltering.filterAndWrapList(innerObjectPropertyDao.getStatementsUsingObjectProperty(op),filters); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementDaoFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementDaoFiltering.java index 5f09c5188..de7c93438 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementDaoFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementDaoFiltering.java @@ -86,12 +86,12 @@ class ObjectPropertyStatementDaoFiltering extends BaseFiltering implements Objec @Override public List> getObjectPropertyStatementsForIndividualByProperty( - String subjectUri, String propertyUri, String objectKey, String query, - Set queryStrings, String sortDirection) { + String subjectUri, String propertyUri, String objectKey, String rangeUri, + String query, Set queryStrings, String sortDirection) { List> data = innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty( - subjectUri, propertyUri, objectKey, query, queryStrings,sortDirection); + subjectUri, propertyUri, objectKey, rangeUri, query, queryStrings,sortDirection); /* Filter the data * @@ -105,6 +105,10 @@ class ObjectPropertyStatementDaoFiltering extends BaseFiltering implements Objec for (Map map : data) { String objectUri = map.get(objectKey); ObjectPropertyStatement statement = new ObjectPropertyStatementImpl(subjectUri, propertyUri, objectUri); + ObjectProperty op = new ObjectProperty(); + op.setURI(propertyUri); + op.setRangeVClassURI(rangeUri); + statement.setProperty(op); stmtsToData.put(statement, map); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java index 8a1ce1189..0d4d77a9b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyDaoJena.java @@ -8,7 +8,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -24,7 +23,6 @@ import com.hp.hpl.jena.ontology.OntProperty; import com.hp.hpl.jena.ontology.OntResource; import com.hp.hpl.jena.ontology.ProfileException; import com.hp.hpl.jena.ontology.Restriction; -import com.hp.hpl.jena.ontology.SomeValuesFromRestriction; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; @@ -53,7 +51,6 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.InsertException; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; -import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.PelletListener; @@ -93,7 +90,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements try { com.hp.hpl.jena.ontology.OntResource ind = ontModel.getOntResource(dataPropertyURI); if( ind != null ){ - ontModel.add(ind,(Property)DATAPROPERTY_ISEXTERNALID, "TRUE"); + ontModel.add(ind, DATAPROPERTY_ISEXTERNALID, "TRUE"); return true; }else{ return false; @@ -114,7 +111,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements while(restIt.hasNext()) { Resource restRes = restIt.next(); if (restRes.canAs(OntResource.class)) { - OntResource restOntRes = (OntResource) restRes.as(OntResource.class); + OntResource restOntRes = restRes.as(OntResource.class); smartRemove(restOntRes, ontModel); } } @@ -181,7 +178,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements dp.setNamespace(op.getNameSpace()); dp.setLocalName(op.getLocalName()); OntologyDao oDao=getWebappDaoFactory().getOntologyDao(); - Ontology o = (Ontology)oDao.getOntologyByURI(dp.getNamespace()); + Ontology o = oDao.getOntologyByURI(dp.getNamespace()); if (o==null) { if (!VitroVocabulary.vitroURI.equals(dp.getNamespace())) { log.debug("datapropFromOntProperty(): no ontology object found for the namespace "+dp.getNamespace()); @@ -206,8 +203,8 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements dp.setExample(getPropertyStringValue(op,EXAMPLE_ANNOT)); dp.setDescription(getPropertyStringValue(op,DESCRIPTION_ANNOT)); dp.setPublicDescription(getPropertyStringValue(op,PUBLIC_DESCRIPTION_ANNOT)); - dp.setDisplayTier(((WebappDaoFactoryJena)getWebappDaoFactory()).getJenaBaseDao().getPropertyNonNegativeIntValue(op, DISPLAY_RANK_ANNOT)); - dp.setDisplayLimit(((WebappDaoFactoryJena)getWebappDaoFactory()).getJenaBaseDao().getPropertyNonNegativeIntValue(op, DISPLAY_LIMIT)); + dp.setDisplayTier((getWebappDaoFactory()).getJenaBaseDao().getPropertyNonNegativeIntValue(op, DISPLAY_RANK_ANNOT)); + dp.setDisplayLimit((getWebappDaoFactory()).getJenaBaseDao().getPropertyNonNegativeIntValue(op, DISPLAY_LIMIT)); //There might be multiple HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT properties, only use the highest StmtIterator it = op.listProperties(HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT); @@ -216,7 +213,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements Statement stmt = it.nextStatement(); RDFNode obj; if( stmt != null && (obj = stmt.getObject()) != null && obj.isURIResource() ){ - Resource res = (Resource)obj.as(Resource.class); + Resource res = obj.as(Resource.class); if( res != null && res.getURI() != null ){ BaseResourceBean.RoleLevel roleFromModel = BaseResourceBean.RoleLevel.getRoleByUri(res.getURI()); if( roleFromModel != null && @@ -235,7 +232,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements Statement stmt = it.nextStatement(); RDFNode obj; if( stmt != null && (obj = stmt.getObject()) != null && obj.isURIResource() ){ - Resource res = (Resource)obj.as(Resource.class); + Resource res = obj.as(Resource.class); if( res != null && res.getURI() != null ){ BaseResourceBean.RoleLevel roleFromModel = BaseResourceBean.RoleLevel.getRoleByUri(res.getURI()); if( roleFromModel != null && @@ -365,7 +362,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements while (restIt.hasNext()) { Resource restRes = restIt.next(); if (restRes.canAs(Restriction.class)) { - Restriction rest = (Restriction) restRes.as(Restriction.class); + Restriction rest = restRes.as(Restriction.class); if (rest.isAllValuesFromRestriction()) { AllValuesFromRestriction avfrest = rest.asAllValuesFromRestriction(); if (avfrest.getAllValuesFrom() != null) { @@ -485,7 +482,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements } com.hp.hpl.jena.ontology.DatatypeProperty jDataprop = ontModel.createDatatypeProperty(dtp.getURI()); if (dtp.getPublicName() != null && dtp.getPublicName().length() > 0) { - jDataprop.setLabel(dtp.getPublicName(), (String) getDefaultLanguage()); + jDataprop.setLabel(dtp.getPublicName(), getDefaultLanguage()); } else { jDataprop.removeAll(RDFS.label); } @@ -609,7 +606,7 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements while (parentNodeIt.hasNext()) { RDFNode parentNode = parentNodeIt.next(); if (parentNode.canAs(Property.class)) { - parentList.add((Property) parentNode.as(Property.class)); + parentList.add(parentNode.as(Property.class)); } } if (parentList.size()==0) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoJena.java index 600d0fa4d..9abceea00 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoJena.java @@ -10,6 +10,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import com.hp.hpl.jena.datatypes.TypeMapper; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntResource; @@ -27,7 +30,6 @@ import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; @@ -40,14 +42,9 @@ import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; import edu.cornell.mannlib.vitro.webapp.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.controller.edit.ReorderController; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ObjectPropertyStatementDaoJena; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; public class DataPropertyStatementDaoJena extends JenaBaseDao implements DataPropertyStatementDao { @@ -114,7 +111,7 @@ public class DataPropertyStatementDaoJena extends JenaBaseDao implements DataPro StmtIterator stmtIt = ind.listProperties(); while( stmtIt.hasNext() ) { - Statement st = (Statement)stmtIt.next(); + Statement st = stmtIt.next(); boolean addToList = /*allowAnyNameSpace ? st.getObject().canAs(Literal.class) :*/ st.getObject().isLiteral() && ( (RDF.value.equals(st.getPredicate()) || VitroVocabulary.value.equals(st.getPredicate().getURI())) @@ -210,7 +207,7 @@ public class DataPropertyStatementDaoJena extends JenaBaseDao implements DataPro // do something annoying if we are dealing with a blank node try { getOntModel().enterCriticalSection(Lock.READ); - OntResource ontRes = (OntResource) getOntModel().createResource( + OntResource ontRes = getOntModel().createResource( new AnonId(entity.getLocalName())).as(OntResource.class); if (ontRes == null) { return edList; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoSDB.java index dcdc82f19..64f39301c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DataPropertyStatementDaoSDB.java @@ -3,7 +3,6 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import com.hp.hpl.jena.ontology.OntModel; @@ -12,20 +11,15 @@ import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; -import com.hp.hpl.jena.query.QuerySolution; -import com.hp.hpl.jena.query.QuerySolutionMap; -import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.vocabulary.RDF; -import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; import edu.cornell.mannlib.vitro.webapp.beans.Individual; @@ -85,7 +79,7 @@ public class DataPropertyStatementDaoSDB extends DataPropertyStatementDaoJena StmtIterator stmtIt = ind.listProperties(); while( stmtIt.hasNext() ) { - Statement st = (Statement)stmtIt.next(); + Statement st = stmtIt.next(); boolean addToList = /*allowAnyNameSpace ? st.getObject().canAs(Literal.class) :*/ st.getObject().isLiteral() && ( (RDF.value.equals(st.getPredicate()) || VitroVocabulary.value.equals(st.getPredicate().getURI())) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DatatypeDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DatatypeDaoJena.java index f6a41b3bc..c0d31c9ee 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DatatypeDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DatatypeDaoJena.java @@ -4,14 +4,10 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import com.hp.hpl.jena.ontology.OntModel; - import edu.cornell.mannlib.vitro.webapp.beans.Datatype; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; public class DatatypeDaoJena extends JenaBaseDao implements DatatypeDao { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DependentResourceDeleteJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DependentResourceDeleteJena.java index 08b879c0b..8583ebe93 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DependentResourceDeleteJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DependentResourceDeleteJena.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.ListIterator; import java.util.Set; -import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Property; @@ -89,14 +88,13 @@ public class DependentResourceDeleteJena { * Find all statements where for a given statement in the assertions, * there is at least one statement in the retractions that has * the same predicate and object. */ - @SuppressWarnings("unchecked") private static List getChangedStmts(Model assertions, Model retractions){ List changedStmts = new LinkedList(); StmtIterator it = assertions.listStatements(); while(it.hasNext()){ Statement assertionStmtStatement = it.nextStatement(); if( assertionStmtStatement.getObject().canAs( Resource.class )){ - Resource asserObj = (Resource) assertionStmtStatement.getObject().as(Resource.class); + Resource asserObj = assertionStmtStatement.getObject().as(Resource.class); StmtIterator retractionStmts = retractions.listStatements( (Resource)null, @@ -138,7 +136,7 @@ public class DependentResourceDeleteJena { if( ( obj.canAs(Resource.class) && isPredicateDependencyRelation(stmt.getPredicate(), model) ) || ( obj.isAnon() && perviousWasDependentResource ) ){ - Resource res = (Resource)obj.as(Resource.class); + Resource res = obj.as(Resource.class); String id = res.isAnon()?res.getId().toString():res.getURI(); if( !visitedUris.contains(id) ){ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DisplayModelDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DisplayModelDaoJena.java index d1568e413..59af49fa8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DisplayModelDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/DisplayModelDaoJena.java @@ -7,9 +7,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; -import java.io.InputStream; import java.io.StringReader; import java.nio.channels.FileChannel; @@ -22,7 +20,6 @@ import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.util.FileManager; import edu.cornell.mannlib.vitro.webapp.dao.DisplayModelDao; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/EmptyReifier.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/EmptyReifier.java index 064dce350..ac29c9077 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/EmptyReifier.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/EmptyReifier.java @@ -2,7 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; -import java.util.ArrayList; import java.util.Collections; import org.apache.commons.collections.iterators.EmptyIterator; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoJena.java index 7293e0dda..ec2a79761 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoJena.java @@ -146,7 +146,7 @@ public class IndividualDaoJena extends JenaBaseDao implements IndividualDao { if (theClass.isAnon() && theClass.canAs(UnionClass.class)) { - UnionClass u = (UnionClass) theClass.as(UnionClass.class); + UnionClass u = theClass.as(UnionClass.class); for (OntClass operand : u.listOperands().toList()) { VClass vc = new VClassJena(operand, getWebappDaoFactory()); ents.addAll(getIndividualsByVClass(vc)); @@ -159,8 +159,8 @@ public class IndividualDaoJena extends JenaBaseDao implements IndividualDao { try { while (stmtIt.hasNext()) { Statement stmt = stmtIt.nextStatement(); - OntResource ind = (OntResource) stmt.getSubject().as(OntResource.class); - ents.add(new IndividualJena(ind, (WebappDaoFactoryJena) getWebappDaoFactory())); + OntResource ind = stmt.getSubject().as(OntResource.class); + ents.add(new IndividualJena(ind, getWebappDaoFactory())); } } finally { stmtIt.close(); @@ -232,7 +232,7 @@ public class IndividualDaoJena extends JenaBaseDao implements IndividualDao { ontModel.getBaseModel().notifyEvent(new IndividualCreationEvent(getWebappDaoFactory().getUserURI(),true,entURI)); com.hp.hpl.jena.ontology.Individual ind = ontModel.createIndividual(entURI,cls); if (ent.getName() != null) { - ind.setLabel(ent.getName(), (String) getDefaultLanguage()); + ind.setLabel(ent.getName(), getDefaultLanguage()); } List vclasses = ent.getVClasses(false); if (vclasses != null) { @@ -388,7 +388,7 @@ public class IndividualDaoJena extends JenaBaseDao implements IndividualDao { return 1; } if (res.canAs(OntResource.class)) { - OntResource ontRes = (OntResource) res.as(OntResource.class); + OntResource ontRes = res.as(OntResource.class); smartRemove(ontRes, ontModel); } else { ontModel.removeAll(res,null,null); @@ -420,7 +420,7 @@ public class IndividualDaoJena extends JenaBaseDao implements IndividualDao { OntResource ontRes = (entityURI.startsWith(VitroVocabulary.PSEUDO_BNODE_NS)) ? (OntResource) ontModel.createResource(new AnonId(entityURI.substring(VitroVocabulary.PSEUDO_BNODE_NS.length()))).as(OntResource.class) : ontModel.getOntResource(entityURI); - Individual ent = new IndividualJena(ontRes, (WebappDaoFactoryJena) getWebappDaoFactory()); + Individual ent = new IndividualJena(ontRes, getWebappDaoFactory()); return ent; } catch (Exception ex) { return null; @@ -494,7 +494,7 @@ public class IndividualDaoJena extends JenaBaseDao implements IndividualDao { String subUri = ((Resource)sub).getURI(); if( ! individualsMap.containsKey(subUri)){ com.hp.hpl.jena.ontology.Individual ind = getOntModel().getIndividual(subUri); - individualsMap.put(subUri,new IndividualJena(ind, (WebappDaoFactoryJena) getWebappDaoFactory())); + individualsMap.put(subUri,new IndividualJena(ind, getWebappDaoFactory())); } } @@ -519,7 +519,7 @@ public class IndividualDaoJena extends JenaBaseDao implements IndividualDao { String subUri = ((Resource)sub).getURI(); if( ! individualsMap.containsKey(subUri)){ com.hp.hpl.jena.ontology.Individual ind = getOntModel().getIndividual(subUri); - individualsMap.put(subUri,new IndividualJena(ind, (WebappDaoFactoryJena) getWebappDaoFactory())); + individualsMap.put(subUri,new IndividualJena(ind, getWebappDaoFactory())); } } @@ -544,7 +544,7 @@ public class IndividualDaoJena extends JenaBaseDao implements IndividualDao { String subUri = ((Resource)sub).getURI(); if( ! individualsMap.containsKey(subUri)){ com.hp.hpl.jena.ontology.Individual ind = getOntModel().getIndividual(subUri); - individualsMap.put(subUri,new IndividualJena(ind, (WebappDaoFactoryJena) getWebappDaoFactory())); + individualsMap.put(subUri,new IndividualJena(ind, getWebappDaoFactory())); } } } finally { @@ -594,7 +594,7 @@ public class IndividualDaoJena extends JenaBaseDao implements IndividualDao { continue; } com.hp.hpl.jena.ontology.Individual ind = getOntModel().getIndividual(st.getURI()); - inds.add(new IndividualJena(ind, (WebappDaoFactoryJena) getWebappDaoFactory())); + inds.add(new IndividualJena(ind, getWebappDaoFactory())); } } finally { if( stmts != null ) stmts.close(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoSDB.java index 388a69078..6ddec9a32 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoSDB.java @@ -106,7 +106,7 @@ public class IndividualDaoSDB extends IndividualDaoJena { : ResourceFactory.createResource(vclassURI); if (theClass.isAnon() && theClass.canAs(UnionClass.class)) { - UnionClass u = (UnionClass) theClass.as(UnionClass.class); + UnionClass u = theClass.as(UnionClass.class); for (OntClass operand : u.listOperands().toList()) { VClass vc = new VClassJena(operand, getWebappDaoFactory()); ents.addAll(getIndividualsByVClass(vc)); @@ -523,7 +523,7 @@ public class IndividualDaoSDB extends IndividualDaoJena { try { ResultSet results = qe.execSelect(); while (results.hasNext()) { - QuerySolution qs = (QuerySolution) results.next(); + QuerySolution qs = results.next(); Resource res = (Resource) qs.get("?ent"); if (res.getURI() != null) { individualURIs.add(res.getURI()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualJena.java index c0e6c0b61..944851dd8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualJena.java @@ -254,8 +254,8 @@ public class IndividualJena extends IndividualImpl implements Individual { if (!s.getSubject().canAs(OntResource.class) || !s.getObject().canAs(OntResource.class)) { continue; } - Individual subj = new IndividualJena((OntResource) s.getSubject().as(OntResource.class), webappDaoFactory); - Individual obj = new IndividualJena((OntResource) s.getObject().as(OntResource.class), webappDaoFactory); + Individual subj = new IndividualJena(s.getSubject().as(OntResource.class), webappDaoFactory); + Individual obj = new IndividualJena(s.getObject().as(OntResource.class), webappDaoFactory); ObjectProperty op = webappDaoFactory.getObjectPropertyDao().getObjectPropertyByURI(s.getPredicate().getURI()); if (subj != null && obj != null && op != null) { ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(); @@ -287,7 +287,7 @@ public class IndividualJena extends IndividualImpl implements Individual { RDFNode value = values.nextNode(); if (value.canAs(OntResource.class)) { relatedIndividuals.add( - new IndividualJena((OntResource) value.as(OntResource.class), webappDaoFactory) ); + new IndividualJena(value.as(OntResource.class), webappDaoFactory) ); } } } finally { @@ -305,7 +305,7 @@ public class IndividualJena extends IndividualImpl implements Individual { try { RDFNode value = ind.getPropertyValue(ind.getModel().getProperty(propertyURI)); if (value != null && value.canAs(OntResource.class)) { - return new IndividualJena((OntResource) value.as(OntResource.class), webappDaoFactory); + return new IndividualJena(value.as(OntResource.class), webappDaoFactory); } else { return null; } @@ -582,11 +582,11 @@ public class IndividualJena extends IndividualImpl implements Individual { int rv = 0; try { if( val1 instanceof String ) - rv = collator.compare( ((String)val1) , ((String)val2) ); + rv = collator.compare(val1 , val2); //rv = ((String)val1).compareTo((String)val2); else if( val1 instanceof Date ) { - DateTime dt1 = new DateTime((Date)val1); - DateTime dt2 = new DateTime((Date)val2); + DateTime dt1 = new DateTime(val1); + DateTime dt2 = new DateTime(val2); rv = dt1.compareTo(dt2); } else diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java index a12bd2fbe..05c224030 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java @@ -478,8 +478,7 @@ public class IndividualSDB extends IndividualImpl implements Individual { Individual subj = null; try { subj = new IndividualSDB( - ((OntResource) s.getSubject().as(OntResource.class)) - .getURI(), + s.getSubject().as(OntResource.class).getURI(), this.dwf, datasetMode, webappDaoFactory); } catch (IndividualNotFoundException e) { // leave null subject @@ -487,8 +486,7 @@ public class IndividualSDB extends IndividualImpl implements Individual { Individual obj = null; try { obj = new IndividualSDB( - ((OntResource) s.getObject().as(OntResource.class)) - .getURI(), + s.getObject().as(OntResource.class).getURI(), this.dwf, datasetMode, webappDaoFactory); } catch (IndividualNotFoundException e) { // leave null object @@ -548,8 +546,7 @@ public class IndividualSDB extends IndividualImpl implements Individual { if (value.canAs(OntResource.class)) { relatedIndividuals.add( new IndividualSDB( - ((OntResource) value.as(OntResource.class)) - .getURI(), + value.as(OntResource.class).getURI(), this.dwf, datasetMode, webappDaoFactory) ); @@ -588,7 +585,7 @@ public class IndividualSDB extends IndividualImpl implements Individual { if (value != null && value.canAs(OntResource.class)) { try { return new IndividualSDB( - ((OntResource) value.as(OntResource.class)).getURI(), + value.as(OntResource.class).getURI(), dwf, datasetMode, webappDaoFactory); } catch (IndividualNotFoundException e) { return null; @@ -1045,8 +1042,8 @@ public class IndividualSDB extends IndividualImpl implements Individual { rv = collator.compare( ((String)val1) , ((String)val2) ); //rv = ((String)val1).compareTo((String)val2); else if( val1 instanceof Date ) { - DateTime dt1 = new DateTime((Date)val1); - DateTime dt2 = new DateTime((Date)val2); + DateTime dt1 = new DateTime(val1); + DateTime dt2 = new DateTime(val2); rv = dt1.compareTo(dt2); } else diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java index 8bdd4fd00..6e8fe09d1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java @@ -12,7 +12,6 @@ import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Set; import org.apache.commons.logging.Log; @@ -23,7 +22,6 @@ import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.iri.IRI; import com.hp.hpl.jena.iri.IRIFactory; -import com.hp.hpl.jena.iri.Violation; import com.hp.hpl.jena.ontology.DatatypeProperty; import com.hp.hpl.jena.ontology.ObjectProperty; import com.hp.hpl.jena.ontology.OntClass; @@ -56,10 +54,6 @@ public class JenaBaseDao extends JenaBaseDaoCon { public static final boolean KEEP_ONLY_IF_TRUE = true; //used for updatePropertyBooleanValue() public static final boolean KEEP_ONLY_IF_FALSE = false; //used for updatePropertyBooleanValue() - public static final String JENA_ONT_MODEL_ATTRIBUTE_NAME = "jenaOntModel"; - public static final String ASSERTIONS_ONT_MODEL_ATTRIBUTE_NAME = "baseOntModel"; - public static final String INFERENCE_ONT_MODEL_ATTRIBUTE_NAME = "inferenceOntModel"; - protected static final Log log = LogFactory.getLog(JenaBaseDao.class.getName()); /* ******************* static constants ****************** */ @@ -749,10 +743,10 @@ public class JenaBaseDao extends JenaBaseDaoCon { if (label != null && label.length() > 0) { - String existingValue = ontRes.getLabel((String) getDefaultLanguage()); + String existingValue = ontRes.getLabel(getDefaultLanguage()); if (existingValue == null || !existingValue.equals(label)) { - ontRes.setLabel(label, (String) getDefaultLanguage()); + ontRes.setLabel(label, getDefaultLanguage()); } } else { ontRes.removeAll(RDFS.label); @@ -910,7 +904,7 @@ public class JenaBaseDao extends JenaBaseDaoCon { if (iri.hasViolation(false) ) { String errorStr = ("Bad URI: "+ uri + "\nOnly well-formed absolute URIrefs can be included in RDF/XML output: " - + ((Violation)iri.violations(false).next()).getShortMessage()); + + (iri.violations(false).next()).getShortMessage()); return errorStr; } else { return null; @@ -933,7 +927,7 @@ public class JenaBaseDao extends JenaBaseDaoCon { String idStr = vitroURIStr.split("#")[1]; RDFNode rdfNode = ontModel.getRDFNode(Node.createAnon(AnonId.create(idStr))); if ( (rdfNode != null) && (rdfNode.canAs(OntClass.class)) ) { - cls = (OntClass) rdfNode.as(OntClass.class); + cls = rdfNode.as(OntClass.class); } } else { try { @@ -1006,7 +1000,7 @@ public class JenaBaseDao extends JenaBaseDaoCon { StmtIterator stmtIt = getOntModel().listStatements((Resource)null, prop, value); while (stmtIt.hasNext()) { Statement stmt = stmtIt.nextStatement(); - possibleSubjectSet.add((Resource)stmt.getSubject()); + possibleSubjectSet.add(stmt.getSubject()); } Iterator possibleSubjectIt = possibleSubjectSet.iterator(); @@ -1016,7 +1010,7 @@ public class JenaBaseDao extends JenaBaseDaoCon { boolean hasAlternatePath = false; while (stmtIt.hasNext()) { Statement stmt = stmtIt.nextStatement(); - if (stmt.getObject().isResource() && possibleSubjectSet.contains((Resource)stmt.getObject())) { + if (stmt.getObject().isResource() && possibleSubjectSet.contains(stmt.getObject())) { hasAlternatePath = true; break; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaChangeListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaChangeListener.java index 47d040fc1..9304d99a7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaChangeListener.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaChangeListener.java @@ -8,7 +8,6 @@ import java.util.HashSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.openjena.riot.RiotException; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelChangedListener; @@ -17,7 +16,6 @@ import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; import edu.cornell.mannlib.vitro.webapp.servlet.setup.SimpleReasonerSetup; /** diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaModelUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaModelUtils.java index 93900a7a7..f271542e9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaModelUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaModelUtils.java @@ -95,7 +95,7 @@ public class JenaModelUtils { .getRootClasses(); for (Iterator rootClassIt = rootClasses.iterator(); rootClassIt.hasNext(); ) { - VClass rootClass = (VClass) rootClassIt.next(); + VClass rootClass = rootClassIt.next(); Individual classGroup = modelForClassgroups.createIndividual( wadf.getDefaultNamespace() + "vitroClassGroup" + rootClass.getLocalName(), classGroupClass); @@ -108,7 +108,7 @@ public class JenaModelUtils { for (Iterator childIt = myWebappDaoFactory.getVClassDao() .getAllSubClassURIs(rootClass.getURI()).iterator(); childIt.hasNext(); ) { - String childURI = (String) childIt.next(); + String childURI = childIt.next(); Resource childClass = modelForClassgroupAnnotations .getResource(childURI); if (!modelForClassgroupAnnotations.contains( diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ModelContext.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ModelContext.java index 57d835a4c..120de2b2a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ModelContext.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ModelContext.java @@ -7,84 +7,14 @@ import javax.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.ModelChangedListener; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; public class ModelContext { - private static final Log log = LogFactory.getLog(ModelContext.class); - private static final String ONT_MODEL_SELECTOR = "ontModelSelector"; - private static final String UNION_ONT_MODEL_SELECTOR = "unionOntModelSelector"; - private static final String BASE_ONT_MODEL_SELECTOR = "baseOntModelSelector"; - private static final String INFERENCE_ONT_MODEL_SELECTOR = "inferenceOntModelSelector"; - - private static final String JENA_ONT_MODEL = "jenaOntModel"; - private static final String BASE_ONT_MODEL = "baseOntModel"; - private static final String INFERENCE_ONT_MODEL = "inferenceOntModel"; - - public ModelContext() {} - - public static OntModelSelector getOntModelSelector(ServletContext ctx) { - return (OntModelSelector) ctx.getAttribute(ONT_MODEL_SELECTOR); - } - - public static void setOntModelSelector(OntModelSelector oms, ServletContext ctx) { - ctx.setAttribute(ONT_MODEL_SELECTOR, oms); - } - - public static OntModelSelector getUnionOntModelSelector(ServletContext ctx) { - return (OntModelSelector) ctx.getAttribute(UNION_ONT_MODEL_SELECTOR); - } - - public static void setUnionOntModelSelector(OntModelSelector oms, ServletContext ctx) { - ctx.setAttribute(UNION_ONT_MODEL_SELECTOR, oms); - } - - public static OntModelSelector getBaseOntModelSelector(ServletContext ctx) { - return (OntModelSelector) ctx.getAttribute(BASE_ONT_MODEL_SELECTOR); - } - - public static void setBaseOntModelSelector(OntModelSelector oms, ServletContext ctx) { - ctx.setAttribute(BASE_ONT_MODEL_SELECTOR, oms); - } - - public static OntModelSelector getInferenceOntModelSelector(ServletContext ctx) { - return (OntModelSelector) ctx.getAttribute(INFERENCE_ONT_MODEL_SELECTOR); - } - - public static void setInferenceOntModelSelector(OntModelSelector oms, ServletContext ctx) { - ctx.setAttribute(INFERENCE_ONT_MODEL_SELECTOR, oms); - } - - public static OntModel getJenaOntModel(ServletContext ctx) { - return (OntModel) ctx.getAttribute(JENA_ONT_MODEL); - } - - public static void setJenaOntModel(OntModel ontModel, ServletContext ctx) { - ctx.setAttribute(JENA_ONT_MODEL, ontModel); - } - - public static OntModel getBaseOntModel(ServletContext ctx) { - return (OntModel) ctx.getAttribute(BASE_ONT_MODEL); - } - - public static void setBaseOntModel(OntModel ontModel, ServletContext ctx) { - ctx.setAttribute(BASE_ONT_MODEL, ontModel); - } - - public static OntModel getInferenceOntModel(ServletContext ctx) { - return (OntModel) ctx.getAttribute(INFERENCE_ONT_MODEL); - } - - public static void setInferenceOntModel(OntModel ontModel, ServletContext ctx) { - ctx.setAttribute(INFERENCE_ONT_MODEL, ontModel); - } - /** * Register a listener to the models needed to get changes to: * Basic abox statemetns: @@ -113,10 +43,4 @@ public class ModelContext { } - public static OntModel getDisplayModel(ServletContext ctx){ - return(OntModel) ctx.getAttribute( DisplayVocabulary.DISPLAY_ONT_MODEL ); - } - public static void setDisplayModel(OntModel ontModel, ServletContext ctx){ - ctx.setAttribute(DisplayVocabulary.DISPLAY_ONT_MODEL,ontModel); - } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java index 1c71bcc48..b1973d45d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyDaoJena.java @@ -27,6 +27,9 @@ import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; @@ -38,6 +41,7 @@ import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDFS; +import com.hp.hpl.jena.sdb.util.Pair; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean; import edu.cornell.mannlib.vitro.webapp.beans.Individual; @@ -90,7 +94,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp p.setNamespace(op.getNameSpace()); p.setLocalName(op.getLocalName()); OntologyDao oDao=getWebappDaoFactory().getOntologyDao(); - Ontology o = (Ontology)oDao.getOntologyByURI(p.getNamespace()); + Ontology o = oDao.getOntologyByURI(p.getNamespace()); if (o==null) { if (!VitroVocabulary.vitroURI.equals(p.getNamespace())) { log.debug("propertyFromOntProperty(): no ontology object found for the namespace "+p.getNamespace()); @@ -178,7 +182,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp Statement stmt = it.nextStatement(); RDFNode obj; if( stmt != null && (obj = stmt.getObject()) != null && obj.isURIResource() ){ - Resource res = (Resource)obj.as(Resource.class); + Resource res = obj.as(Resource.class); if( res != null && res.getURI() != null ){ BaseResourceBean.RoleLevel roleFromModel = BaseResourceBean.RoleLevel.getRoleByUri(res.getURI()); if( roleFromModel != null && @@ -197,7 +201,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp Statement stmt = it.nextStatement(); RDFNode obj; if( stmt != null && (obj = stmt.getObject()) != null && obj.isURIResource() ){ - Resource res = (Resource)obj.as(Resource.class); + Resource res = obj.as(Resource.class); if( res != null && res.getURI() != null ){ BaseResourceBean.RoleLevel roleFromModel = BaseResourceBean.RoleLevel.getRoleByUri(res.getURI()); if( roleFromModel != null && @@ -229,12 +233,6 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp } return p; } - - private String stripItalics(String in) { - String out = in.replaceAll("\\",""); - out = out.replaceAll("\\<\\/i\\>",""); - return out; - } public List getAllObjectProperties() { getOntModel().enterCriticalSection(Lock.READ); @@ -257,7 +255,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp while (opIt.hasNext()) { Resource res = (Resource) opIt.next(); if ( (res.canAs(OntProperty.class)) && (!NONUSER_NAMESPACES.contains(res.getNameSpace())) ) { - props.add(propertyFromOntProperty((OntProperty)res.as(OntProperty.class))); + props.add(propertyFromOntProperty(res.as(OntProperty.class))); } } } finally { @@ -285,6 +283,64 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp getOntModel().leaveCriticalSection(); } } + + public ObjectProperty getObjectPropertyByURIAndRangeURI(String propertyURI, String rangeURI) { + ObjectProperty op = getObjectPropertyByURI(propertyURI); + if (op == null) { + return op; + } + op.setRangeVClassURI(rangeURI); + String propQuery = "PREFIX rdfs: \n" + + "PREFIX config: \n" + + "PREFIX vitro: \n" + + "SELECT ?range ?label ?group ?customForm ?displayLevel ?updateLevel WHERE { \n" + + " ?context config:configContextFor <" + propertyURI + "> . \n" + + " ?context config:qualifiedBy <" + rangeURI + "> . \n" + + " ?context config:hasConfiguration ?configuration . \n" + + " OPTIONAL { ?configuration config:propertyGroup ?group } \n" + + " OPTIONAL { ?configuration config:displayName ?label } \n" + + " OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" + + " OPTIONAL { ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" + + " OPTIONAL { ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n" + + "}"; + + Query q = QueryFactory.create(propQuery); + QueryExecution qe = QueryExecutionFactory.create(q, getOntModelSelector().getDisplayModel()); + try { + ResultSet rs = qe.execSelect(); + if (rs.hasNext()) { + QuerySolution qsoln = rs.nextSolution(); + Resource groupRes = qsoln.getResource("group"); + if (groupRes != null) { + op.setGroupURI(groupRes.getURI()); + } + Resource displayLevelRes = qsoln.getResource("displayLevel"); + if (displayLevelRes != null) { + op.setHiddenFromDisplayBelowRoleLevel( + BaseResourceBean.RoleLevel.getRoleByUri( + displayLevelRes.getURI())); + } + Resource updateLevelRes = qsoln.getResource("updateLevel"); + if (updateLevelRes != null) { + op.setProhibitedFromUpdateBelowRoleLevel( + BaseResourceBean.RoleLevel.getRoleByUri( + updateLevelRes.getURI())); + } + Literal labelLit = qsoln.getLiteral("label"); + if (labelLit != null) { + op.setDomainPublic(labelLit.getLexicalForm()); + } + Literal customFormLit = qsoln.getLiteral("customForm"); + if (customFormLit != null) { + op.setCustomEntryForm(customFormLit.getLexicalForm()); + } + } + } finally { + qe.close(); + } + return op; + } + public List getObjectPropertiesForObjectPropertyStatements(List objPropertyStmts) { if( objPropertyStmts == null || objPropertyStmts.size() < 1) return new ArrayList(); @@ -296,7 +352,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp while(it.hasNext()){ ObjectPropertyStatement objPropertyStmt = (ObjectPropertyStatement)it.next(); if (hash.containsKey(objPropertyStmt.getPropertyURI())) { - ObjectProperty p = (ObjectProperty) hash.get(objPropertyStmt.getPropertyURI()); + ObjectProperty p = hash.get(objPropertyStmt.getPropertyURI()); p.addObjectPropertyStatement(objPropertyStmt); } else { OntProperty op = getOntModel().getOntProperty(objPropertyStmt.getPropertyURI()); @@ -601,7 +657,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp while(restIt.hasNext()) { Resource restRes = restIt.next(); if (restRes.canAs(OntResource.class)) { - OntResource restOntRes = (OntResource) restRes.as(OntResource.class); + OntResource restOntRes = restRes.as(OntResource.class); smartRemove(restOntRes, ontModel); } } @@ -625,7 +681,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp while(restIt.hasNext()) { Resource restRes = restIt.next(); if (restRes.canAs(OntResource.class)) { - OntResource restOntRes = (OntResource) restRes.as(OntResource.class); + OntResource restOntRes = restRes.as(OntResource.class); smartRemove(restOntRes, ontModel); } } @@ -658,7 +714,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp while (propIt.hasNext()) { Resource res = (Resource) propIt.next(); if (res.canAs(OntProperty.class)) { - com.hp.hpl.jena.ontology.OntProperty op = (com.hp.hpl.jena.ontology.OntProperty) res.as(OntProperty.class); + com.hp.hpl.jena.ontology.OntProperty op = res.as(OntProperty.class); boolean isRoot = false; Iterator parentIt = op.listSuperProperties(); if (parentIt != null) { @@ -798,7 +854,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp PREFIXES + "\n" + "SELECT DISTINCT ?property WHERE { \n" + " ?subject ?property ?object . \n" + - " ?property a owl:ObjectProperty . \n" + +// " ?property a owl:ObjectProperty . \n" + " FILTER ( \n" + " isURI(?object) && \n" + PROPERTY_FILTERS + "\n" + @@ -844,11 +900,19 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp } protected static final String LIST_VIEW_CONFIG_FILE_QUERY_STRING = - "PREFIX display: " + - "SELECT ?property ?filename WHERE { \n" + - " ?property display:listViewConfigFile ?filename . \n" + + "PREFIX display: \n" + + "PREFIX config: \n" + + "SELECT ?property ?range ?filename WHERE { \n" + + " { ?property display:listViewConfigFile ?filename \n" + + " } UNION { \n" + + " ?lv config:listViewConfigFile ?filename . \n " + + " ?configuration config:hasListView ?lv . " + + " ?context config:hasConfiguration ?configuration . \n" + + " ?context config:configContextFor ?property . \n" + + " ?context config:qualifiedBy ?range . \n" + + " } \n" + "}"; - + protected static Query listViewConfigFileQuery = null; static { try { @@ -859,12 +923,16 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp } } - Map customListViewConfigFileMap = null; + //TODO private void addPropertyClassCombinationsToListViewMap(HashMap) + + // Map key is pair of object property and range class URI + // If range is unspecified, OWL.Thing.getURI() is used in the key. + Map, String> customListViewConfigFileMap = null; @Override public String getCustomListViewConfigFileName(ObjectProperty op) { if (customListViewConfigFileMap == null) { - customListViewConfigFileMap = new HashMap(); + customListViewConfigFileMap = new HashMap, String>(); OntModel displayModel = getOntModelSelector().getDisplayModel(); //Get all property to list view config file mappings in the system QueryExecution qexec = QueryExecutionFactory.create(listViewConfigFileQuery, displayModel); @@ -873,6 +941,10 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp while (results.hasNext()) { QuerySolution soln = results.next(); String propertyUri = soln.getResource("property").getURI(); + RDFNode rangeNode = soln.get("range"); + String rangeUri = (rangeNode != null) + ? ((Resource) rangeNode).getURI() + : OWL.Thing.getURI(); ObjectProperty prop = getObjectPropertyByURI(propertyUri); if (prop == null) { //This is a warning only if this property is the one for which we're searching @@ -883,12 +955,18 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp } } else { String filename = soln.getLiteral("filename").getLexicalForm(); - customListViewConfigFileMap.put(prop, filename); + customListViewConfigFileMap.put(new Pair(prop, rangeUri), filename); } } qexec.close(); - } - return customListViewConfigFileMap.get(op); + } + + String customListViewConfigFileName = customListViewConfigFileMap.get(new Pair(op, op.getRangeVClassURI())); + if (customListViewConfigFileName == null) { + customListViewConfigFileName = customListViewConfigFileMap.get(new Pair(op, OWL.Thing.getURI())); + } + + return customListViewConfigFileName; } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java index 84255162a..073c1189f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoJena.java @@ -99,7 +99,7 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec ClosableIterator propIt = ind.listProperties(); try { while (propIt.hasNext()) { - Statement st = (Statement) propIt.next(); + Statement st = propIt.next(); if (st.getObject().isResource() && !(NONUSER_NAMESPACES.contains(st.getPredicate().getNameSpace()))) { try { @@ -173,7 +173,7 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec try { int count = 0; while ( (opsIt.hasNext()) && ((endIndex<0) || (count constructQueryStrings, String sortDirection) { @@ -296,6 +297,9 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec QuerySolutionMap initialBindings = new QuerySolutionMap(); initialBindings.add("subject", ResourceFactory.createResource(subjectUri)); initialBindings.add("property", ResourceFactory.createResource(propertyUri)); + if (rangeUri != null) { + initialBindings.add("objectType", ResourceFactory.createResource(rangeUri)); + } // Run the SPARQL query to get the properties List> list = new ArrayList>(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoSDB.java index 7cfd99734..07565f011 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/ObjectPropertyStatementDaoSDB.java @@ -102,7 +102,7 @@ public class ObjectPropertyStatementDaoSDB extends ClosableIterator propIt = ind.listProperties(); try { while (propIt.hasNext()) { - Statement st = (Statement) propIt.next(); + Statement st = propIt.next(); if (st.getObject().isResource() && !(NONUSER_NAMESPACES.contains(st.getPredicate().getNameSpace()))) { try { ObjectPropertyStatement objPropertyStmt = new ObjectPropertyStatementImpl(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntModelSelector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntModelSelector.java index e5aa2f68b..63d4d1446 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntModelSelector.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntModelSelector.java @@ -35,13 +35,9 @@ public interface OntModelSelector { * @return OntModel containing all TBox axioms */ public OntModel getTBoxModel(); - + /** - * @param ontologyURI - * @return OntModel containing TBox axioms for the specified ontology + * @return OntModel containing all RDF statements in the Display model. */ - public OntModel getTBoxModel(String ontologyURI); - public OntModel getDisplayModel(); - } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntModelSelectorImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntModelSelectorImpl.java index 673ebdc91..a80d064f2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntModelSelectorImpl.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntModelSelectorImpl.java @@ -38,11 +38,6 @@ public class OntModelSelectorImpl implements OntModelSelector { return this.tboxModel; } - @Override - public OntModel getTBoxModel(String ontologyURI) { - return this.tboxModel; - } - @Override public OntModel getUserAccountsModel() { return this.userAccountsModel; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntologyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntologyDaoJena.java index 067a29cf2..94a5b97f0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntologyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntologyDaoJena.java @@ -2,10 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; -import java.text.Collator; import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.List; import com.hp.hpl.jena.ontology.OntModel; @@ -16,7 +14,6 @@ import com.hp.hpl.jena.util.iterator.ClosableIterator; import edu.cornell.mannlib.vitro.webapp.beans.Ontology; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; public class OntologyDaoJena extends JenaBaseDao implements OntologyDao { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java index e552e20c8..e8ac4392e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PageDaoJena.java @@ -8,7 +8,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.HashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java index d91d2dd0a..a457b607c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java @@ -30,11 +30,11 @@ import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.Syntax; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.sparql.resultset.ResultSetMem; -import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.RDFS; @@ -151,7 +151,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { List directSubproperties = getSubPropertyURIs(propertyURI); Iterator it=directSubproperties.iterator(); while(it.hasNext()){ - String uri = (String)it.next(); + String uri = it.next(); if (!subtree.contains(uri)) { subtree.add(uri); getAllSubPropertyURIs(uri,subtree); @@ -192,7 +192,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { List directSuperproperties = getSuperPropertyURIs(propertyURI,true); Iterator it=directSuperproperties.iterator(); while(it.hasNext()){ - String uri = (String)it.next(); + String uri = it.next(); if (!subtree.contains(uri)) { subtree.add(uri); getAllSuperPropertyURIs(uri,subtree); @@ -342,13 +342,13 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { if (targetProp != null) { - StmtIterator stmtIter = ontModel.listStatements((Resource) null, OWL.onProperty, (RDFNode) targetProp); + StmtIterator stmtIter = ontModel.listStatements((Resource) null, OWL.onProperty, targetProp); while (stmtIter.hasNext()) { Statement statement = stmtIter.next(); if ( statement.getSubject().canAs(OntClass.class) ) { - classURISet.addAll(getRelatedClasses((OntClass) statement.getSubject().as(OntClass.class))); + classURISet.addAll(getRelatedClasses(statement.getSubject().as(OntClass.class))); } else { log.warn("getClassesWithRestrictionOnProperty: Unexpected use of onProperty: it is not applied to a class"); } @@ -503,7 +503,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { List allTypes = ind.getVClasses(false); // include indirect types Set allSuperclassURIs = new HashSet(); - + for (VClass type : allTypes) { String classURI = type.getURI(); if (classURI != null) { @@ -661,7 +661,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { // TODO: check if restriction is something like // maxCardinality 0 or allValuesFrom owl:Nothing, // in which case the property is NOT applicable! - Restriction rest = (Restriction) relatedClass.as(Restriction.class); + Restriction rest = relatedClass.as(Restriction.class); OntProperty onProperty = rest.getOnProperty(); if (onProperty != null) { Resource[] ranges = new Resource[2]; @@ -707,55 +707,27 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { // make the PropertyInstance objects for (String propertyURI : applicableProperties.keySet()) { - OntProperty op = ontModel - .getOntProperty(propertyURI); - if (op == null) { - continue; - } - String domainURIStr = getURIStr(op.getDomain()); - Resource[] foundRanges = applicableProperties.get(propertyURI); - Resource rangeRes = (foundRanges[0] != null) - ? foundRanges[0] - : (op.getRange() == null && foundRanges[1] != null) - ? foundRanges[1] - : op.getRange(); - PropertyInstance pi = new PropertyInstance(); - if (rangeRes != null) { - String rangeClassURI; - if (rangeRes.isAnon()) { - rangeClassURI = PSEUDO_BNODE_NS + rangeRes.getId() - .toString(); - } else { - rangeClassURI = (String) rangeRes.getURI(); - } - pi.setRangeClassURI(rangeClassURI); - VClass range = getWebappDaoFactory().getVClassDao() - .getVClassByURI(rangeClassURI); - if (range == null) { - range = new VClass(); - range.setURI(rangeClassURI); - range.setName(range.getLocalName()); - } - pi.setRangeClassName(range.getName()); - } else { - pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above - } - pi.setDomainClassURI(domainURIStr); - VClass domain = getWebappDaoFactory().getVClassDao() - .getVClassByURI(domainURIStr); - if (domain == null) { - domain = new VClass(); - domain.setURI(domainURIStr); - domain.setName(domain.getLocalName()); - } - pi.setDomainClassName(domain.getName()); - pi.setSubjectSide(true); - pi.setPropertyURI(op.getURI()); - pi.setPropertyName(getLabelOrId(op)); // TODO - pi.setRangePublic(getLabelOrId(op)); - pi.setDomainPublic(getLabelOrId(op)); - propInsts.add(pi); - } + OntProperty op = ontModel + .getOntProperty(propertyURI); + if (op == null) { + continue; + } + Resource[] foundRanges = applicableProperties.get(propertyURI); + Resource rangeRes = (foundRanges[0] != null) + ? foundRanges[0] + : (op.getRange() == null && foundRanges[1] != null) + ? foundRanges[1] + : op.getRange(); + propInsts.add(getPropInstForPropertyAndRange(op, rangeRes, applicableProperties)); + List additionalFauxSubpropertyRangeURIs = getAdditionalFauxSubpropertyRangeURIsForPropertyURI(propertyURI); + for (String rangeURI : additionalFauxSubpropertyRangeURIs) { + if (getWebappDaoFactory().getVClassDao().isSubClassOf(rangeURI, rangeRes.getURI())) { + propInsts.add(getPropInstForPropertyAndRange( + op, ResourceFactory.createResource(rangeURI), applicableProperties)); + } + } + } + } finally { ontModel.leaveCriticalSection(); } @@ -763,6 +735,72 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { return propInsts; } + + private PropertyInstance getPropInstForPropertyAndRange(OntProperty op, Resource rangeRes, + Map applicableProperties) { + PropertyInstance pi = new PropertyInstance(); + String domainURIStr = getURIStr(op.getDomain()); + if (rangeRes != null) { + String rangeClassURI; + if (rangeRes.isAnon()) { + rangeClassURI = PSEUDO_BNODE_NS + rangeRes.getId() + .toString(); + } else { + rangeClassURI = rangeRes.getURI(); + } + pi.setRangeClassURI(rangeClassURI); + VClass range = getWebappDaoFactory().getVClassDao() + .getVClassByURI(rangeClassURI); + if (range == null) { + range = new VClass(); + range.setURI(rangeClassURI); + range.setName(range.getLocalName()); + } + pi.setRangeClassName(range.getName()); + } else { + pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above + } + pi.setDomainClassURI(domainURIStr); + VClass domain = getWebappDaoFactory().getVClassDao() + .getVClassByURI(domainURIStr); + if (domain == null) { + domain = new VClass(); + domain.setURI(domainURIStr); + domain.setName(domain.getLocalName()); + } + pi.setDomainClassName(domain.getName()); + pi.setSubjectSide(true); + pi.setPropertyURI(op.getURI()); + pi.setPropertyName(getLabelOrId(op)); // TODO + pi.setRangePublic(getLabelOrId(op)); + pi.setDomainPublic(getLabelOrId(op)); + return pi; + } + + private List getAdditionalFauxSubpropertyRangeURIsForPropertyURI(String propertyURI) { + List rangeURIs = new ArrayList(); + String propQuery = "PREFIX rdfs: \n" + + "PREFIX config: \n" + + "PREFIX vitro: \n" + + "SELECT ?range WHERE { \n" + + " ?context config:configContextFor <" + propertyURI + "> . \n" + + " ?context config:qualifiedBy ?range . \n" + + "}"; + + Query q = QueryFactory.create(propQuery); + QueryExecution qe = QueryExecutionFactory.create(q, getOntModelSelector().getDisplayModel()); + try { + ResultSet rs = qe.execSelect(); + while (rs.hasNext()) { + QuerySolution qsoln = rs.nextSolution(); + Resource rangeRes = qsoln.getResource("range"); + rangeURIs.add(rangeRes.getURI()); + } + } finally { + qe.close(); + } + return rangeURIs; + } private String getURIStr(Resource res) { String URIStr; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyGroupDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyGroupDaoJena.java index 6bb652094..2d713d3f3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyGroupDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyGroupDaoJena.java @@ -4,7 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ListIterator; @@ -16,7 +15,6 @@ import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; import com.hp.hpl.jena.ontology.Individual; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Resource; @@ -26,7 +24,6 @@ import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.util.iterator.ClosableIterator; import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; @@ -228,7 +225,7 @@ public class PropertyGroupDaoJena extends JenaBaseDao implements PropertyGroupDa try { Individual groupInd = ontModel.getIndividual(group.getURI()); try { - groupInd.setLabel(group.getName(), (String) getDefaultLanguage()); + groupInd.setLabel(group.getName(), getDefaultLanguage()); } catch (Exception e) { log.error("error updating name for "+groupInd.getURI()); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyInstanceDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyInstanceDaoJena.java index b1517700d..e03271273 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyInstanceDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyInstanceDaoJena.java @@ -7,27 +7,18 @@ import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Set; -import com.hp.hpl.jena.ontology.ObjectProperty; -import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntProperty; -import com.hp.hpl.jena.ontology.Restriction; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.RDF; -import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; @@ -35,7 +26,6 @@ import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance; import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstanceIface; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao; -import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualDeletionEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent; public class PropertyInstanceDaoJena extends PropertyDaoJena implements @@ -58,7 +48,7 @@ public class PropertyInstanceDaoJena extends PropertyDaoJena implements Property pred = tboxModel.getProperty(propertyURI); OntProperty invPred = null; if (pred.canAs(OntProperty.class)) { - invPred = ((OntProperty)pred.as(OntProperty.class)).getInverse(); + invPred = pred.as(OntProperty.class).getInverse(); } Resource objRes = ontModel.getResource(objectURI); if ( (subjRes != null) && (pred != null) && (objRes != null) ) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDataset.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDataset.java index 61cd2b58c..6517b495f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDataset.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDataset.java @@ -8,7 +8,6 @@ import java.util.Iterator; import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.sparql.core.DatasetGraph; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDatasetGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDatasetGraph.java index ca0dfa80f..23f9aaff2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDatasetGraph.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceDatasetGraph.java @@ -10,10 +10,6 @@ import java.util.List; import com.hp.hpl.jena.graph.Graph; import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.graph.Triple; -import com.hp.hpl.jena.query.Query; -import com.hp.hpl.jena.query.QueryExecution; -import com.hp.hpl.jena.query.QueryExecutionFactory; -import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.shared.Lock; @@ -21,7 +17,6 @@ import com.hp.hpl.jena.shared.LockMRSW; import com.hp.hpl.jena.sparql.core.DatasetGraph; import com.hp.hpl.jena.sparql.core.Quad; import com.hp.hpl.jena.sparql.resultset.JSONInput; -import com.hp.hpl.jena.sparql.resultset.ResultSetMem; import com.hp.hpl.jena.sparql.util.Context; import com.hp.hpl.jena.util.iterator.SingletonIterator; import com.hp.hpl.jena.util.iterator.WrappedIterator; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphBulkUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphBulkUpdater.java index 4cf036c2a..8a1170204 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphBulkUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphBulkUpdater.java @@ -4,7 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.InputStream; import java.util.Iterator; import java.util.List; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceModelMaker.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceModelMaker.java index de822941c..004eadbb9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceModelMaker.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceModelMaker.java @@ -305,7 +305,7 @@ public class RDFServiceModelMaker implements ModelMaker { List graphNames = rdfService.getGraphURIs(); Iterator nameIt = graphNames.iterator(); while (nameIt.hasNext()) { - String name = (String) nameIt.next(); + String name = nameIt.next(); metadataModel.add(dbResource,metadataModel.getProperty( HAS_NAMED_MODEL_URI),name); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SimpleOntModelSelector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SimpleOntModelSelector.java index 7564dc891..562b45f2b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SimpleOntModelSelector.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SimpleOntModelSelector.java @@ -47,6 +47,7 @@ public class SimpleOntModelSelector implements OntModelSelector { this.applicationMetadataModel = ontModel; this.tboxModel = ontModel; this.userAccountsModel = ontModel; + this.displayModel = ontModel; } public void setABoxModel(OntModel m) { @@ -89,26 +90,27 @@ public class SimpleOntModelSelector implements OntModelSelector { this.fullModel = m; } + @Override public OntModel getABoxModel() { return aboxModel; } + @Override public OntModel getApplicationMetadataModel() { return applicationMetadataModel; } + @Override public OntModel getFullModel() { return fullModel; } + @Override public OntModel getTBoxModel() { return tboxModel; } - public OntModel getTBoxModel(String ontologyURI) { - return tboxModel; - } - + @Override public OntModel getUserAccountsModel() { return userAccountsModel; } @@ -120,6 +122,7 @@ public class SimpleOntModelSelector implements OntModelSelector { public void setDisplayModel(OntModel displayModel) { this.displayModel = displayModel; } + @Override public OntModel getDisplayModel(){ return this.displayModel; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java index e26729272..8c4a20e77 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java @@ -66,15 +66,21 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.PelletListener; public class VClassDaoJena extends JenaBaseDao implements VClassDao { protected static final Log log = LogFactory.getLog(VClassDaoJena.class); + private boolean isUnderlyingStoreReasoned = false; - public VClassDaoJena(WebappDaoFactoryJena wadf) { + public VClassDaoJena(WebappDaoFactoryJena wadf, boolean isUnderlyingStoreReasoned) { super(wadf); + this.isUnderlyingStoreReasoned = isUnderlyingStoreReasoned; } @Override protected OntModel getOntModel() { return getOntModelSelector().getTBoxModel(); } + + protected boolean isUnderlyingStoreReasoned() { + return this.isUnderlyingStoreReasoned; + } /* ************************************************** */ @@ -98,11 +104,11 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { labelStr += "some values from "; } if (fillerRes.canAs(OntClass.class)) { - OntClass avf = (OntClass) fillerRes.as(OntClass.class); + OntClass avf = fillerRes.as(OntClass.class); labelStr += getLabelForClass(avf,withPrefix,forPickList); } else { try { - labelStr += getLabelOrId( (OntResource) fillerRes.as(OntResource.class)); + labelStr += getLabelOrId(fillerRes.as(OntResource.class)); } catch (Exception e) { labelStr += "???"; } @@ -113,9 +119,9 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { RDFNode fillerNode = hvRest.getHasValue(); try { if (fillerNode.isResource()) { - labelStr += getLabelOrId((OntResource)fillerNode.as(OntResource.class)); + labelStr += getLabelOrId(fillerNode.as(OntResource.class)); } else { - labelStr += ((Literal) fillerNode.as(Literal.class)).getLexicalForm(); + labelStr += fillerNode.as(Literal.class).getLexicalForm(); } } catch (Exception e) { labelStr += "???"; @@ -138,10 +144,10 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { String labelStr = "("; if (cls.isComplementClass()) { labelStr += "not "; - ComplementClass ccls = (ComplementClass) cls.as(ComplementClass.class); + ComplementClass ccls = cls.as(ComplementClass.class); labelStr += getLabelForClass(ccls.getOperand(),withPrefix,forPickList); } else if (cls.isIntersectionClass()) { - IntersectionClass icls = (IntersectionClass) cls.as(IntersectionClass.class); + IntersectionClass icls = cls.as(IntersectionClass.class); for (Iterator operandIt = icls.listOperands(); operandIt.hasNext();) { OntClass operand = (OntClass) operandIt.next(); labelStr += getLabelForClass(operand,withPrefix,forPickList); @@ -150,7 +156,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { } } } else if (cls.isUnionClass()) { - UnionClass icls = (UnionClass) cls.as(UnionClass.class); + UnionClass icls = cls.as(UnionClass.class); for (Iterator operandIt = icls.listOperands(); operandIt.hasNext();) { OntClass operand = (OntClass) operandIt.next(); labelStr += getLabelForClass(operand,withPrefix,forPickList); @@ -169,7 +175,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { } else { if (withPrefix || forPickList) { OntologyDao oDao=getWebappDaoFactory().getOntologyDao(); - Ontology o = (Ontology)oDao.getOntologyByURI(cls.getNameSpace()); + Ontology o = oDao.getOntologyByURI(cls.getNameSpace()); if (o!=null) { if (withPrefix) { return(o.getPrefix()==null?(o.getName()==null?"unspec:"+getLabelOrId(cls):o.getName()+":"+getLabelOrId(cls)):o.getPrefix()+":"+getLabelOrId(cls)); @@ -208,7 +214,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { while(restIt.hasNext()) { Resource restRes = restIt.next(); if (restRes.canAs(OntResource.class)) { - OntResource restOntRes = (OntResource) restRes.as(OntResource.class); + OntResource restOntRes = restRes.as(OntResource.class); smartRemove(restOntRes, ontModel); } } @@ -216,7 +222,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { while(restIt.hasNext()) { Resource restRes = restIt.next(); if (restRes.canAs(OntResource.class)) { - OntResource restOntRes = (OntResource) restRes.as(OntResource.class); + OntResource restOntRes = restRes.as(OntResource.class); smartRemove(restOntRes, ontModel); } } @@ -400,7 +406,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { List directSubclasses = getSubClassURIs(classURI); Iterator it=directSubclasses.iterator(); while(it.hasNext()){ - String uri = (String)it.next(); + String uri = it.next(); if (!subtree.contains(uri)) { subtree.add(uri); getAllSubClassURIs(uri,subtree); @@ -412,18 +418,15 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { List superclassURIs = null; - //String infersTypes = getWebappDaoFactory().getProperties().get("infersTypes"); - //if ("true".equalsIgnoreCase(infersTypes)) { - - PelletListener pl = getWebappDaoFactory().getPelletListener(); - if (pl != null && pl.isConsistent() && !pl.isInErrorState() && !pl.isReasoning()) { + if (isUnderlyingStoreReasoned()) { superclassURIs = new ArrayList(); - OntClass cls = getOntClass(getOntModel(),classURI); - StmtIterator superClassIt = getOntModel().listStatements(cls,RDFS.subClassOf,(RDFNode)null); + Resource cls = ResourceFactory.createResource(classURI); + StmtIterator superClassIt = getOntModel().listStatements( + cls, RDFS.subClassOf, (RDFNode)null); while (superClassIt.hasNext()) { Statement stmt = superClassIt.nextStatement(); if (stmt.getObject().canAs(OntResource.class)) { - OntResource superRes = (OntResource) stmt.getObject().as(OntResource.class); + OntResource superRes = stmt.getObject().as(OntResource.class); String test = getClassURIStr(superRes); superclassURIs.add(test); } @@ -442,7 +445,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { List directSuperclasses = getSuperClassURIs(classURI, true); Iterator it=directSuperclasses.iterator(); while(it.hasNext()){ - String uri = (String)it.next(); + String uri = it.next(); if (!subtree.contains(uri)) { subtree.add(uri); getAllSuperClassURIs(uri,subtree); @@ -459,7 +462,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { while (classIt.hasNext()) { try { Individual classInd = classIt.next(); - OntClass cls = (OntClass) classInd.as(OntClass.class); + OntClass cls = classInd.as(OntClass.class); if (!cls.isAnon() && !(NONUSER_NAMESPACES.contains(cls.getNameSpace()))) { classes.add(new VClassJena(cls,getWebappDaoFactory())); } @@ -724,17 +727,17 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { Statement axStmt = (Statement) axStmtIt.next(); OntResource subjOntRes = null; if (axStmt.getSubject().canAs(OntResource.class)) { - subjOntRes = (OntResource) axStmt.getSubject().as(OntResource.class); + subjOntRes = axStmt.getSubject().as(OntResource.class); } if ( (subjOntRes != null) && (subjSuperclasses.contains(getClassURIStr(subjOntRes))) && (axStmt.getPredicate().equals(RDFS.subClassOf) || (axStmt.getPredicate().equals(OWL.equivalentClass))) ) { if (restRes.canAs(AllValuesFromRestriction.class)) { - AllValuesFromRestriction avfRest = (AllValuesFromRestriction) restRes.as(AllValuesFromRestriction.class); + AllValuesFromRestriction avfRest = restRes.as(AllValuesFromRestriction.class); Resource avf = avfRest.getAllValuesFrom(); if (avf.canAs(OntClass.class)) { - superclass = (OntClass) avfRest.getAllValuesFrom().as(OntClass.class); + superclass = avfRest.getAllValuesFrom().as(OntClass.class); } } } @@ -766,12 +769,9 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { } if (superVclass != null) { vClasses.add(superVclass); - String isInferencing = getWebappDaoFactory().getProperties().get("infersTypes"); // if this model infers types based on the taxonomy, adding the subclasses will only // waste time for no benefit - PelletListener pl = getWebappDaoFactory().getPelletListener(); - if (pl == null || !pl.isConsistent() || pl.isInErrorState() || pl.isReasoning() - || isInferencing == null || "false".equalsIgnoreCase(isInferencing)) { + if (!isUnderlyingStoreReasoned()) { Iterator classURIs = getAllSubClassURIs(getClassURIStr(superclass)).iterator(); while (classURIs.hasNext()) { String classURI = (String) classURIs.next(); @@ -818,8 +818,8 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { while (annotIt.hasNext()) { try { Statement annot = (Statement) annotIt.next(); - Resource cls = (Resource) annot.getSubject(); - VClass vcw = (VClass) getVClassByURI(cls.getURI()); + Resource cls = annot.getSubject(); + VClass vcw = getVClassByURI(cls.getURI()); if (vcw != null) { boolean classIsInstantiated = false; if (getIndividualCount) { @@ -926,7 +926,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { OntClass ontCls = ontModel.createClass(cls.getURI()); try { if (cls.getName() != null && cls.getName().length() > 0) { - ontCls.setLabel(cls.getName(), (String) getDefaultLanguage()); + ontCls.setLabel(cls.getName(), getDefaultLanguage()); } else { ontCls.removeAll(RDFS.label); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoSDB.java index c177161fa..0e97bd923 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoSDB.java @@ -2,7 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; -import java.util.List; import com.hp.hpl.jena.ontology.AnnotationProperty; import com.hp.hpl.jena.ontology.OntClass; @@ -11,15 +10,15 @@ import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; -import com.hp.hpl.jena.query.QuerySolution; -import com.hp.hpl.jena.query.QuerySolutionMap; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.Syntax; import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.vocabulary.RDF; @@ -36,8 +35,8 @@ public class VClassDaoSDB extends VClassDaoJena { public VClassDaoSDB(DatasetWrapperFactory datasetWrapperFactory, SDBDatasetMode datasetMode, - WebappDaoFactoryJena wadf) { - super(wadf); + WebappDaoFactoryJena wadf, boolean isUnderlyingStoreReasoned) { + super(wadf, isUnderlyingStoreReasoned); this.dwf = datasetWrapperFactory; this.datasetMode = datasetMode; } @@ -57,15 +56,15 @@ public class VClassDaoSDB extends VClassDaoJena { try { if ((group != null) && (group.getURI() != null)) { Resource groupRes = ResourceFactory.createResource(group.getURI()); - AnnotationProperty inClassGroup = getOntModel().getAnnotationProperty(VitroVocabulary.IN_CLASSGROUP); + Property inClassGroup = ResourceFactory.createProperty(VitroVocabulary.IN_CLASSGROUP); if (inClassGroup != null) { - ClosableIterator annotIt = getOntModel().listStatements((OntClass)null,inClassGroup,groupRes); + StmtIterator annotIt = getOntModel().listStatements((Resource)null,inClassGroup, groupRes); try { while (annotIt.hasNext()) { try { Statement annot = (Statement) annotIt.next(); - Resource cls = (Resource) annot.getSubject(); - VClass vcw = (VClass) getVClassByURI(cls.getURI()); + Resource cls = annot.getSubject(); + VClass vcw = getVClassByURI(cls.getURI()); if (vcw != null) { boolean classIsInstantiated = false; if (getIndividualCount) { @@ -95,7 +94,7 @@ public class VClassDaoSDB extends VClassDaoJena { Model aboxModel = getOntModelSelector().getABoxModel(); aboxModel.enterCriticalSection(Lock.READ); try { - ClosableIterator countIt = aboxModel.listStatements(null,RDF.type,cls); + StmtIterator countIt = aboxModel.listStatements(null,RDF.type,cls); try { if (countIt.hasNext()) { classIsInstantiated = true; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupCache.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupCache.java index cf8387a06..4be2ed142 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupCache.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupCache.java @@ -4,14 +4,13 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; +import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -33,8 +32,9 @@ import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; -import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; +import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering; @@ -176,12 +176,7 @@ public class VClassGroupCache implements IndexingEventListener { } protected VClassGroupDao getVCGDao() { - WebappDaoFactory wdf = (WebappDaoFactory) context.getAttribute("webappDaoFactory"); - if (wdf == null) { - log.error("Cannot get webappDaoFactory from context"); - return null; - } else - return wdf.getVClassGroupDao(); + return ModelAccess.on(context).getWebappDaoFactory().getVClassGroupDao(); } public void doSynchronousRebuild(){ @@ -234,6 +229,14 @@ public class VClassGroupCache implements IndexingEventListener { return (VClassGroupCache) sc.getAttribute(ATTRIBUTE_NAME); } + /** + * Use getVClassGroups(HttpServletRequest) to get a language-aware image of + * the cached groups and classes. + */ + public static VClassGroupsForRequest getVClassGroups(HttpServletRequest req) { + return new VClassGroupsForRequest(req, getVClassGroupCache(req.getSession().getServletContext())); + } + /** * Method that rebuilds the cache. This will use a WebappDaoFactory, * a SolrSever and maybe a ProhibitedFromSearch from the cache.context. @@ -244,12 +247,9 @@ public class VClassGroupCache implements IndexingEventListener { */ protected static void rebuildCacheUsingSolr( VClassGroupCache cache ) throws SolrServerException{ long start = System.currentTimeMillis(); - WebappDaoFactory wdFactory = (WebappDaoFactory) cache.context.getAttribute("webappDaoFactory"); - if (wdFactory == null){ - log.error("Unable to rebuild cache: could not get 'webappDaoFactory' from Servletcontext"); - return; - } - SolrServer solrServer = (SolrServer)cache.context.getAttribute(SolrSetup.SOLR_SERVER); + WebappDaoFactory wdFactory = ModelAccess.on(cache.context).getWebappDaoFactory(); + + SolrServer solrServer = (SolrServer)cache.context.getAttribute(SolrSetup.SOLR_SERVER); if( solrServer == null){ log.error("Unable to rebuild cache: could not get solrServer from ServletContext"); return; @@ -497,7 +497,7 @@ public class VClassGroupCache implements IndexingEventListener { } else if(VitroVocabulary.DISPLAY_RANK.equals(stmt.getPredicate().getURI())){ requestCacheUpdate(); } else { - OntModel jenaOntModel = ModelContext.getJenaOntModel(context); + OntModel jenaOntModel = ModelAccess.on(context).getJenaOntModel(); if( isClassNameChange(stmt, jenaOntModel) ) { requestCacheUpdate(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupDaoJena.java index d45fa222e..37bcf9434 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassGroupDaoJena.java @@ -14,11 +14,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; -import com.hp.hpl.jena.ontology.DatatypeProperty; import com.hp.hpl.jena.ontology.Individual; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; @@ -32,7 +30,6 @@ import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.InsertException; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch; @@ -82,7 +79,7 @@ public class VClassGroupDaoJena extends JenaBaseDao implements VClassGroupDao { ClosableIterator groupIt = getOntModel().listIndividuals(CLASSGROUP); try { while (groupIt.hasNext()) { - Individual groupInd = (Individual) groupIt.next(); + Individual groupInd = groupIt.next(); VClassGroup group = groupFromGroupIndividual(groupInd); if (group!=null) { groups.add(group); @@ -94,7 +91,7 @@ public class VClassGroupDaoJena extends JenaBaseDao implements VClassGroupDao { Collections.sort(groups); Iterator groupsIt = groups.iterator(); while (groupsIt.hasNext()) { - VClassGroup group = (VClassGroup) groupsIt.next(); + VClassGroup group = groupsIt.next(); map.put(group.getPublicName(), group); } return map; @@ -140,7 +137,7 @@ public class VClassGroupDaoJena extends JenaBaseDao implements VClassGroupDao { ClosableIterator groupIt = getOntModel().listIndividuals(CLASSGROUP); try { while (groupIt.hasNext()) { - Individual grp = (Individual) groupIt.next(); + Individual grp = groupIt.next(); VClassGroup vgrp = groupFromGroupIndividual(grp); if (vgrp != null) { groups.add(vgrp); @@ -247,7 +244,7 @@ public class VClassGroupDaoJena extends JenaBaseDao implements VClassGroupDao { int removedGroupsCount = 0; ListIterator it = groups.listIterator(); while(it.hasNext()){ - VClassGroup group = (VClassGroup) it.next(); + VClassGroup group = it.next(); List classes = group.getVitroClassList(); if( classes == null || classes.size() < 1 ){ removedGroupsCount++; @@ -283,7 +280,7 @@ public class VClassGroupDaoJena extends JenaBaseDao implements VClassGroupDao { try { Individual groupInd = ontModel.getIndividual(vcg.getURI()); try { - groupInd.setLabel(vcg.getPublicName(), (String) getDefaultLanguage()); + groupInd.setLabel(vcg.getPublicName(), getDefaultLanguage()); } catch (Exception e) { log.error("error updating name for "+groupInd.getURI()); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassJena.java index 1715eeec9..c4db19dd2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassJena.java @@ -324,7 +324,7 @@ public class VClassJena extends VClass { Statement stmt = it.nextStatement(); RDFNode obj; if( stmt != null && (obj = stmt.getObject()) != null && obj.isURIResource() ){ - Resource res = (Resource)obj.as(Resource.class); + Resource res = obj.as(Resource.class); if( res != null && res.getURI() != null ){ BaseResourceBean.RoleLevel roleFromModel = BaseResourceBean.RoleLevel.getRoleByUri(res.getURI()); if( roleFromModel != null && @@ -358,7 +358,7 @@ public class VClassJena extends VClass { Statement stmt = it.nextStatement(); RDFNode obj; if( stmt != null && (obj = stmt.getObject()) != null && obj.isURIResource() ){ - Resource res = (Resource)obj.as(Resource.class); + Resource res = obj.as(Resource.class); if( res != null && res.getURI() != null ){ BaseResourceBean.RoleLevel roleFromModel = BaseResourceBean.RoleLevel.getRoleByUri(res.getURI()); if( roleFromModel != null && diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaModelMaker.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaModelMaker.java index d2ed5b30f..1f4c087cd 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaModelMaker.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaModelMaker.java @@ -27,6 +27,7 @@ import com.hp.hpl.jena.util.iterator.ExtendedIterator; import com.hp.hpl.jena.util.iterator.WrappedIterator; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; /** @@ -311,28 +312,11 @@ public class VitroJenaModelMaker implements ModelMaker { private Model getSpecialModel(String modelName) { if (request != null) { if ("vitro:jenaOntModel".equals(modelName)) { - Object sessionOntModel = request.getSession().getAttribute("jenaOntModel"); - if (sessionOntModel != null && sessionOntModel instanceof OntModel) { - log.debug("Returning jenaOntModel from session"); - return (OntModel) sessionOntModel; - } else { - log.debug("Returning jenaOntModel from context"); - return (OntModel) request.getSession().getServletContext().getAttribute("jenaOntModel"); - } + return ModelAccess.on(request.getSession()).getJenaOntModel(); } else if ("vitro:baseOntModel".equals(modelName)) { - Object sessionOntModel = request.getSession().getAttribute("baseOntModel"); - if (sessionOntModel != null && sessionOntModel instanceof OntModel) { - return (OntModel) sessionOntModel; - } else { - return (OntModel) request.getSession().getServletContext().getAttribute("baseOntModel"); - } + return ModelAccess.on(request.getSession()).getBaseOntModel(); } else if ("vitro:inferenceOntModel".equals(modelName)) { - Object sessionOntModel = request.getSession().getAttribute("inferenceOntModel"); - if (sessionOntModel != null && sessionOntModel instanceof OntModel) { - return (OntModel) sessionOntModel; - } else { - return (OntModel) request.getSession().getServletContext().getAttribute("inferenceOntModel"); - } + return ModelAccess.on(request.getSession()).getInferenceOntModel(); } else { return null; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaSpecialModelMaker.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaSpecialModelMaker.java index 4dd2cfcc3..58247d3e8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaSpecialModelMaker.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaSpecialModelMaker.java @@ -2,21 +2,19 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; -import java.util.HashMap; - import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.graph.GraphMaker; -import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelMaker; import com.hp.hpl.jena.rdf.model.ModelReader; -import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.util.iterator.ExtendedIterator; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; + /** * Wraps a model maker and returns Models from the servlet context when * certain model URIs are requested @@ -118,28 +116,11 @@ public class VitroJenaSpecialModelMaker implements ModelMaker { private Model getSpecialModel(String modelName) { if (request != null) { if ("vitro:jenaOntModel".equals(modelName)) { - Object sessionOntModel = request.getSession().getAttribute("jenaOntModel"); - if (sessionOntModel != null && sessionOntModel instanceof OntModel) { - log.debug("Returning jenaOntModel from session"); - return (OntModel) sessionOntModel; - } else { - log.debug("Returning jenaOntModel from context"); - return (OntModel) request.getSession().getServletContext().getAttribute("jenaOntModel"); - } + return ModelAccess.on(request.getSession()).getJenaOntModel(); } else if ("vitro:baseOntModel".equals(modelName)) { - Object sessionOntModel = request.getSession().getAttribute("baseOntModel"); - if (sessionOntModel != null && sessionOntModel instanceof OntModel) { - return (OntModel) sessionOntModel; - } else { - return (OntModel) request.getSession().getServletContext().getAttribute("baseOntModel"); - } + return ModelAccess.on(request.getSession()).getBaseOntModel(); } else if ("vitro:inferenceOntModel".equals(modelName)) { - Object sessionOntModel = request.getSession().getAttribute("inferenceOntModel"); - if (sessionOntModel != null && sessionOntModel instanceof OntModel) { - return (OntModel) sessionOntModel; - } else { - return (OntModel) request.getSession().getServletContext().getAttribute("inferenceOntModel"); - } + return ModelAccess.on(request.getSession()).getInferenceOntModel(); } else { return null; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroModelSource.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroModelSource.java index 2366777cb..d41df3011 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroModelSource.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroModelSource.java @@ -9,7 +9,8 @@ import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelReader; import com.hp.hpl.jena.rdf.model.ModelSource; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; /** * ModelSource that will handle specially named Vitro models such @@ -106,15 +107,15 @@ public class VitroModelSource implements ModelSource { private Model getNamedModel( ModelName pmn ){ switch( pmn ){ case ABOX: - return (Model) context.getAttribute("jenaOntModel"); + return ModelAccess.on(context).getJenaOntModel(); case TBOX: return (Model) context.getAttribute("tboxmodel???"); case DISPLAY: - return (Model) context.getAttribute(DisplayVocabulary.DISPLAY_ONT_MODEL ); + return ModelAccess.on(context).getDisplayModel(); case DISPLAY_TBOX: - return (Model) context.getAttribute(DisplayVocabulary.CONTEXT_DISPLAY_TBOX); + return ModelAccess.on(context).getOntModel(ModelID.DISPLAY_TBOX); case DISPLAY_DISPLAY: - return (Model) context.getAttribute(DisplayVocabulary.CONTEXT_DISPLAY_DISPLAY); + return ModelAccess.on(context).getOntModel(ModelID.DISPLAY_DISPLAY); case USER_ACCOUNTS: throw new IllegalArgumentException("getNamedModel() Does not yet handle USER_ACCOUNTS"); default: diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java index f519824a1..143f93c61 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java @@ -11,7 +11,6 @@ import java.util.Set; import com.hp.hpl.jena.iri.IRI; import com.hp.hpl.jena.iri.IRIFactory; -import com.hp.hpl.jena.iri.Violation; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.ontology.OntResource; @@ -184,7 +183,7 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { IRI iri = factory.create( uriStr ); if (iri.hasViolation(false) ) { validURI = false; - errorMsg += ((Violation)iri.violations(false).next()) + errorMsg += (iri.violations(false).next()) .getShortMessage() + " "; } else if (checkUniqueness) { OntModel ontModel = ontModelSelector.getFullModel(); @@ -377,7 +376,7 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { protected VClassDao vClassDao = null; public VClassDao getVClassDao() { if( vClassDao == null ) - vClassDao = new VClassDaoJena(this); + vClassDao = new VClassDaoJena(this, config.isUnderlyingStoreReasoned()); return vClassDao; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java index de66561a8..2ca1c9f77 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactorySDB.java @@ -91,7 +91,7 @@ public class WebappDaoFactorySDB extends WebappDaoFactoryJena { if (vClassDao != null) return vClassDao; else - return vClassDao = new VClassDaoSDB(dwf, datasetMode, this); + return vClassDao = new VClassDaoSDB(dwf, datasetMode, this, config.isUnderlyingStoreReasoned()); } public WebappDaoFactory getUserAwareDaoFactory(String userURI) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/ObjectPropertyStatementPatternFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/ObjectPropertyStatementPatternFactory.java index ad7ac82f8..57fb8f900 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/ObjectPropertyStatementPatternFactory.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/ObjectPropertyStatementPatternFactory.java @@ -2,15 +2,9 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena.pellet; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.Resource; -import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.ObjectPropertyStatementPattern; - public class ObjectPropertyStatementPatternFactory { //private static Set patternSet = new HashSet(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java index 2a2e1fda1..58be08c6d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java @@ -320,9 +320,9 @@ public class PelletListener implements ModelChangedListener { try { if ( ( ((Resource)stmt.getObject()).equals(RDFS.Resource) ) ) { reject = true; - } else if ( ( ((Resource)stmt.getSubject()).equals(OWL.Nothing) ) ) { + } else if ( ( stmt.getSubject().equals(OWL.Nothing) ) ) { reject = true; - } else if ( ( ((Resource)stmt.getObject()).equals(OWL.Nothing) ) ) { + } else if ( ( stmt.getObject().equals(OWL.Nothing) ) ) { reject = true; } } catch (Exception e) {} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dwr/EntityDWR.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dwr/EntityDWR.java index d04f44d9a..c3872f70f 100755 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dwr/EntityDWR.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dwr/EntityDWR.java @@ -2,10 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.dwr; -import java.util.ArrayList; import java.util.Collection; -import java.util.LinkedList; -import java.util.List; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -18,7 +15,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.dao.InsertException; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; /** This is a class to support Direct Web Remoting(DWR) in @@ -31,7 +28,7 @@ public class EntityDWR { public EntityDWR(){ WebContext ctx = WebContextFactory.get(); ServletContext sc= ctx.getServletContext(); - entityWADao = ((WebappDaoFactory)sc.getAttribute("webappDaoFactory")).getIndividualDao(); + entityWADao = ModelAccess.on(sc).getWebappDaoFactory().getIndividualDao(); } /** diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java index a88aa24b4..45c5deb58 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/EditConfigurationUtils.java @@ -14,15 +14,17 @@ import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfigurationLoader; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo; @@ -52,6 +54,14 @@ public class EditConfigurationUtils { return vreq.getParameter("objectUri"); } + public static String getRangeUri(VitroRequest vreq) { + return vreq.getParameter("rangeUri"); + } + + public static VClass getRangeVClass(VitroRequest vreq) { + return vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(getRangeUri(vreq)); + } + //get individual public static Individual getSubjectIndividual(VitroRequest vreq) { @@ -88,7 +98,8 @@ public class EditConfigurationUtils { public static ObjectProperty getObjectProperty(VitroRequest vreq) { //gets the predicate uri from the request String predicateUri = getPredicateUri(vreq); - return getObjectPropertyForPredicate(vreq, predicateUri); + String rangeUri = getRangeUri(vreq); + return getObjectPropertyForPredicate(vreq, predicateUri, rangeUri); } public static DataProperty getDataProperty(VitroRequest vreq) { @@ -97,8 +108,16 @@ public class EditConfigurationUtils { } public static ObjectProperty getObjectPropertyForPredicate(VitroRequest vreq, String predicateUri) { + return getObjectPropertyForPredicate(vreq, predicateUri, null); + } + + public static ObjectProperty getObjectPropertyForPredicate(VitroRequest vreq, String predicateUri, String rangeUri) { WebappDaoFactory wdf = vreq.getWebappDaoFactory(); ObjectProperty objectProp = wdf.getObjectPropertyDao().getObjectPropertyByURI(predicateUri); + if (rangeUri != null) { + objectProp.setRangeVClassURI(rangeUri); + // TODO implement this in the DAO? + } return objectProp; } @@ -189,7 +208,7 @@ public class EditConfigurationUtils { public static DataPropertyStatement getDataPropertyStatement(VitroRequest vreq, HttpSession session, Integer dataHash, String predicateUri) { DataPropertyStatement dps = null; if( dataHash != 0) { - Model model = (Model)session.getServletContext().getAttribute("jenaOntModel"); + OntModel model = ModelAccess.on(session.getServletContext()).getJenaOntModel(); dps = RdfLiteralHash.getPropertyStmtByHash(EditConfigurationUtils.getSubjectUri(vreq), predicateUri, dataHash, model); } return dps; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/fields/IndividualsViaObjectPropetyOptions.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/fields/IndividualsViaObjectPropetyOptions.java index 7668d41e8..39095ba3f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/fields/IndividualsViaObjectPropetyOptions.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/fields/IndividualsViaObjectPropetyOptions.java @@ -1,7 +1,6 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields; -import java.text.Collator; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; @@ -15,22 +14,26 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; public class IndividualsViaObjectPropetyOptions implements FieldOptions { + + private static final Log log = LogFactory.getLog(IndividualsViaObjectPropetyOptions.class); + private static final String LEFT_BLANK = ""; private String subjectUri; private String predicateUri; + private String rangeUri; private String objectUri; private String defaultOptionLabel; public IndividualsViaObjectPropetyOptions(String subjectUri, - String predicateUri, String objectUri) throws Exception { + String predicateUri, String rangeUri, String objectUri) throws Exception { super(); if (subjectUri == null || subjectUri.equals("")) { @@ -42,8 +45,14 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions { this.subjectUri = subjectUri; this.predicateUri = predicateUri; + this.rangeUri = rangeUri; this.objectUri = objectUri; } + + public IndividualsViaObjectPropetyOptions(String subjectUri, + String predicateUri, String objectUri) throws Exception { + this (subjectUri, predicateUri, null, objectUri); + } public IndividualsViaObjectPropetyOptions setDefaultOptionLabel(String label){ this.defaultOptionLabel = label; @@ -65,20 +74,12 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions { } Individual subject = wDaoFact.getIndividualDao().getIndividualByURI(subjectUri); - ObjectProperty objProp = wDaoFact.getObjectPropertyDao().getObjectPropertyByURI(predicateUri); + //get all vclasses applicable to the individual subject - List subjectVClasses = subject.getVClasses(); - //using hashset to prevent duplicates - HashSet vclassesURIs = new HashSet(); - //Get the range vclasses applicable for the property and each vclass for the subject - for(VClass subjectVClass: subjectVClasses) { - List vclasses = wDaoFact.getVClassDao().getVClassesForProperty(subjectVClass.getURI(), predicateUri); - //add range vclass to hash - if(vclasses != null) { - for(VClass v: vclasses) { - vclassesURIs.add(v.getURI()); - } - } + HashSet vclassesURIs = getApplicableVClassURIs(subject, wDaoFact); + + if (rangeUri != null) { + vclassesURIs = filterToSubclassesOfRange(vclassesURIs, rangeUri, wDaoFact); } if (vclassesURIs.size() == 0) { @@ -114,6 +115,46 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions { return optionsMap; } + private HashSet getApplicableVClassURIs(Individual subject, WebappDaoFactory wDaoFact) { + HashSet vclassesURIs = new HashSet(); + if (rangeUri != null) { + log.debug("individualsViaObjectProperty using rangeUri " + rangeUri); + vclassesURIs.add(rangeUri); + return vclassesURIs; + } + + log.debug("individualsViaObjectProperty not using any rangeUri"); + + List subjectVClasses = subject.getVClasses(); + + //using hashset to prevent duplicates + + //Get the range vclasses applicable for the property and each vclass for the subject + for(VClass subjectVClass: subjectVClasses) { + List vclasses = wDaoFact.getVClassDao().getVClassesForProperty(subjectVClass.getURI(), predicateUri); + //add range vclass to hash + if(vclasses != null) { + for(VClass v: vclasses) { + vclassesURIs.add(v.getURI()); + } + } + } + + return vclassesURIs; + } + + private HashSet filterToSubclassesOfRange(HashSet vclassesURIs, + String rangeUri, + WebappDaoFactory wDaoFact) { + HashSet filteredVClassesURIs = new HashSet(); + VClassDao vcDao = wDaoFact.getVClassDao(); + for (String vclass : vclassesURIs) { + if (vclass.equals(rangeUri) || vcDao.isSubClassOf(vclass, rangeUri)) { + filteredVClassesURIs.add(vclass); + } + } + return filteredVClassesURIs; + } // copied from OptionsForPropertyTag.java in the thought that class may be deprecated private static List removeIndividualsAlreadyInRange(List individuals, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java index 47c0d19d2..2fecd1063 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java @@ -10,35 +10,15 @@ import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; -import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; public class StandardModelSelector implements ModelSelector { private static final Log log = LogFactory.getLog(StandardModelSelector.class); public OntModel getModel(HttpServletRequest request, ServletContext context) { - VitroRequest vreq = new VitroRequest( request ); - - Object sessionOntModel = null; - if( vreq.getSession() != null) { - OntModelSelector oms = (OntModelSelector) vreq.getSession() - .getAttribute("unionOntModelSelector"); - if (oms != null) { - sessionOntModel = oms.getABoxModel(); - } - } - if(sessionOntModel != null && sessionOntModel instanceof OntModel ) { - log.debug("using OntModelSelector from session"); - return (OntModel)sessionOntModel; - } else if (vreq.getOntModelSelector() != null) { - log.debug("using OntModelSelector from request"); - return vreq.getOntModelSelector().getABoxModel(); - } else { - log.debug("using OntModelSelector from context"); - return ((OntModelSelector) context - .getAttribute("unionOntModelSelector")).getABoxModel(); - } + return ModelAccess.on(request.getSession()).getOntModel(ModelID.UNION_ABOX); } public static final ModelSelector selector = new StandardModelSelector(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java index 80adcecd0..0599081bd 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java @@ -4,8 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators import java.util.ArrayList; import java.util.List; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.commons.lang.StringUtils; @@ -13,13 +11,11 @@ import org.apache.commons.lang.StringUtils; import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; 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.configuration.IdModelSelector; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.ModelSelector; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.StandardModelSelector; -import edu.cornell.mannlib.vitro.webapp.filters.VitroRequestPrep; public abstract class BaseEditConfigurationGenerator implements EditConfigurationGenerator { @@ -66,7 +62,7 @@ public abstract class BaseEditConfigurationGenerator implements EditConfiguratio //setup the model selectors for query, write and display models on editConfig setupModelSelectorsFromVitroRequest(vreq, editConfig); - OntModel queryModel = vreq.getJenaOntModel(); // (OntModel)vreq.getAttribute("jenaOntModel"); + OntModel queryModel = ModelAccess.on(vreq).getJenaOntModel(); if( editConfig.getSubjectUri() == null) editConfig.setSubjectUri( EditConfigurationUtils.getSubjectUri(vreq)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultAddMissingIndividualFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultAddMissingIndividualFormGenerator.java index ca2f7b74a..6b24a1825 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultAddMissingIndividualFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultAddMissingIndividualFormGenerator.java @@ -14,6 +14,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; @@ -21,6 +22,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; 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; @@ -350,7 +352,7 @@ public class DefaultAddMissingIndividualFormGenerator implements EditConfigurati private void prepareForUpdate(VitroRequest vreq, HttpSession session, EditConfigurationVTwo editConfiguration) { //Here, retrieve model from - Model model = (Model) session.getServletContext().getAttribute("jenaOntModel"); + OntModel model = ModelAccess.on(session.getServletContext()).getJenaOntModel(); //if object property if(EditConfigurationUtils.isObjectProperty(EditConfigurationUtils.getPredicateUri(vreq), vreq)){ Individual objectIndividual = EditConfigurationUtils.getObjectIndividual(vreq); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java index a6ea9e704..8ffa4e04c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/DefaultObjectPropertyFormGenerator.java @@ -2,8 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.generators; -import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.*; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -24,13 +22,13 @@ import org.apache.solr.common.SolrDocumentList; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; @@ -102,10 +100,15 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene } protected List getRangeTypes(VitroRequest vreq) { + WebappDaoFactory wDaoFact = vreq.getWebappDaoFactory(); + List types = new ArrayList(); Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq); String predicateUri = EditConfigurationUtils.getPredicateUri(vreq); - WebappDaoFactory wDaoFact = vreq.getWebappDaoFactory(); - List types = new ArrayList(); + String rangeUri = EditConfigurationUtils.getRangeUri(vreq); + if (rangeUri != null) { + types.add(rangeUri); + return types; + } //Get all vclasses applicable to subject List vClasses = subject.getVClasses(); HashSet typesHash = new HashSet(); @@ -141,11 +144,10 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene }else{ query.setQuery( VitroSearchTermNames.RDFTYPE + ":" + type); } - query.setRows(0); - + query.setRows(0); QueryResponse rsp = solrServer.query(query); SolrDocumentList docs = rsp.getResults(); - long found = docs.getNumFound(); + long found = docs.getNumFound(); count = count + found; if( count > maxNonACRangeIndividualCount ) break; @@ -182,7 +184,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene this.setSparqlQueries(editConfiguration); //set fields - setFields(editConfiguration, vreq, EditConfigurationUtils.getPredicateUri(vreq)); + setFields(editConfiguration, vreq, EditConfigurationUtils.getPredicateUri(vreq), EditConfigurationUtils.getRangeUri(vreq)); // No need to put in session here b/c put in session within edit request dispatch controller instead //placing in session depends on having edit key which is handled in edit request dispatch controller @@ -352,7 +354,11 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene return map; } - protected void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri) throws Exception { + protected void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri) throws Exception { + setFields(editConfiguration, vreq, predicateUri, null); + } + + protected void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri, String rangeUri) throws Exception { FieldVTwo field = new FieldVTwo(); field.setName("objectVar"); @@ -363,7 +369,8 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene if( ! doAutoComplete ){ field.setOptions( new IndividualsViaObjectPropetyOptions( subjectUri, - predicateUri, + predicateUri, + rangeUri, objectUri)); }else{ field.setOptions(null); @@ -377,7 +384,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene private void prepareForUpdate(VitroRequest vreq, HttpSession session, EditConfigurationVTwo editConfiguration) { //Here, retrieve model from - Model model = (Model) session.getServletContext().getAttribute("jenaOntModel"); + OntModel model = ModelAccess.on(session.getServletContext()).getJenaOntModel(); //if object property if(EditConfigurationUtils.isObjectProperty(EditConfigurationUtils.getPredicateUri(vreq), vreq)){ Individual objectIndividual = EditConfigurationUtils.getObjectIndividual(vreq); @@ -408,16 +415,11 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene if(isSelectFromExisting(vreq)) { // set ProhibitedFromSearch object so picklist doesn't show // individuals from classes that should be hidden from list views - //TODO: Check how model is retrieved - OntModel displayOntModel = - (OntModel) session.getServletContext() - .getAttribute(DISPLAY_ONT_MODEL); - if (displayOntModel != null) { - ProhibitedFromSearch pfs = new ProhibitedFromSearch( - DisplayVocabulary.SEARCH_INDEX_URI, displayOntModel); - if( editConfig != null ) - editConfig.setProhibitedFromSearch(pfs); - } + OntModel displayOntModel = ModelAccess.on(session.getServletContext()).getDisplayModel(); + ProhibitedFromSearch pfs = new ProhibitedFromSearch( + DisplayVocabulary.SEARCH_INDEX_URI, displayOntModel); + if( editConfig != null ) + editConfig.setProhibitedFromSearch(pfs); } } @@ -468,7 +470,8 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene boolean rangeIndividualsFound = false; for( String type:types){ //solr for type count. - SolrQuery query = new SolrQuery(); + SolrQuery query = new SolrQuery(); + query.setQuery( VitroSearchTermNames.RDFTYPE + ":" + type); query.setRows(0); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManagePageGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManagePageGenerator.java index 225d086ed..43c820fb5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManagePageGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManagePageGenerator.java @@ -18,8 +18,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; @@ -27,12 +25,15 @@ import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.QuerySolutionMap; import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.vocabulary.XSD; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; 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.fields.FieldVTwo; @@ -207,7 +208,7 @@ public class ManagePageGenerator extends BaseEditConfigurationGenerator implemen void prepare(VitroRequest vreq, EditConfigurationVTwo editConfig) { //setup the model selectors for query, write and display models on editConfig setupModelSelectorsFromVitroRequest(vreq, editConfig); - OntModel queryModel = (OntModel)vreq.getAttribute("jenaOntModel"); + OntModel queryModel = ModelAccess.on(vreq).getJenaOntModel(); if (editConfig.isParamUpdate()) { editConfig.prepareForParamUpdate(queryModel); @@ -224,7 +225,7 @@ public class ManagePageGenerator extends BaseEditConfigurationGenerator implemen if (editConfig.isParamUpdate()) { //setup the model selectors for query, write and display models on editConfig setupModelSelectorsFromVitroRequest(vreq, editConfig); - OntModel queryModel = (OntModel)vreq.getAttribute("jenaOntModel"); + OntModel queryModel = ModelAccess.on(vreq).getJenaOntModel(); retrieveExistingDataGetterInfo(context, editConfig, queryModel); } @@ -507,7 +508,7 @@ private String getExistingIsSelfContainedTemplateQuery() { private void addRequiredPageData(VitroRequest vreq, Map data) { MenuManagementDataUtils.includeRequiredSystemData(vreq.getSession().getServletContext(), data); data.put("classGroup", new ArrayList()); - data.put("classGroups", DataGetterUtils.getClassGroups(vreq.getSession().getServletContext())); + data.put("classGroups", DataGetterUtils.getClassGroups(vreq)); } private void addExistingPageData(VitroRequest vreq, Map data) { @@ -589,7 +590,8 @@ private String getExistingIsSelfContainedTemplateQuery() { int maxMenuPosition = 0; Literal menuPosition = null; setupModelSelectorsFromVitroRequest(vreq, editConfig); - OntModel queryModel = (OntModel)vreq.getAttribute("jenaOntModel"); + OntModel queryModel = ModelAccess.on(vreq).getJenaOntModel(); + String maxMenuPositionQuery = getMaxMenuPositionQueryString(); QueryExecution qe = null; try{ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/NewIndividualFormGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/NewIndividualFormGenerator.java index 0c0adcdde..ba5b640ab 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/NewIndividualFormGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/NewIndividualFormGenerator.java @@ -10,13 +10,14 @@ import java.util.Map; import javax.servlet.http.HttpSession; +import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.vocabulary.RDFS; import com.hp.hpl.jena.vocabulary.XSD; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; @@ -239,7 +240,7 @@ public class NewIndividualFormGenerator implements EditConfigurationGenerator { private void prepareForUpdate(VitroRequest vreq, HttpSession session, EditConfigurationVTwo editConfiguration) { //Here, retrieve model from - Model model = (Model) session.getServletContext().getAttribute("jenaOntModel"); + OntModel model = ModelAccess.on(session.getServletContext()).getJenaOntModel(); //This form is always doing a non-update editConfiguration.prepareForNonUpdate( model ); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/RDFSLabelGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/RDFSLabelGenerator.java index 764f2f7b4..7dc24a5be 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/RDFSLabelGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/RDFSLabelGenerator.java @@ -13,6 +13,7 @@ import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.vocabulary.XSD; @@ -21,6 +22,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; @@ -297,7 +299,7 @@ public class RDFSLabelGenerator implements EditConfigurationGenerator { private void prepareForUpdate(VitroRequest vreq, HttpSession session, EditConfigurationVTwo editConfiguration) { //Here, retrieve model from - Model model = (Model) session.getServletContext().getAttribute("jenaOntModel"); + OntModel model = ModelAccess.on(session.getServletContext()).getJenaOntModel(); if( editConfiguration.isDataPropertyUpdate() ){ editConfiguration.prepareForDataPropUpdate(model, vreq.getWebappDaoFactory().getDataPropertyDao()); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessClassGroupDataGetterN3.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessClassGroupDataGetterN3.java index 5d93bbbd9..503f7193a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessClassGroupDataGetterN3.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessClassGroupDataGetterN3.java @@ -2,11 +2,14 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils; -import java.util.List; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; +import java.util.List; + +import javax.servlet.ServletContext; + +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -18,20 +21,13 @@ import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; -import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Resource; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; -import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo; -import javax.servlet.ServletContext; - -import net.sf.json.JSONArray; -import net.sf.json.JSONObject; -import net.sf.json.JSONSerializer; //Returns the appropriate n3 based on data getter public class ProcessClassGroupDataGetterN3 extends ProcessDataGetterAbstract { private static String classType = "java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.ClassGroupPageData"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessDataGetterAbstract.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessDataGetterAbstract.java index 02f1db4f2..3ad5c1309 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessDataGetterAbstract.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessDataGetterAbstract.java @@ -2,27 +2,14 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils; -import java.util.List; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import com.hp.hpl.jena.rdf.model.Literal; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.fields.FieldVTwo; - -import net.sf.json.JSONObject; -import net.sf.json.JSONSerializer; -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.query.Query; -import com.hp.hpl.jena.query.QueryExecution; -import com.hp.hpl.jena.query.QueryExecutionFactory; -import com.hp.hpl.jena.query.QueryFactory; -import com.hp.hpl.jena.query.QuerySolution; -import com.hp.hpl.jena.query.ResultSet; -import com.hp.hpl.jena.rdf.model.Literal; - //Returns the appropriate n3 based on data getter public abstract class ProcessDataGetterAbstract implements ProcessDataGetterN3 { public static String classTypeVarBase = "classType"; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessDataGetterN3Map.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessDataGetterN3Map.java index 6612cf8a0..4900cba6f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessDataGetterN3Map.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessDataGetterN3Map.java @@ -2,27 +2,11 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils; -import java.lang.reflect.Constructor; import java.util.HashMap; -import java.util.Map; - -import javax.servlet.ServletContext; - -import net.sf.json.JSONObject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.ResourceFactory; -import com.hp.hpl.jena.rdf.model.StmtIterator; - -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessDataGetterN3; -import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter; - /* * This class determines what n3 should be returned for a particular data getter and can be overwritten or extended in VIVO. */ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessDataGetterN3Utils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessDataGetterN3Utils.java index a4dbacd0b..64a64b36c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessDataGetterN3Utils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/preprocessors/utils/ProcessDataGetterN3Utils.java @@ -4,25 +4,12 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocess import java.lang.reflect.Constructor; import java.util.HashMap; -import java.util.Map; - -import javax.servlet.ServletContext; import net.sf.json.JSONObject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.ResourceFactory; -import com.hp.hpl.jena.rdf.model.StmtIterator; - -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; -import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.preprocessors.utils.ProcessDataGetterN3; -import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetter; - /* * This class determines what n3 should be returned for a particular data getter and can be overwritten or extended in VIVO. */ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestAJAXController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestAJAXController.java index e09aa6ae4..de0900354 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestAJAXController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestAJAXController.java @@ -2,11 +2,7 @@ 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; @@ -16,39 +12,13 @@ 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 diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java index a122eaaeb..fba13b869 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/EditRequestDispatchController.java @@ -199,6 +199,7 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { String editConfGeneratorName = null; String predicateUri = getPredicateUri(vreq); + String rangeUri = EditConfigurationUtils.getRangeUri(vreq); // *** handle the case where the form is specified as a request parameter *** String formParam = getFormParam(vreq); @@ -215,7 +216,9 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { // *** check for a predicate URI in the request }else if( predicateUri != null && !predicateUri.isEmpty() ){ Property prop = getProperty( predicateUri, vreq); - if( prop != null && prop.getCustomEntryForm() != null ){ + if (prop != null && rangeUri != null) { + editConfGeneratorName = getCustomEntryFormForPropertyAndRange(prop, rangeUri); + } else if( prop != null && prop.getCustomEntryForm() != null ){ //there is a custom form, great! let's use it. editConfGeneratorName = prop.getCustomEntryForm(); @@ -244,7 +247,22 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet { return editConfGeneratorName; } - private Property getProperty(String predicateUri, VitroRequest vreq) { + private String getCustomEntryFormForPropertyAndRange(Property prop, String rangeUri){ + String entryFormName = null; + // = ApplicationConfigurationOntologyUtils.getEntryForm(prop.getURI(), rangeUri); + if (entryFormName == null) { + if (prop.getCustomEntryForm() != null) { + return prop.getCustomEntryForm(); + } else { + return DEFAULT_OBJ_FORM; + } + } else { + prop.setCustomEntryForm(entryFormName); + return entryFormName; + } + } + + private Property getProperty(String predicateUri, VitroRequest vreq) { Property p = null; try{ p = vreq.getWebappDaoFactory().getObjectPropertyDao().getObjectPropertyByURI(predicateUri); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailFactory.java index bedeab160..05e3c7a51 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailFactory.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailFactory.java @@ -61,8 +61,8 @@ public class FreemarkerEmailFactory { FreemarkerEmailFactory factory = getFactory(vreq); FreemarkerConfiguration fConfig = FreemarkerConfigurationLoader .getConfig(vreq); - return new FreemarkerEmailMessage(fConfig, factory.getEmailSession(), - factory.getReplyToAddress()); + return new FreemarkerEmailMessage(vreq, fConfig, + factory.getEmailSession(), factory.getReplyToAddress()); } /** diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailMessage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailMessage.java index db7356ed4..6fab17daa 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailMessage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailMessage.java @@ -27,8 +27,10 @@ import javax.mail.internet.MimeMultipart; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfiguration; import edu.cornell.mannlib.vitro.webapp.web.directives.EmailDirective; +import freemarker.core.Environment; import freemarker.template.Template; import freemarker.template.TemplateException; @@ -47,7 +49,8 @@ public class FreemarkerEmailMessage { private static final Log log = LogFactory .getLog(FreemarkerEmailMessage.class); - private final Session session; + private final VitroRequest vreq; + private final Session mailSession; private final FreemarkerConfiguration config; private final List recipients = new ArrayList(); @@ -63,9 +66,10 @@ public class FreemarkerEmailMessage { /** * Package access - should only be created by the factory. */ - FreemarkerEmailMessage(FreemarkerConfiguration fConfig, Session session, - InternetAddress replyToAddress) { - this.session = session; + FreemarkerEmailMessage(VitroRequest vreq, FreemarkerConfiguration fConfig, + Session mailSession, InternetAddress replyToAddress) { + this.vreq = vreq; + this.mailSession = mailSession; this.replyToAddress = replyToAddress; this.config = fConfig; } @@ -141,7 +145,13 @@ public class FreemarkerEmailMessage { try { Template template = config.getTemplate(templateName); - template.process(bodyMap, new StringWriter()); + + Environment env = template.createProcessingEnvironment(bodyMap, + new StringWriter()); + env.setCustomAttribute("request", vreq); + env.setCustomAttribute("context", vreq.getSession() + .getServletContext()); + env.process(); } catch (TemplateException e) { log.error(e, e); } catch (IOException e) { @@ -151,7 +161,7 @@ public class FreemarkerEmailMessage { public boolean send() { try { - MimeMessage msg = new MimeMessage(session); + MimeMessage msg = new MimeMessage(mailSession); msg.setReplyTo(new Address[] { replyToAddress }); if (fromAddress == null) { @@ -199,11 +209,11 @@ public class FreemarkerEmailMessage { bodyPart.setContent(textBody, type); content.addBodyPart(bodyPart); } - - public String getReplyToAddress() { - return replyToAddress.getAddress(); - } - + + public String getReplyToAddress() { + return replyToAddress.getAddress(); + } + private T nonNull(T value, T defaultValue) { return (value == null) ? defaultValue : value; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/serving/FileServingServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/serving/FileServingServlet.java index 388b71e38..defd15a54 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/serving/FileServingServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/serving/FileServingServlet.java @@ -87,19 +87,19 @@ public class FileServingServlet extends VitroHttpServlet { InputStream in; String mimeType = null; try { - FileInfo fileInfo = figureFileInfo( - request.getFullWebappDaoFactory(), path); + FileInfo fileInfo = figureFileInfo(request.getWebappDaoFactory(), + path); mimeType = fileInfo.getMimeType(); String actualFilename = findAndValidateFilename(fileInfo, path); in = openImageInputStream(fileInfo, actualFilename); } catch (FileServingException e) { - log.info("Failed to serve the file at '" + path + "' -- " + e.getMessage()); + log.info("Failed to serve the file at '" + path + "' -- " + e); in = openMissingLinkImage(request); mimeType = "image/png"; } catch (Exception e) { - log.warn("Failed to serve the file at '" + path + "' -- " + e.getMessage()); + log.warn("Failed to serve the file at '" + path + "' -- " + e); in = openMissingLinkImage(request); mimeType = "image/png"; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/CachingResponseFilter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/CachingResponseFilter.java new file mode 100644 index 000000000..26c8e452d --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/CachingResponseFilter.java @@ -0,0 +1,363 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.filters; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.collections.EnumerationUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServer; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.response.QueryResponse; + +import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup; +import edu.cornell.mannlib.vitro.webapp.utils.solr.FieldMap; +import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrQueryUtils; +import edu.cornell.mannlib.vitro.webapp.utils.solr.SolrResultsParser; + +/** + * Assist in cache management for individual profile pages. + * + * Must be enabled in runtime.properties. + * + * Only works for users who are not logged in. + * + * The Solr index must be configured to keep an ETAG on each individual's + * record. The ETAG is a hash of the record's content and is updated each time + * the individual is re-indexed. + * + * But this ETAG is not sufficient, since the page may have different versions + * for different languages. So we append a hash of the Locales from the request + * to the ETAG to make it unique. NOTE: If we allow users to choose their + * preferred languages, the LocalSelectionFilter must execute before this one. + * + * When an external cache (e.g. Squid) is asked for an individual's profile + * page, it will ask VIVO whether the version in the cache is still current, and + * to provide a new version if it is not. This is a conditional request. + * + * When a conditional request is received, this filter will check to see whether + * the request is on behalf of a logged-in user. If so, a fresh response is + * generated, with a Cache-Control header that should prevent the cache from + * storing that response. + * + * If the requesting user is not logged in, this filter will ask Solr for the + * ETAG on the requested individual. If it is the same as the ETAG supplied by + * the cache in the request, then the response is 304 Not Modified. Otherwise, a + * fresh response is generated. + * + * An unconditional request may mean that there is no external cache, or that + * the cache doesn't have a copy of this particular page. + * + * @see http://tools.ietf.org/pdf/rfc2616 + */ +public class CachingResponseFilter implements Filter { + private static final Log log = LogFactory + .getLog(CachingResponseFilter.class); + + private static final String PROPERTY_DEFAULT_NAMESPACE = "Vitro.defaultNamespace"; + private static final String PROPERTY_ENABLE_CACHING = "http.createCacheHeaders"; + private static final String ETAG_FIELD = "etag"; + + private static final FieldMap parserFieldMap = SolrQueryUtils.fieldMap() + .put(ETAG_FIELD, ETAG_FIELD); + + private ServletContext ctx; + private String defaultNamespace; + private boolean enabled; + + @Override + public void init(FilterConfig fc) throws ServletException { + ctx = fc.getServletContext(); + ConfigurationProperties props = ConfigurationProperties.getBean(ctx); + defaultNamespace = props.getProperty(PROPERTY_DEFAULT_NAMESPACE); + enabled = Boolean.valueOf(props.getProperty(PROPERTY_ENABLE_CACHING)); + } + + @Override + public void destroy() { + // Nothing to tear down. + } + + /** + * Process an HTTP request. + */ + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse resp = (HttpServletResponse) response; + + /* + * If caching is disabled, if this request is not for a profile page, or + * if the individual doesn't appear in the search index, create a basic, + * cache-neutral response. + */ + if (!enabled) { + produceBasicResponse(req, resp, chain); + return; + } + String individualUri = figureIndividualUriFromRequest(req); + if (individualUri == null) { + produceBasicResponse(req, resp, chain); + return; + } + String rawEtag = findEtagForIndividual(individualUri); + String etag = produceLanguageSpecificEtag(req, rawEtag); + if (etag == null) { + produceBasicResponse(req, resp, chain); + return; + } + + /* + * If a logged-in user asks for an individual profile page, the response + * should not come from the cache, nor should it be stored in the cache. + */ + if (userIsLoggedIn(req)) { + produceUncacheableResponse(req, resp, chain); + return; + } + + /* + * If the request is not conditional then there is no cached version of + * this page. If the request is conditional and the condition is met, + * then the cached version is stale. In either case, create a fresh + * response to be stored in the cache. + */ + if (!isConditionalRequest(req)) { + produceCacheableResponse(req, resp, chain, etag); + return; + } + if (cacheIsStale(req, etag)) { + produceCacheableResponse(req, resp, chain, etag); + return; + } + + /* + * If the request is conditional and the condition is not met + * (individual has not changed), send a "not-modified" response, so the + * cached version will be used. + */ + produceCacheHitResponse(resp, etag); + } + + private boolean isConditionalRequest(HttpServletRequest req) { + if (req.getHeader("If-None-Match") == null) { + log.debug("Not conditional request."); + return false; + } else { + log.debug("Conditional request."); + return true; + } + } + + private boolean userIsLoggedIn(HttpServletRequest req) { + UserAccount currentUser = LoginStatusBean.getCurrentUser(req); + if (currentUser == null) { + log.debug("Not logged in."); + return false; + } else { + log.debug("Logged in as '" + currentUser.getEmailAddress() + "'"); + return true; + } + } + + /** + * This rejects some of the requests as being obviously not individuals, and + * then assumes that the last part of any request is a Localname. + * + * This is not always true, of course, but it will work because we will + * prepend the default namespace and look for the resulting "URI" in the URI + * field of the search index. If we find it there, then it is valid. + * + * If we were to make this more rigorous, it would reduce the number of + * unnecessary searches. + */ + private String figureIndividualUriFromRequest(HttpServletRequest req) { + String requestPath = req.getRequestURI(); + if (requestPath == null) { + return null; + } + + if (!mightBeProfileRequest(requestPath)) { + return null; + } + + String[] pathParts = requestPath.split("/"); + String uri = defaultNamespace + pathParts[pathParts.length - 1]; + + log.debug("Request path = '" + requestPath + "', uri = '" + uri + "'"); + return uri; + } + + /** + * Requests for profile pages come in many forms, but we can still narrow + * them down. + * + * Eliminate CSS files, JavaScript files, and images. + * + * That leaves these acceptable forms: + * + *
+	 *     /individual?uri=urlencodedURI
+	 *     /individual?netId=bdc34
+	 *     /individual?netid=bdc34
+	 *     /individual/localname         
+	 *     /display/localname
+	 *     /individual/localname/localname.rdf
+	 *     /individual/localname/localname.n3
+	 *     /individual/localname/localname.ttl
+	 * 
+ */ + private boolean mightBeProfileRequest(String requestPath) { + String path = requestPath.toLowerCase(); + String[] extensions = { ".css", ".js", ".gif", ".png", ".jpg", ".jpeg" }; + for (String ext : extensions) { + if (path.endsWith(ext)) { + return false; + } + } + return requestPath.endsWith("/individual") + || requestPath.contains("/individual/") + || requestPath.contains("/display/"); + } + + /** + * Ask Solr whether it has an ETAG for this URI. + */ + private String findEtagForIndividual(String individualUri) { + SolrQuery query = new SolrQuery("URI:" + individualUri) + .setFields(ETAG_FIELD); + + SolrServer solr = SolrSetup.getSolrServer(ctx); + + try { + QueryResponse response = solr.query(query); + List> maps = new SolrResultsParser(response, + parserFieldMap).parse(); + log.debug("Solr response for '" + query.getQuery() + "' was " + + maps); + + if (maps.isEmpty()) { + return null; + } else { + return maps.get(0).get(ETAG_FIELD); + } + } catch (SolrServerException e) { + log.warn( + "Solr query '" + query.getQuery() + "' threw an exception", + e); + return null; + } + } + + /** + * The ETAG from the Solr index is not specific enough, since we may have + * different versions for different languages. Add the Locales from the + * request to make it unique. + */ + private String produceLanguageSpecificEtag(HttpServletRequest req, + String rawEtag) { + if (rawEtag == null) { + return null; + } + + @SuppressWarnings("unchecked") + List locales = EnumerationUtils.toList(req.getLocales()); + + StringBuilder buffer = new StringBuilder('"').append(rawEtag); + for (Locale locale : locales) { + buffer.append(locale.toString()).append(" "); + } + buffer.append('"'); + + String etag = buffer.toString(); + log.debug("Language-specific ETAG = " + etag); + return etag; + } + + /** + * If the etag does not match any of the etags in any of the "If-None-Match" + * headers, then they are all stale. An asterisk matches anything. + */ + private boolean cacheIsStale(HttpServletRequest req, String etag) { + for (Enumeration values = req.getHeaders("If-None-Match"); values + .hasMoreElements();) { + String value = (String) values.nextElement(); + log.debug("If-None-Match: " + value); + + String[] matches = value.split("\\s*,\\s*"); + for (String match : matches) { + if (etag.equalsIgnoreCase(match) || "*".equals(match)) { + log.debug("Cache is not stale: etag=" + match); + return false; + } + } + } + log.debug("Cache is stale."); + return true; + } + + private void produceBasicResponse(HttpServletRequest req, + HttpServletResponse resp, FilterChain chain) throws IOException, + ServletException { + chain.doFilter(req, resp); + } + + private void produceUncacheableResponse(HttpServletRequest req, + HttpServletResponse resp, FilterChain chain) throws IOException, + ServletException { + String etag = generateArbitraryUniqueEtag(req); + log.debug("Produce uncacheable response: etag='" + etag + "'"); + + resp.addHeader("ETag", etag); + resp.addHeader("Vary", "*"); + resp.addHeader("Cache-Control", "no-store"); + chain.doFilter(req, resp); + } + + private void produceCacheableResponse(HttpServletRequest req, + HttpServletResponse resp, FilterChain chain, String etag) + throws IOException, ServletException { + log.debug("Produce cacheable response: etag='" + etag + "'"); + resp.addHeader("ETag", etag); + resp.addHeader("Vary", "Accept-Language"); + chain.doFilter(req, resp); + } + + /** + * Technically, if the request is not GET or HEAD, we should return 412 + * PreconditionFailed. However, we usually treat GET and POST as equivalent. + */ + private void produceCacheHitResponse(HttpServletResponse resp, String etag) + throws IOException { + log.debug("Produce cache hit response: etag='" + etag + "'"); + resp.addHeader("ETag", etag); + resp.addHeader("Vary", "Accept-Language"); + resp.sendError(HttpServletResponse.SC_NOT_MODIFIED, "Not Modified"); + } + + private String generateArbitraryUniqueEtag(HttpServletRequest req) { + return String.format("%s-%d", req.getSession().getId(), + System.currentTimeMillis()); + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/ModelSwitcher.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/ModelSwitcher.java new file mode 100644 index 000000000..37f72c4dd --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/ModelSwitcher.java @@ -0,0 +1,182 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.filters; + +import static edu.cornell.mannlib.vitro.webapp.controller.VitroRequest.SPECIAL_WRITE_MODEL; +import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.SWITCH_TO_DISPLAY_MODEL; +import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.USE_DISPLAY_MODEL_PARAM; +import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.USE_MODEL_PARAM; +import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.USE_TBOX_MODEL_PARAM; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.sql.DataSource; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; +import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; +import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; + +/** + * Handle model switching, if requested for the editing framework. + */ +public class ModelSwitcher { + private static final Log log = LogFactory.getLog(ModelSwitcher.class); + + /** + * Are they authorized for whatever models they are asking for? + */ + public static boolean authorizedForSpecialModel(HttpServletRequest req) { + if (isParameterPresent(req, SWITCH_TO_DISPLAY_MODEL)) { + return PolicyHelper.isAuthorizedForActions(req, SimplePermission.MANAGE_MENUS.ACTIONS); + } else if (anyOtherSpecialProperties(req)){ + return PolicyHelper.isAuthorizedForActions(req, SimplePermission.ACCESS_SPECIAL_DATA_MODELS.ACTIONS); + } else { + return true; + } + } + + private static boolean anyOtherSpecialProperties(HttpServletRequest req) { + return isParameterPresent(req, USE_MODEL_PARAM) + || isParameterPresent(req, USE_TBOX_MODEL_PARAM) + || isParameterPresent(req, USE_DISPLAY_MODEL_PARAM); + } + + private static boolean isParameterPresent(HttpServletRequest req, String key) { + return StringUtils.isNotEmpty(req.getParameter(key)); + } + + /** + * Check if special model is requested - this is for enabling the use of a different + * model for menu management. Also enables the use of a completely different + * model and tbox if uris are passed. + */ + public WebappDaoFactory checkForModelSwitching(VitroRequest vreq, WebappDaoFactory inputWadf) { + ServletContext _context = vreq.getSession().getServletContext(); + //TODO: Does the dataset in the vreq get set when using a special WDF? Does it need to? + //TODO: Does the unfiltered WDF get set when using a special WDF? Does it need to? + + // If this isn't a Jena WADF, then there's nothing to be done. + if (!(inputWadf instanceof WebappDaoFactoryJena)) { + log.warn("Can't set special models: " + + "WebappDaoFactory is not a WebappDaoFactoryJena"); + removeSpecialWriteModel(vreq); + return inputWadf; + } + + WebappDaoFactoryJena wadf = (WebappDaoFactoryJena) inputWadf; + + // If they asked for the display model, give it to them. + if (isParameterPresent(vreq, SWITCH_TO_DISPLAY_MODEL)) { + OntModel mainOntModel = ModelAccess.on(_context).getDisplayModel(); + OntModel tboxOntModel = ModelAccess.on(_context).getOntModel(ModelID.DISPLAY_TBOX); + setSpecialWriteModel(vreq, mainOntModel); + + vreq.setAttribute(VitroRequest.ID_FOR_ABOX_MODEL, VitroModelSource.ModelName.DISPLAY.toString()); + vreq.setAttribute(VitroRequest.ID_FOR_TBOX_MODEL, VitroModelSource.ModelName.DISPLAY_TBOX.toString()); + vreq.setAttribute(VitroRequest.ID_FOR_DISPLAY_MODEL, VitroModelSource.ModelName.DISPLAY_DISPLAY.toString()); + vreq.setAttribute(VitroRequest.ID_FOR_WRITE_MODEL, VitroModelSource.ModelName.DISPLAY.toString()); + + return createNewWebappDaoFactory(wadf, mainOntModel, tboxOntModel, null); + } + + // If they asked for other models by URI, set them. + if (anyOtherSpecialProperties(vreq)) { + DataSource bds = JenaDataSourceSetupBase.getApplicationDataSource(_context); + String dbType = ConfigurationProperties.getBean(_context) + .getProperty("VitroConnection.DataSource.dbtype", "MySQL"); + + OntModel mainOntModel = createSpecialModel(vreq, USE_MODEL_PARAM, bds, dbType); + OntModel tboxOntModel = createSpecialModel(vreq, USE_TBOX_MODEL_PARAM, bds, dbType); + OntModel displayOntModel = createSpecialModel(vreq, USE_DISPLAY_MODEL_PARAM, bds, dbType); + + vreq.setAttribute(VitroRequest.ID_FOR_ABOX_MODEL, vreq.getParameter(USE_MODEL_PARAM)); + vreq.setAttribute(VitroRequest.ID_FOR_WRITE_MODEL, vreq.getParameter(USE_MODEL_PARAM)); + vreq.setAttribute(VitroRequest.ID_FOR_TBOX_MODEL, vreq.getParameter(USE_TBOX_MODEL_PARAM)); + vreq.setAttribute(VitroRequest.ID_FOR_DISPLAY_MODEL, vreq.getParameter(USE_DISPLAY_MODEL_PARAM)); + + setSpecialWriteModel(vreq, mainOntModel); + return createNewWebappDaoFactory(wadf, mainOntModel, tboxOntModel, displayOntModel); + } + + // Otherwise, there's nothing special about this request. + removeSpecialWriteModel(vreq); + return wadf; + + } + + private void setSpecialWriteModel(VitroRequest vreq, OntModel mainOntModel) { + if (mainOntModel != null) { + ModelAccess.on(vreq).setJenaOntModel(mainOntModel); + vreq.setAttribute(SPECIAL_WRITE_MODEL, mainOntModel); + } + } + + private void removeSpecialWriteModel(VitroRequest vreq) { + if (vreq.getAttribute(SPECIAL_WRITE_MODEL) != null) { + vreq.removeAttribute(SPECIAL_WRITE_MODEL); + } + } + + /** + * The goal here is to return a new WDF that is set to + * have the mainOntModel as its ABox, the tboxOntModel as it + * TBox and displayOntModel as it display model. + * + * Right now this is achieved by creating a copy of + * the WADF, and setting the special models onto it. + * + * If a model is null, it will have no effect. + */ + private WebappDaoFactory createNewWebappDaoFactory( + WebappDaoFactoryJena inputWadf, OntModel mainOntModel, + OntModel tboxOntModel, OntModel displayOntModel) { + + WebappDaoFactoryJena wadfj = new WebappDaoFactoryJena(inputWadf); + wadfj.setSpecialDataModel(mainOntModel, tboxOntModel, displayOntModel); + return wadfj; + } + + /** + * If the request asks for a special model by URI, create it from the + * Database. + * + * @return the model they asked for, or null if they didn't ask for one. + * @throws IllegalStateException + * if it's not found. + */ + private OntModel createSpecialModel(VitroRequest vreq, String key, + DataSource bds, String dbType) { + if (!isParameterPresent(vreq, key)) { + return null; + } + + String modelUri = vreq.getParameter(key); + Model model = JenaDataSourceSetupBase.makeDBModel(bds, modelUri, + OntModelSpec.OWL_MEM, + JenaDataSourceSetupBase.TripleStoreType.RDB, dbType, vreq.getSession().getServletContext()); + if (model != null) { + return ModelFactory + .createOntologyModel(OntModelSpec.OWL_MEM, model); + } else { + throw new IllegalStateException("Main Model Uri " + modelUri + + " did not retrieve model"); + } + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java index d4b9be61c..4c849338a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/PageRoutingFilter.java @@ -11,6 +11,7 @@ import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -21,6 +22,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.PageController; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.PageDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; /** @@ -52,7 +54,9 @@ public class PageRoutingFilter implements Filter{ @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { - PageDao pageDao = getPageDao(); + ServletContext ctx = filterConfig.getServletContext(); + + PageDao pageDao = ModelAccess.on(ctx).getWebappDaoFactory().getPageDao(); Map urlMappings = pageDao.getPageMappings(); // get URL without hostname or servlet context @@ -81,7 +85,7 @@ public class PageRoutingFilter implements Filter{ String controllerName = getControllerToForwardTo(req, pageUri, pageDao); log.debug(path + " is being forwarded to controller " + controllerName); - RequestDispatcher rd = filterConfig.getServletContext().getNamedDispatcher( controllerName ); + RequestDispatcher rd = ctx.getNamedDispatcher( controllerName ); if( rd == null ){ log.error(path + " should be forwarded to controller " + controllerName + " but there " + "is no servlet named that defined for the web application in web.xml"); @@ -91,7 +95,7 @@ public class PageRoutingFilter implements Filter{ rd.forward(req, response); }else if( "/".equals( path ) || path.isEmpty() ){ log.debug("url '" +path + "' is being forward to home controller" ); - RequestDispatcher rd = filterConfig.getServletContext().getNamedDispatcher( HOME_CONTROLLER_NAME ); + RequestDispatcher rd = ctx.getNamedDispatcher( HOME_CONTROLLER_NAME ); rd.forward(req, response); }else{ doNonDisplayPage(path,arg0,arg1,chain); @@ -132,12 +136,6 @@ public class PageRoutingFilter implements Filter{ return false; } - protected PageDao getPageDao(){ - WebappDaoFactory wdf = (WebappDaoFactory) - filterConfig.getServletContext().getAttribute("webappDaoFactory"); - return wdf.getPageDao(); - } - @Override public void destroy() { //nothing to do here diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/RequestModelsPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/RequestModelsPrep.java new file mode 100644 index 000000000..001e8e51f --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/RequestModelsPrep.java @@ -0,0 +1,228 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.filters; + +import java.io.IOException; +import java.util.List; +import java.util.regex.Pattern; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.ModelFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; +import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering; +import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.HideFromDisplayByPolicyFilter; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringRDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringUtils; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; + +/** + * This sets up several objects in the Request scope for each incoming HTTP + * request. This is done in a Filter so that controllers and JSPs get the same + * setup. + * + * This code configures the WebappDaoFactory for each request. + */ +public class RequestModelsPrep implements Filter { + private final static Log log = LogFactory.getLog(RequestModelsPrep.class); + + /** + * The filter will be applied to all incoming urls, this is a list of URI + * patterns to skip. These are matched against the requestURI sans query + * parameters, e.g. "/vitro/index.jsp" "/vitro/themes/enhanced/css/edit.css" + */ + private final static Pattern[] skipPatterns = { + Pattern.compile(".*\\.(gif|GIF|jpg|jpeg)$"), + Pattern.compile(".*\\.css$"), Pattern.compile(".*\\.js$"), + Pattern.compile("/.*/themes/.*/site_icons/.*"), + Pattern.compile("/.*/images/.*") }; + + private ServletContext ctx; + private ConfigurationProperties props; + private String defaultNamespace; + + @Override + public void init(FilterConfig fc) throws ServletException { + ctx = fc.getServletContext(); + props = ConfigurationProperties.getBean(ctx); + defaultNamespace = props.getProperty("Vitro.defaultNamespace"); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse resp = (HttpServletResponse) response; + + // If we're not authorized for this request, skip the chain and + // redirect. + if (!ModelSwitcher.authorizedForSpecialModel(req)) { + VitroHttpServlet.redirectUnauthorizedRequest(req, resp); + return; + } + + if (!thisRequestNeedsModels(req) || modelsAreAlreadySetUp(req)) { + filterChain.doFilter(req, resp); + } else { + RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx) + .getShortTermRDFService(); + try { + setUpTheRequestModels(rdfService, req); + filterChain.doFilter(req, resp); + } finally { + rdfService.close(); + } + } + } + + private boolean thisRequestNeedsModels(HttpServletRequest req) { + String requestURI = req.getRequestURI(); + for (Pattern skipPattern : skipPatterns) { + if (skipPattern.matcher(requestURI).matches()) { + log.debug("request matched skipPattern '" + skipPattern + + "', skipping RequestModelsPrep"); + return false; + } + } + return true; + } + + private boolean modelsAreAlreadySetUp(HttpServletRequest req) { + String attributeName = RequestModelsPrep.class.getName() + "-setup"; + if (req.getAttribute(attributeName) != null) { + return true; + } else { + req.setAttribute(attributeName, Boolean.TRUE); + return false; + } + } + + private void setUpTheRequestModels(RDFService rawRdfService, + HttpServletRequest req) { + VitroRequest vreq = new VitroRequest(req); + + vreq.setUnfilteredRDFService(rawRdfService); + + List langs = getPreferredLanguages(req); + RDFService rdfService = addLanguageAwareness(langs, rawRdfService); + vreq.setRDFService(rdfService); + + Dataset dataset = new RDFServiceDataset(rdfService); + vreq.setDataset(dataset); + + WebappDaoFactoryConfig config = createWadfConfig(langs, req); + + WebappDaoFactory assertions = new WebappDaoFactorySDB(rdfService, + ModelAccess.on(ctx).getBaseOntModelSelector(), config, + SDBDatasetMode.ASSERTIONS_ONLY); + ModelAccess.on(vreq).setBaseWebappDaoFactory(assertions); + + ModelAccess.on(vreq).setJenaOntModel( + ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, + dataset.getDefaultModel())); + + OntModelSelector oms = ModelAccess.on(ctx).getUnionOntModelSelector(); + WebappDaoFactory wadf = new WebappDaoFactorySDB(rdfService, oms, config); + vreq.setUnfilteredWebappDaoFactory(wadf); + + addLanguageAwarenessToRequestModel(req, ModelID.DISPLAY); + addLanguageAwarenessToRequestModel(req, ModelID.APPLICATION_METADATA); + addLanguageAwarenessToRequestModel(req, ModelID.UNION_TBOX); + addLanguageAwarenessToRequestModel(req, ModelID.UNION_FULL); + addLanguageAwarenessToRequestModel(req, ModelID.BASE_TBOX); + addLanguageAwarenessToRequestModel(req, ModelID.BASE_FULL); + + wadf = new WebappDaoFactorySDB(rdfService, ModelAccess.on(vreq).getUnionOntModelSelector(), config); + + // Do model switching and replace the WebappDaoFactory with + // a different version if requested by parameters + WebappDaoFactory switchedWadf = new ModelSwitcher() + .checkForModelSwitching(vreq, wadf); + + HideFromDisplayByPolicyFilter filter = new HideFromDisplayByPolicyFilter( + RequestIdentifiers.getIdBundleForRequest(req), + ServletPolicyList.getPolicies(ctx)); + WebappDaoFactoryFiltering filteredWadf = new WebappDaoFactoryFiltering( + switchedWadf, filter); + ModelAccess.on(vreq).setWebappDaoFactory(filteredWadf); + } + + private WebappDaoFactoryConfig createWadfConfig(List langs, HttpServletRequest req) { + WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); + config.setDefaultNamespace(defaultNamespace); + config.setPreferredLanguages(langs); + config.setUnderlyingStoreReasoned(isStoreReasoned(req)); + return config; + } + + private List getPreferredLanguages(HttpServletRequest req) { + log.debug("Accept-Language: " + req.getHeader("Accept-Language")); + return LanguageFilteringUtils.localesToLanguages(req.getLocales()); + } + + /** + * Language awareness is enabled unless they explicitly disable it. + */ + private Boolean isLanguageAwarenessEnabled() { + return Boolean.valueOf(props.getProperty("RDFService.languageFilter", + "true")); + } + + private RDFService addLanguageAwareness(List langs, + RDFService rawRDFService) { + if (isLanguageAwarenessEnabled()) { + return new LanguageFilteringRDFService(rawRDFService, langs); + } else { + return rawRDFService; + } + } + + private void addLanguageAwarenessToRequestModel(HttpServletRequest req, ModelID id) { + if (isLanguageAwarenessEnabled()) { + OntModel unaware = ModelAccess.on(req.getSession()).getOntModel(id); + OntModel aware = LanguageFilteringUtils + .wrapOntModelInALanguageFilter(unaware, req); + ModelAccess.on(req).setOntModel(id, aware); + } + } + + private boolean isStoreReasoned(ServletRequest req) { + String isStoreReasoned = ConfigurationProperties.getBean(req).getProperty( + "VitroConnection.DataSource.isStoreReasoned", "true"); + return ("true".equals(isStoreReasoned)); + } + + @Override + public void destroy() { + // Nothing to destroy + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/SessionTimeoutLimitingFilter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/SessionTimeoutLimitingFilter.java index 275066c6c..3ce778c1b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/SessionTimeoutLimitingFilter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/SessionTimeoutLimitingFilter.java @@ -43,8 +43,7 @@ public class SessionTimeoutLimitingFilter implements Filter { /** * If this request has a trivial session object -- that is, the user is not - * logged in and not self-editing -- then give it a short expiration - * interval. + * logged in -- then give it a short expiration interval. */ private void limitTrivialSession(ServletRequest servletRequest) { if (!(servletRequest instanceof HttpServletRequest)) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/StartupStatusDisplayFilter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/StartupStatusDisplayFilter.java index 3ef123eb4..faa7f9ee2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/StartupStatusDisplayFilter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/StartupStatusDisplayFilter.java @@ -21,7 +21,7 @@ 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.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import freemarker.cache.WebappTemplateLoader; @@ -116,8 +116,7 @@ public class StartupStatusDisplayFilter implements Filter { private Object getApplicationName() { String name = ""; try { - WebappDaoFactory wadf = (WebappDaoFactory) ctx - .getAttribute("webappDaoFactory"); + WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory(); ApplicationBean app = wadf.getApplicationDao().getApplicationBean(); name = app.getApplicationName(); } catch (Exception e) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/URLRewritingHttpServletResponse.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/URLRewritingHttpServletResponse.java index f52727c27..64d554c5b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/URLRewritingHttpServletResponse.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/URLRewritingHttpServletResponse.java @@ -8,7 +8,6 @@ import java.util.List; import java.util.regex.Pattern; import javax.servlet.ServletContext; -import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; @@ -18,6 +17,7 @@ import org.apache.commons.logging.LogFactory; import org.openrdf.model.URI; import org.openrdf.model.impl.URIImpl; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapperFactory; @@ -36,7 +36,7 @@ public class URLRewritingHttpServletResponse extends HttpServletResponseWrapper/ super(response); this._response = response; this._context = context; - this.wadf = (WebappDaoFactory) context.getAttribute("webappDaoFactory"); + this.wadf = ModelAccess.on(context).getWebappDaoFactory(); this.contextPathDepth = slashPattern.split(request.getContextPath()).length-1; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java deleted file mode 100644 index f1d7a6e71..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/VitroRequestPrep.java +++ /dev/null @@ -1,360 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filters; - -import static edu.cornell.mannlib.vitro.webapp.controller.VitroRequest.SPECIAL_WRITE_MODEL; -import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.CONTEXT_DISPLAY_TBOX; -import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.DISPLAY_ONT_MODEL; -import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.SWITCH_TO_DISPLAY_MODEL; -import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.USE_DISPLAY_MODEL_PARAM; -import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.USE_MODEL_PARAM; -import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.USE_TBOX_MODEL_PARAM; - -import java.io.IOException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.sql.DataSource; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.query.Dataset; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; - -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.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; -import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering; -import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.FilterFactory; -import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.HideFromDisplayByPolicyFilter; -import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; -import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; - -/** - * This sets up several objects in the Request scope for each - * incoming HTTP request. This is done in a Filter so - * that controllers and JSPs get the same setup. - * - * This code configures the WebappDaoFactory for each request. - * - * @author bdc34 - * - */ -public class VitroRequestPrep implements Filter { - private static final Log log = LogFactory.getLog(VitroRequestPrep.class.getName()); - - /** - * The filter will be applied to all incoming requests, but should skip any - * request whose URI matches any of these patterns. These are matched - * against the requestURI without query parameters, e.g. "/vitro/index.jsp" - * "/vitro/themes/enhanced/css/edit.css" - */ - private static final Pattern[] skipPatterns = { - Pattern.compile(".*\\.(gif|GIF|jpg|jpeg)$"), - Pattern.compile(".*\\.css$"), - Pattern.compile(".*\\.js$"), - Pattern.compile("/.*/themes/.*/site_icons/.*"), - Pattern.compile("/.*/images/.*") - }; - - private ServletContext _context; - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - _context = filterConfig.getServletContext(); - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - // If this isn't an HttpServletRequest, we might as well fail now. - HttpServletRequest req = (HttpServletRequest) request; - HttpServletResponse resp = (HttpServletResponse) response; - logRequestUriForDebugging(req); - - //don't waste time running this filter again. - if( req.getAttribute("VitroRequestPrep.setup") != null ){ - log.debug("VitroRequestPrep has already been executed at least once, not re-executing."); - Integer a =(Integer) req.getAttribute("VitroRequestPrep.setup"); - req.setAttribute("VitroRequestPrep.setup", new Integer( a + 1 ) ); - chain.doFilter(req, response); - return; - } - - // don't run this filter for image files, CSS files, etc. - for( Pattern skipPattern : skipPatterns){ - Matcher match =skipPattern.matcher( req.getRequestURI() ); - if( match.matches() ){ - log.debug("request matched a skipPattern, skipping VitroRequestPrep"); - chain.doFilter(req, response); - return; - } - } - - // If we're not authorized for this request, skip the chain and redirect. - if (!authorizedForSpecialModel(req)) { - VitroHttpServlet.redirectUnauthorizedRequest(req, resp); - return; - } - - VitroRequest vreq = new VitroRequest(req); - - //-- setup DAO factory --// - WebappDaoFactory wdf = getWebappDaoFactory(vreq); - //TODO: get accept-language from request and set as preferred languages - - // if there is a WebappDaoFactory in the session, use it - Object o = req.getSession().getAttribute("webappDaoFactory"); - if (o instanceof WebappDaoFactory) { - wdf = (WebappDaoFactory) o; - log.debug("Found a WebappDaoFactory in the session and using it for this request"); - } - - //Do model switching and replace the WebappDaoFactory with - //a different version if requested by parameters - wdf = checkForModelSwitching(vreq, wdf); - - //get any filters from the ContextFitlerFactory - VitroFilters filters = getFiltersFromContextFilterFactory(req, wdf); - if( filters != null ){ - log.debug("Wrapping WebappDaoFactory in filters from ContextFitlerFactory"); - wdf = new WebappDaoFactoryFiltering(wdf, filters); - } - - /* - * display filtering happens now at any level, all the time; editing - * pages get their WebappDaoFactories differently - */ - HideFromDisplayByPolicyFilter filter = new HideFromDisplayByPolicyFilter( - RequestIdentifiers.getIdBundleForRequest(req), - ServletPolicyList.getPolicies(_context)); - vreq.setWebappDaoFactory(new WebappDaoFactoryFiltering(wdf, filter)); - - // support for Dataset interface if using Jena in-memory model - if (vreq.getDataset() == null) { - Dataset dataset = WebappDaoFactoryJena.makeInMemoryDataset( - vreq.getAssertionsOntModel(), vreq.getInferenceOntModel()); - vreq.setDataset(dataset); - } - - ServletContext ctx = vreq.getSession().getServletContext(); - - if (vreq.getUnfilteredWebappDaoFactory() == null) { - vreq.setUnfilteredWebappDaoFactory(new WebappDaoFactorySDB( - RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService(), - ModelContext.getUnionOntModelSelector( - ctx))); - } - - req.setAttribute("VitroRequestPrep.setup", new Integer(1)); - chain.doFilter(req, response); - } - - private WebappDaoFactory getWebappDaoFactory(VitroRequest vreq){ - WebappDaoFactory webappDaoFactory = vreq.getWebappDaoFactory(); - return (webappDaoFactory != null) ? webappDaoFactory : - (WebappDaoFactory) _context.getAttribute("webappDaoFactory"); - } - - private VitroFilters getFiltersFromContextFilterFactory( HttpServletRequest request, WebappDaoFactory wdf){ - FilterFactory ff = (FilterFactory)_context.getAttribute("FilterFactory"); - if( ff == null ){ - return null; - } else { - return ff.getFilters(request, wdf); - } - } - - private boolean authorizedForSpecialModel(HttpServletRequest req) { - if (isParameterPresent(req, SWITCH_TO_DISPLAY_MODEL)) { - return PolicyHelper.isAuthorizedForActions(req, SimplePermission.MANAGE_MENUS.ACTIONS); - } else if (anyOtherSpecialProperties(req)){ - return PolicyHelper.isAuthorizedForActions(req, SimplePermission.ACCESS_SPECIAL_DATA_MODELS.ACTIONS); - } else { - return true; - } - } - - @Override - public void destroy() { - // Nothing to do. - } - - /** - * Check if special model is requested - this is for enabling the use of a different - * model for menu management. Also enables the use of a completely different - * model and tbox if uris are passed. - */ - private WebappDaoFactory checkForModelSwitching(VitroRequest vreq, WebappDaoFactory inputWadf) { - //TODO: Does the dataset in the vreq get set when using a special WDF? Does it need to? - //TODO: Does the unfiltered WDF get set when using a special WDF? Does it need to? - - // If this isn't a Jena WADF, then there's nothing to be done. - if (!(inputWadf instanceof WebappDaoFactoryJena)) { - log.warn("Can't set special models: " + - "WebappDaoFactory is not a WebappDaoFactoryJena"); - removeSpecialWriteModel(vreq); - return inputWadf; - } - - WebappDaoFactoryJena wadf = (WebappDaoFactoryJena) inputWadf; - - // If they asked for the display model, give it to them. - if (isParameterPresent(vreq, SWITCH_TO_DISPLAY_MODEL)) { - OntModel mainOntModel = (OntModel)_context.getAttribute( DISPLAY_ONT_MODEL); - OntModel tboxOntModel = (OntModel) _context.getAttribute(CONTEXT_DISPLAY_TBOX); - setSpecialWriteModel(vreq, mainOntModel); - - vreq.setAttribute(VitroRequest.ID_FOR_ABOX_MODEL, VitroModelSource.ModelName.DISPLAY.toString()); - vreq.setAttribute(VitroRequest.ID_FOR_TBOX_MODEL, VitroModelSource.ModelName.DISPLAY_TBOX.toString()); - vreq.setAttribute(VitroRequest.ID_FOR_DISPLAY_MODEL, VitroModelSource.ModelName.DISPLAY_DISPLAY.toString()); - vreq.setAttribute(VitroRequest.ID_FOR_WRITE_MODEL, VitroModelSource.ModelName.DISPLAY.toString()); - - return createNewWebappDaoFactory(wadf, mainOntModel, tboxOntModel, null); - } - - // If they asked for other models by URI, set them. - if (anyOtherSpecialProperties(vreq)) { - DataSource bds = JenaDataSourceSetupBase.getApplicationDataSource(_context); - String dbType = ConfigurationProperties.getBean(_context) - .getProperty("VitroConnection.DataSource.dbtype", "MySQL"); - - OntModel mainOntModel = createSpecialModel(vreq, USE_MODEL_PARAM, bds, dbType); - OntModel tboxOntModel = createSpecialModel(vreq, USE_TBOX_MODEL_PARAM, bds, dbType); - OntModel displayOntModel = createSpecialModel(vreq, USE_DISPLAY_MODEL_PARAM, bds, dbType); - - vreq.setAttribute(VitroRequest.ID_FOR_ABOX_MODEL, vreq.getParameter(USE_MODEL_PARAM)); - vreq.setAttribute(VitroRequest.ID_FOR_WRITE_MODEL, vreq.getParameter(USE_MODEL_PARAM)); - vreq.setAttribute(VitroRequest.ID_FOR_TBOX_MODEL, vreq.getParameter(USE_TBOX_MODEL_PARAM)); - vreq.setAttribute(VitroRequest.ID_FOR_DISPLAY_MODEL, vreq.getParameter(USE_DISPLAY_MODEL_PARAM)); - - setSpecialWriteModel(vreq, mainOntModel); - return createNewWebappDaoFactory(wadf, mainOntModel, tboxOntModel, displayOntModel); - } - - // Otherwise, there's nothing special about this request. - removeSpecialWriteModel(vreq); - return wadf; - - } - - private boolean anyOtherSpecialProperties(HttpServletRequest req) { - return isParameterPresent(req, USE_MODEL_PARAM) - || isParameterPresent(req, USE_TBOX_MODEL_PARAM) - || isParameterPresent(req, USE_DISPLAY_MODEL_PARAM); - } - - /** - * If the request asks for a special model by URI, create it from the - * Database. - * - * @return the model they asked for, or null if they didn't ask for one. - * @throws IllegalStateException - * if it's not found. - */ - private OntModel createSpecialModel(VitroRequest vreq, String key, - DataSource bds, String dbType) { - if (!isParameterPresent(vreq, key)) { - return null; - } - - String modelUri = vreq.getParameter(key); - Model model = JenaDataSourceSetupBase.makeDBModel(bds, modelUri, - OntModelSpec.OWL_MEM, - JenaDataSourceSetupBase.TripleStoreType.RDB, dbType, _context); - if (model != null) { - return ModelFactory - .createOntologyModel(OntModelSpec.OWL_MEM, model); - } else { - throw new IllegalStateException("Main Model Uri " + modelUri - + " did not retrieve model"); - } - } - - private void removeSpecialWriteModel(VitroRequest vreq) { - if (vreq.getAttribute(SPECIAL_WRITE_MODEL) != null) { - vreq.removeAttribute(SPECIAL_WRITE_MODEL); - } - } - - private void setSpecialWriteModel(VitroRequest vreq, OntModel mainOntModel) { - if (mainOntModel != null) { - vreq.setAttribute("jenaOntModel", mainOntModel); - vreq.setAttribute(SPECIAL_WRITE_MODEL, mainOntModel); - } - } - - /** - * The goal here is to return a new WDF that is set to - * have the mainOntModel as its ABox, the tboxOntModel as it - * TBox and displayOntModel as it display model. - * - * Right now this is achieved by creating a copy of - * the WADF, and setting the special models onto it. - * - * If a model is null, it will have no effect. - */ - private WebappDaoFactory createNewWebappDaoFactory( - WebappDaoFactoryJena inputWadf, OntModel mainOntModel, - OntModel tboxOntModel, OntModel displayOntModel) { - - WebappDaoFactoryJena wadfj = new WebappDaoFactoryJena(inputWadf); - wadfj.setSpecialDataModel(mainOntModel, tboxOntModel, displayOntModel); - return wadfj; - } - - private boolean isParameterPresent(HttpServletRequest req, String key) { - return getNonEmptyParameter(req, key) != null; - } - - /** - * Return a non-empty parameter from the request, or a null. - */ - private String getNonEmptyParameter(HttpServletRequest req, String key) { - String value = req.getParameter(key); - if ((value == null) || value.isEmpty()) { - return null; - } else { - return value; - } - } - - private void logRequestUriForDebugging(HttpServletRequest req) { - if (log.isDebugEnabled()) { - try { - String uriString = req.getRequestURI(); - String queryString = req.getQueryString(); - if ((queryString != null) && (queryString.length() > 0)) { - uriString += "?" + queryString; - } - log.debug("RequestURI: " + uriString); - } catch (Exception e) { - // Don't want to kill the request if the logging fails. - } - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java deleted file mode 100644 index 4bb7fda8e..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java +++ /dev/null @@ -1,165 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filters; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.query.Dataset; -import com.hp.hpl.jena.rdf.model.ModelFactory; - -import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; -import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; -import edu.cornell.mannlib.vitro.webapp.rdfservice.filter.LanguageFilteringRDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; - -public class WebappDaoFactorySDBPrep implements Filter { - - private final static Log log = LogFactory.getLog(WebappDaoFactorySDBPrep.class); - - ServletContext _ctx; - - /** - * The filter will be applied to all incoming urls, - this is a list of URI patterns to skip. These are - matched against the requestURI sans query parameters, - * e.g. - * "/vitro/index.jsp" - * "/vitro/themes/enhanced/css/edit.css" - * - * These patterns are from VitroRequestPrep.java - */ - Pattern[] skipPatterns = { - Pattern.compile(".*\\.(gif|GIF|jpg|jpeg)$"), - Pattern.compile(".*\\.css$"), - Pattern.compile(".*\\.js$"), - Pattern.compile("/.*/themes/.*/site_icons/.*"), - Pattern.compile("/.*/images/.*") - }; - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain filterChain) throws IOException, ServletException { - - if ( request.getAttribute("WebappDaoFactorySDBPrep.setup") != null ) { - // don't run multiple times - filterChain.doFilter(request, response); - return; - } - - for( Pattern skipPattern : skipPatterns){ - Matcher match =skipPattern.matcher( ((HttpServletRequest)request).getRequestURI() ); - if( match.matches() ){ - log.debug("request matched a skipPattern, skipping VitroRequestPrep"); - filterChain.doFilter(request, response); - return; - } - } - - OntModelSelector oms = ModelContext.getUnionOntModelSelector(_ctx); - OntModelSelector baseOms = ModelContext.getBaseOntModelSelector(_ctx); - String defaultNamespace = (String) _ctx.getAttribute("defaultNamespace"); - WebappDaoFactory wadf = null; - VitroRequest vreq = new VitroRequest((HttpServletRequest) request); - - List langs = new ArrayList(); - - log.debug("Accept-Language: " + vreq.getHeader("Accept-Language")); - Enumeration locs = vreq.getLocales(); - while (locs.hasMoreElements()) { - Locale locale = locs.nextElement(); - langs.add(locale.toString().replace("_", "-")); - } - if (langs.isEmpty()) { - langs.add("en"); - } - WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); - config.setDefaultNamespace(defaultNamespace); - config.setPreferredLanguages(langs); - - RDFServiceFactory factory = RDFServiceUtils.getRDFServiceFactory(_ctx); - - //RDFService rdfService = factory.getRDFService(); - RDFService unfilteredRDFService = factory.getShortTermRDFService(); - RDFService rdfService = null; - - if (!"false".equals( - ConfigurationProperties.getBean(vreq).getProperty( - "RDFService.languageFilter", "true"))) { - rdfService = new LanguageFilteringRDFService(unfilteredRDFService, langs); - } else { - rdfService = unfilteredRDFService; - } - - Dataset dataset = new RDFServiceDataset(rdfService); - wadf = new WebappDaoFactorySDB(rdfService, oms, config); - WebappDaoFactory assertions = new WebappDaoFactorySDB( - rdfService, baseOms, config, SDBDatasetMode.ASSERTIONS_ONLY); - vreq.setRDFService(rdfService); - vreq.setUnfilteredRDFService(unfilteredRDFService); - vreq.setWebappDaoFactory(wadf); - vreq.setAssertionsWebappDaoFactory(assertions); - vreq.setFullWebappDaoFactory(wadf); - vreq.setUnfilteredWebappDaoFactory(new WebappDaoFactorySDB( - rdfService, ModelContext.getUnionOntModelSelector(_ctx))); - vreq.setDataset(dataset); - vreq.setOntModelSelector(baseOms); - - vreq.setJenaOntModel(ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, dataset.getDefaultModel())); - - request.setAttribute("WebappDaoFactorySDBPrep.setup", 1); - - try { - filterChain.doFilter(request, response); - return; - } finally { - if (wadf != null) { - wadf.close(); - } - } - - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - try { - _ctx = filterConfig.getServletContext(); - } catch (Throwable t) { - log.error("Unable to initialize WebappDaoFactorySDBPrep", t); - } - } - - @Override - public void destroy() { - // no destroy actions - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySparqlPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySparqlPrep.java deleted file mode 100644 index 770fb8c5a..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySparqlPrep.java +++ /dev/null @@ -1,210 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.filters; - -import java.io.IOException; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.graph.Graph; -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.query.DataSource; -import com.hp.hpl.jena.query.Dataset; -import com.hp.hpl.jena.query.DatasetFactory; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.sdb.SDBFactory; -import com.hp.hpl.jena.sdb.Store; -import com.hp.hpl.jena.sdb.StoreDesc; -import com.hp.hpl.jena.sdb.sql.SDBConnection; - -import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; -import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; -import edu.cornell.mannlib.vitro.webapp.dao.jena.SingleContentOntModelSelector; -import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlDatasetGraph; -import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraphMultilingual; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; - -public class WebappDaoFactorySparqlPrep implements Filter { - - private final static Log log = LogFactory.getLog(WebappDaoFactorySparqlPrep.class); - - ServletContext _ctx; - - /** - * The filter will be applied to all incoming urls, - this is a list of URI patterns to skip. These are - matched against the requestURI sans query parameters, - * e.g. - * "/vitro/index.jsp" - * "/vitro/themes/enhanced/css/edit.css" - * - * These patterns are from VitroRequestPrep.java - */ - Pattern[] skipPatterns = { - Pattern.compile(".*\\.(gif|GIF|jpg|jpeg)$"), - Pattern.compile(".*\\.css$"), - Pattern.compile(".*\\.js$"), - Pattern.compile("/.*/themes/.*/site_icons/.*"), - Pattern.compile("/.*/images/.*") - }; - - @Override - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain filterChain) throws IOException, ServletException { - - if ( request.getAttribute("WebappDaoFactorySDBPrep.setup") != null ) { - // don't run multiple times - filterChain.doFilter(request, response); - return; - } - - for( Pattern skipPattern : skipPatterns){ - Matcher match =skipPattern.matcher( ((HttpServletRequest)request).getRequestURI() ); - if( match.matches() ){ - log.debug("request matched a skipPattern, skipping VitroRequestPrep"); - filterChain.doFilter(request, response); - return; - } - } - - javax.sql.DataSource ds = JenaDataSourceSetupBase.getApplicationDataSource(_ctx); - StoreDesc storeDesc = (StoreDesc) _ctx.getAttribute("storeDesc"); - OntModelSelector oms = (OntModelSelector) _ctx.getAttribute("unionOntModelSelector"); - String defaultNamespace = (String) _ctx.getAttribute("defaultNamespace"); - Connection sqlConn = null; - SDBConnection conn = null; - Store store = null; - Dataset dataset = null; - WebappDaoFactory wadf = null; - - try { - if (ds == null || storeDesc == null || oms == null) { - throw new RuntimeException("SDB store not property set up"); - } - - try { - sqlConn = ds.getConnection(); - conn = new SDBConnection(sqlConn) ; - } catch (SQLException sqe) { - throw new RuntimeException("Unable to connect to database", sqe); - } - if (conn != null) { - store = SDBFactory.connectStore(conn, storeDesc); - dataset = SDBFactory.connectDataset(store); - VitroRequest vreq = new VitroRequest((HttpServletRequest) request); - - log.info("---------"); - - Enumeration headStrs = vreq.getHeaderNames(); - while (headStrs.hasMoreElements()) { - String head = headStrs.nextElement(); - log.info(head + " : " + vreq.getHeader(head)); - } - - List langs = new ArrayList(); - - log.info("Accept-Language: " + vreq.getHeader("Accept-Language")); - Enumeration locs = vreq.getLocales(); - while (locs.hasMoreElements()) { - Locale locale = locs.nextElement(); - langs.add(locale.toString().replace("_", "-")); - log.info(locale.toString() + " / " + locale.getLanguage() + " + " + locale.getCountry() + " : " + locale.getDisplayCountry() + " | " + locale.getLanguage() + " : " + locale.getDisplayLanguage()); - } - WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); - config.setDefaultNamespace(defaultNamespace); - config.setPreferredLanguages(langs); - - //okay let's make a graph-backed model - String endpointURI = ConfigurationProperties.getBean( - request).getProperty("VitroConnection.DataSource.endpointURI"); - - Graph g = new SparqlGraphMultilingual(endpointURI, langs); - //Graph g = new SparqlGraph(endpointURI); - - Model m = ModelFactory.createModelForGraph(g); - OntModel om = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, m); - oms = new SingleContentOntModelSelector(om, oms.getDisplayModel(), oms.getUserAccountsModel()); - - dataset = DatasetFactory.create(new SparqlDatasetGraph(endpointURI)); - - //DataSource datasource = DatasetFactory.create(); - //datasource.addNamedModel("fake:fake", m); - //dataset = datasource; - - vreq.setAssertionsWebappDaoFactory(wadf); - - wadf = new WebappDaoFactoryJena(oms, config); - //wadf = new WebappDaoFactorySDB(oms, dataset, config); - vreq.setWebappDaoFactory(wadf); - vreq.setFullWebappDaoFactory(wadf); - vreq.setUnfilteredWebappDaoFactory(wadf); - vreq.setWebappDaoFactory(wadf); - vreq.setDataset(dataset); - vreq.setJenaOntModel(om); - vreq.setOntModelSelector(oms); - } - } catch (Throwable t) { - log.error("Unable to filter request to set up SDB connection", t); - } - - request.setAttribute("WebappDaoFactorySDBPrep.setup", 1); - - try { - filterChain.doFilter(request, response); - return; - } finally { - if (conn != null) { - conn.close(); - } - if (dataset != null) { - dataset.close(); - } - if (store != null) { - store.close(); - } - if (wadf != null) { - wadf.close(); - } - } - - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - try { - _ctx = filterConfig.getServletContext(); - } catch (Throwable t) { - log.error("Unable to initialize WebappDaoFactorySDBPrep", t); - } - } - - @Override - public void destroy() { - // no destroy actions - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18n.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18n.java index 3bc2d6045..38a1bc059 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18n.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18n.java @@ -7,7 +7,6 @@ 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; @@ -34,6 +33,13 @@ public class I18n { public static final String DEFAULT_BUNDLE_NAME = "all"; private static final String PROPERTY_DEVELOPER_DEFEAT_CACHE = "developer.defeatI18nCache"; + /** + * If this attribute is present on the request, then the cache has already + * been cleared. + */ + private static final String ATTRIBUTE_CACHE_CLEARED = I18n.class.getName() + + "-cacheCleared"; + /** * This is where the work gets done. Not declared final, so it can be * modified in unit tests. @@ -91,8 +97,10 @@ public class I18n { * cache is cleared on each request. * * If the theme directory has changed, the cache is cleared. + * + * Declared 'protected' so it can be overridden in unit tests. */ - private I18nBundle getBundle(String bundleName, HttpServletRequest req) { + protected I18nBundle getBundle(String bundleName, HttpServletRequest req) { log.debug("Getting bundle '" + bundleName + "'"); try { @@ -102,7 +110,7 @@ public class I18n { String dir = themeDirectory.get(); ServletContext ctx = req.getSession().getServletContext(); - ResourceBundle.Control control = getControl(ctx, dir); + ResourceBundle.Control control = new ThemeBasedControl(ctx, dir); ResourceBundle rb = ResourceBundle.getBundle(bundleName, req.getLocale(), control); return new I18nBundle(bundleName, rb); @@ -125,7 +133,7 @@ public class I18n { .getProperty(PROPERTY_DEVELOPER_DEFEAT_CACHE, "false"); if (Boolean.valueOf(flag.trim())) { log.debug("In development mode - clearing the cache."); - ResourceBundle.clearCache(); + clearCacheOnRequest(req); } } @@ -139,16 +147,19 @@ public class I18n { if (!currentDir.equals(previousDir)) { log.debug("Theme directory changed from '" + previousDir + "' to '" + currentDir + "' - clearing the cache."); - ResourceBundle.clearCache(); + clearCacheOnRequest(req); } } - /** - * 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); + /** Only clear the cache one time per request. */ + private void clearCacheOnRequest(HttpServletRequest req) { + if (req.getAttribute(ATTRIBUTE_CACHE_CLEARED) != null) { + log.debug("Cache was already cleared on this request."); + } else { + ResourceBundle.clearCache(); + log.debug("Cache cleared."); + req.setAttribute(ATTRIBUTE_CACHE_CLEARED, Boolean.TRUE); + } } // ---------------------------------------------------------------------- diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18nBundle.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18nBundle.java index 7ea5acc3d..44b930089 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18nBundle.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/I18nBundle.java @@ -39,8 +39,9 @@ public class I18nBundle { public I18nBundle(String bundleName, ResourceBundle resources) { this(bundleName, resources, MESSAGE_KEY_NOT_FOUND); } - - private I18nBundle(String bundleName, ResourceBundle resources, String notFoundMessage) { + + private I18nBundle(String bundleName, ResourceBundle resources, + String notFoundMessage) { if (bundleName == null) { throw new IllegalArgumentException("bundleName may not be null"); } @@ -49,20 +50,22 @@ public class I18nBundle { } if (resources == null) { throw new NullPointerException("resources may not be null."); - }if (notFoundMessage == 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); + log.debug("In '" + bundleName + "', " + key + "='" + textString + + "')"); return formatString(textString, parameters); } else { String message = MessageFormat.format(notFoundMessage, bundleName, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/VitroResourceBundle.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/VitroResourceBundle.java index c9b2b2acb..93a7131ca 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/VitroResourceBundle.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/VitroResourceBundle.java @@ -53,6 +53,23 @@ public class VitroResourceBundle extends ResourceBundle { // Factory method // ---------------------------------------------------------------------- + /** + * Returns the bundle for the for foo_ba_RR, providing that + * foo_ba_RR.properties exists in the I18n area of either the theme or the + * application. + * + * If the desired file doesn't exist in either location, return null. + * Usually, this does not indicate a problem but only that we were looking + * for too specific a bundle. For example, if the base name of the bundle is + * "all" and the locale is "en_US", we will likely return null on the search + * for all_en_US.properties, and all_en.properties, but will return a full + * bundle for all.properties. + * + * Of course, if all.properties doesn't exist either, then we have a + * problem, but that will be reported elsewhere. + * + * @return the populated bundle or null. + */ public static VitroResourceBundle getBundle(String bundleName, ServletContext ctx, String appI18nPath, String themeI18nPath, Control control) { @@ -60,7 +77,7 @@ public class VitroResourceBundle extends ResourceBundle { return new VitroResourceBundle(bundleName, ctx, appI18nPath, themeI18nPath, control); } catch (FileNotFoundException e) { - log.debug(e); + log.debug(e.getMessage()); return null; } catch (Exception e) { log.warn(e, e); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionController.java index 523a263a2..76bf70012 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectionController.java @@ -18,6 +18,7 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; +import edu.cornell.mannlib.vitro.webapp.i18n.I18n; /** * Call this at /selectLocale&selection=[locale_string] @@ -75,8 +76,7 @@ public class LocaleSelectionController extends HttpServlet { } 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."); + I18n.bundle(req).text("language_selection_failed")); return; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectorUtilities.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectorUtilities.java index 0e5eeb492..d7f93f937 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectorUtilities.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/i18n/selection/LocaleSelectorUtilities.java @@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.i18n.selection; import java.io.FileNotFoundException; import java.util.Locale; +import java.util.Set; import javax.servlet.ServletContext; @@ -40,13 +41,16 @@ public class LocaleSelectorUtilities { 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; + @SuppressWarnings("unchecked") + Set resourcePaths = ctx.getResourcePaths(imageDirPath); + if (resourcePaths != null) { + for (String resourcePath : resourcePaths) { + 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); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringRDFService.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringRDFService.java index 1df269857..936462153 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringRDFService.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringRDFService.java @@ -8,8 +8,10 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Enumeration; import java.util.Iterator; import java.util.List; +import java.util.Locale; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -368,17 +370,20 @@ public class LanguageFilteringRDFService implements RDFService { int index = langs.indexOf(lang); if (index >= 0) { + log.debug("languageIndex for '" + lang + "' is " + index); return index; } if (lang.length() > 2) { index = langs.indexOf(lang.substring(0, 2)); if (index >= 0) { + log.debug("languageIndex for '" + lang + "' is " + index + inexactMatchPenalty); return index + inexactMatchPenalty; } } if (lang.isEmpty()) { + log.debug("languageIndex for '" + lang + "' is " + noLanguage); return noLanguage; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringUtils.java new file mode 100644 index 000000000..a1e2e879d --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringUtils.java @@ -0,0 +1,63 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.rdfservice.filter; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; + +import javax.servlet.ServletRequest; + +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.rdf.model.ModelFactory; + +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel; + +/** + * Some methods that will come in handy when dealing with Language Filtering + */ +public class LanguageFilteringUtils { + + /** + * Take an Enumeration of Locale objects, such as we might get from a + * request, and convert to a List of langauage strings, such as are needed + * by the LanguageFilteringRDFService. + * + * While converting, change all underscores (as in Locale names) to hyphens + * (as in RDF language specifiers). + */ + public static List localesToLanguages(Enumeration locales) { + List langs = new ArrayList<>(); + while (locales.hasMoreElements()) { + Locale locale = (Locale) locales.nextElement(); + langs.add(locale.toString().replace("_", "-")); + } + if (langs.isEmpty()) { + langs.add("en"); + } + return langs; + + } + + /** + * Add a Language Filtering layer to an OntModel by treating it as an RDFService. + */ + public static OntModel wrapOntModelInALanguageFilter(OntModel rawModel, + ServletRequest req) { + /** This is some nasty layering. Could we do this more easily? */ + List languages = localesToLanguages(req.getLocales()); + return ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, + RDFServiceGraph.createRDFServiceModel( + new RDFServiceGraph( + new LanguageFilteringRDFService( + new RDFServiceModel(rawModel), languages)))); + } + + private LanguageFilteringUtils() { + // Nothing to instantiate + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/PagedSearchController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/PagedSearchController.java index d85ba6ada..b74979164 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/PagedSearchController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/controller/PagedSearchController.java @@ -70,6 +70,7 @@ public class PagedSearchController extends FreemarkerHttpServlet { protected static final int DEFAULT_MAX_HIT_COUNT = 1000; private static final String PARAM_XML_REQUEST = "xml"; + private static final String PARAM_CSV_REQUEST = "csv"; private static final String PARAM_START_INDEX = "startIndex"; private static final String PARAM_HITS_PER_PAGE = "hitsPerPage"; private static final String PARAM_CLASSGROUP = "classgroup"; @@ -79,7 +80,7 @@ public class PagedSearchController extends FreemarkerHttpServlet { protected static final Map> templateTable; protected enum Format { - HTML, XML; + HTML, XML, CSV; } protected enum Result { @@ -101,14 +102,27 @@ public class PagedSearchController extends FreemarkerHttpServlet { throws IOException, ServletException { VitroRequest vreq = new VitroRequest(request); boolean wasXmlRequested = isRequestedFormatXml(vreq); - if( ! wasXmlRequested ){ + boolean wasCSVRequested = isRequestedFormatCSV(vreq); + if( !wasXmlRequested && !wasCSVRequested){ super.doGet(vreq,response); - }else{ + }else if (wasXmlRequested){ try { ResponseValues rvalues = processRequest(vreq); response.setCharacterEncoding("UTF-8"); response.setContentType("text/xml;charset=UTF-8"); + response.setHeader("Content-Disposition", "attachment; filename=search.xml"); + writeTemplate(rvalues.getTemplateName(), rvalues.getMap(), request, response); + } catch (Exception e) { + log.error(e, e); + } + }else if (wasCSVRequested){ + try { + ResponseValues rvalues = processRequest(vreq); + + response.setCharacterEncoding("UTF-8"); + response.setContentType("text/csv;charset=UTF-8"); + response.setHeader("Content-Disposition", "attachment; filename=search.csv"); writeTemplate(rvalues.getTemplateName(), rvalues.getMap(), request, response); } catch (Exception e) { log.error(e, e); @@ -122,8 +136,9 @@ public class PagedSearchController extends FreemarkerHttpServlet { //There may be other non-html formats in the future Format format = getFormat(vreq); boolean wasXmlRequested = Format.XML == format; + boolean wasCSVRequested = Format.CSV == format; log.debug("Requested format was " + (wasXmlRequested ? "xml" : "html")); - boolean wasHtmlRequested = ! wasXmlRequested; + boolean wasHtmlRequested = ! (wasXmlRequested || wasCSVRequested); try { @@ -211,7 +226,8 @@ public class PagedSearchController extends FreemarkerHttpServlet { Map body = new HashMap(); - String classGroupParam = vreq.getParameter(PARAM_CLASSGROUP); + String classGroupParam = vreq.getParameter(PARAM_CLASSGROUP); + log.debug("Query text is \""+ classGroupParam + "\""); boolean classGroupFilterRequested = false; if (!StringUtils.isEmpty(classGroupParam)) { VClassGroup grp = grpDao.getGroupByURI(classGroupParam); @@ -671,10 +687,25 @@ public class PagedSearchController extends FreemarkerHttpServlet { return false; } } + + protected boolean isRequestedFormatCSV(VitroRequest req){ + if( req != null ){ + String param = req.getParameter(PARAM_CSV_REQUEST); + if( param != null && "1".equals(param)){ + return true; + }else{ + return false; + } + }else{ + return false; + } + } protected Format getFormat(VitroRequest req){ if( req != null && req.getParameter("xml") != null && "1".equals(req.getParameter("xml"))) return Format.XML; + else if ( req != null && req.getParameter("csv") != null && "1".equals(req.getParameter("csv"))) + return Format.CSV; else return Format.HTML; } @@ -704,9 +735,20 @@ public class PagedSearchController extends FreemarkerHttpServlet { resultsToTemplates = new HashMap(); resultsToTemplates.put(Result.PAGED, "search-xmlResults.ftl"); resultsToTemplates.put(Result.ERROR, "search-xmlError.ftl"); + // resultsToTemplates.put(Result.BAD_QUERY, "search-xmlBadQuery.ftl"); templateTable.put(Format.XML, Collections.unmodifiableMap(resultsToTemplates)); + + // set up CSV format + resultsToTemplates = new HashMap(); + resultsToTemplates.put(Result.PAGED, "search-csvResults.ftl"); + resultsToTemplates.put(Result.ERROR, "search-csvError.ftl"); + + // resultsToTemplates.put(Result.BAD_QUERY, "search-xmlBadQuery.ftl"); + templateTable.put(Format.CSV, Collections.unmodifiableMap(resultsToTemplates)); + + return Collections.unmodifiableMap(templateTable); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/solr/SolrSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/solr/SolrSetup.java index b0dcacf6d..5f4e7493b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/search/solr/SolrSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/search/solr/SolrSetup.java @@ -2,7 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.search.solr; -import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; @@ -11,19 +10,16 @@ import java.util.List; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer; import org.apache.solr.client.solrj.impl.XMLResponseParser; import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.vocabulary.OWL; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.filtering.WebappDaoFactoryFiltering; @@ -32,8 +28,6 @@ import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; -import edu.cornell.mannlib.vitro.webapp.search.beans.FileBasedProhibitedFromSearch; -import edu.cornell.mannlib.vitro.webapp.search.beans.ProhibitedFromSearch; import edu.cornell.mannlib.vitro.webapp.search.beans.StatementToURIsToUpdate; import edu.cornell.mannlib.vitro.webapp.search.indexing.AdditionalURIsForContextNodes; import edu.cornell.mannlib.vitro.webapp.search.indexing.AdditionalURIsForDataProperties; @@ -120,8 +114,8 @@ public class SolrSetup implements javax.servlet.ServletContextListener{ context.setAttribute(SOLR_SERVER, server); /* set up the individual to solr doc translation */ - OntModel jenaOntModel = ModelContext.getJenaOntModel(context); - Model displayModel = ModelContext.getDisplayModel(context); + OntModel jenaOntModel = ModelAccess.on(context).getJenaOntModel(); + OntModel displayModel = ModelAccess.on(context).getDisplayModel(); /* try to get context attribute DocumentModifiers * and use that as the start of the list of DocumentModifier @@ -151,7 +145,7 @@ public class SolrSetup implements javax.servlet.ServletContextListener{ // This is where the builder gets the list of places to try to // get objects to index. It is filtered so that non-public text // does not get into the search index. - WebappDaoFactory wadf = (WebappDaoFactory) context.getAttribute("webappDaoFactory"); + WebappDaoFactory wadf = ModelAccess.on(context).getWebappDaoFactory(); VitroFilters vf = VitroFilterUtils.getPublicFilter(context); wadf = new WebappDaoFactoryFiltering(wadf, vf); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ApplicationModelSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ApplicationModelSetup.java index 15fc6a49f..366cbc5d6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ApplicationModelSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ApplicationModelSetup.java @@ -9,7 +9,6 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.sql.DataSource; -import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.joda.time.DateTime; @@ -23,7 +22,8 @@ import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; @@ -63,8 +63,8 @@ implements ServletContextListener { } OntModel displayModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC); displayModel.add(displayDbModel); - displayModel.getBaseModel().register(new ModelSynchronizer(displayDbModel)); - ModelContext.setDisplayModel(displayModel, ctx); + displayModel.getBaseModel().register(new ModelSynchronizer(displayDbModel)); + ModelAccess.on(ctx).setDisplayModel(displayModel); //at each startup load all RDF files from directory to sub-models of display model initializeDisplayLoadedAtStartup(ctx, displayModel); @@ -84,7 +84,7 @@ implements ServletContextListener { MEM_ONT_MODEL_SPEC); appTBOXModel.add(displayTboxModel); appTBOXModel.getBaseModel().register(new ModelSynchronizer(displayTboxModel)); - ctx.setAttribute("displayOntModelTBOX", appTBOXModel); + ModelAccess.on(ctx).setOntModel(ModelID.DISPLAY_TBOX, appTBOXModel); log.debug("Loaded file " + APPPATH_LOAD + "displayTBOX.n3 into display tbox model"); } catch (Throwable t) { log.error("Unable to load user application configuration model TBOX", t); @@ -102,7 +102,7 @@ implements ServletContextListener { MEM_ONT_MODEL_SPEC); appDisplayDisplayModel.add(displayDisplayModel); appDisplayDisplayModel.getBaseModel().register(new ModelSynchronizer(displayDisplayModel)); - ctx.setAttribute("displayOntModelDisplayModel", appDisplayDisplayModel); + ModelAccess.on(ctx).setOntModel(ModelID.DISPLAY_DISPLAY, appDisplayDisplayModel); log.debug("Loaded file " + APPPATH_LOAD + "displayDisplay.n3 into display display model"); } catch (Throwable t) { log.error("Unable to load user application configuration model Display Model", t); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/AssembleModelsSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/AssembleModelsSetup.java index e9dbc9f20..d95c4fc68 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/AssembleModelsSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/AssembleModelsSetup.java @@ -22,6 +22,7 @@ import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.util.iterator.ExtendedIterator; import com.hp.hpl.jena.vocabulary.RDF; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer; /** @@ -42,14 +43,7 @@ public class AssembleModelsSetup implements ServletContextListener { private String SYNTAX = "N3"; public void contextInitialized(ServletContextEvent sce) { - - OntModel jenaOntModel = null; - try { - jenaOntModel = (OntModel) sce.getServletContext().getAttribute("baseOntModel"); - } catch (Exception e) { - log.error("No baseOntModel found to which to attach assembled models"); - return; - } + OntModel jenaOntModel = ModelAccess.on(sce.getServletContext()).getBaseOntModel(); // read assemblers out of assemblers directory Set pathSet = sce.getServletContext().getResourcePaths(ASSEMBLERS_DIR_PATH); for (String path : (Set)pathSet) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ContentModelSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ContentModelSetup.java new file mode 100644 index 000000000..06ebcdc63 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ContentModelSetup.java @@ -0,0 +1,262 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.servlet.setup; + +import static edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode.ASSERTIONS_ONLY; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.graph.BulkUpdateHandler; +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.ResIterator; +import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.shared.Lock; +import com.hp.hpl.jena.util.ResourceUtils; +import com.hp.hpl.jena.vocabulary.RDF; + +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.FactoryID; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; +import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer; +import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; +import edu.cornell.mannlib.vitro.webapp.dao.jena.SpecialBulkUpdateHandlerGraph; +import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; +import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; +import edu.cornell.mannlib.vitro.webapp.utils.jena.InitialJenaModelUtils; + +/** + * Sets up the content models, OntModelSelectors and webapp DAO factories. + */ +public class ContentModelSetup extends JenaDataSourceSetupBase + implements javax.servlet.ServletContextListener { + + private static final Log log = LogFactory.getLog(ContentModelSetup.class); + + @Override + public void contextInitialized(ServletContextEvent sce) { + ServletContext ctx = sce.getServletContext(); + StartupStatus ss = StartupStatus.getBean(ctx); + + long begin = System.currentTimeMillis(); + setUpJenaDataSource(ctx); + ss.info(this, secondsSince(begin) + " seconds to set up models and DAO factories"); + } + + private void setUpJenaDataSource(ServletContext ctx) { + RDFServiceFactory rdfServiceFactory = RDFServiceUtils.getRDFServiceFactory(ctx); + RDFService rdfService = rdfServiceFactory.getRDFService(); + Dataset dataset = new RDFServiceDataset(rdfService); + setStartupDataset(dataset, ctx); + + OntModel applicationMetadataModel = createdMemoryMappedModel(dataset, JENA_APPLICATION_METADATA_MODEL, "application metadata model"); + if (applicationMetadataModel.size()== 0) { + JenaDataSourceSetupBase.thisIsFirstStartup(); + } + + ModelAccess models = ModelAccess.on(ctx); + OntModel baseABoxModel = createNamedModelFromDataset(dataset, JENA_DB_MODEL); + OntModel inferenceABoxModel = createNamedModelFromDataset(dataset, JENA_INF_MODEL); + OntModel baseTBoxModel = createdMemoryMappedModel(dataset, JENA_TBOX_ASSERTIONS_MODEL, "tbox assertions"); + OntModel inferenceTBoxModel = createdMemoryMappedModel(dataset, JENA_TBOX_INF_MODEL, "tbox inferences"); + OntModel unionABoxModel = createCombinedBulkUpdatingModel(baseABoxModel, inferenceABoxModel); + OntModel unionTBoxModel = createCombinedBulkUpdatingModel(baseTBoxModel, inferenceTBoxModel); + + if (isFirstStartup()) { + loadInitialApplicationMetadataModel(applicationMetadataModel, ctx); + loadDataFromFilesystem(baseABoxModel, baseTBoxModel, applicationMetadataModel, ctx); + } + + log.info("Setting up full models"); + OntModel baseFullModel = createCombinedBulkUpdatingModel(baseABoxModel, baseTBoxModel); + OntModel inferenceFullModel = createCombinedModel(inferenceABoxModel, inferenceTBoxModel); + OntModel unionFullModel = ModelFactory.createOntologyModel(DB_ONT_MODEL_SPEC, dataset.getDefaultModel()); + + models.setOntModel(ModelID.APPLICATION_METADATA, applicationMetadataModel); + + models.setOntModel(ModelID.BASE_ABOX, baseABoxModel); + models.setOntModel(ModelID.BASE_TBOX, baseTBoxModel); + models.setOntModel(ModelID.BASE_FULL, baseFullModel); + models.setOntModel(ModelID.INFERRED_ABOX, inferenceABoxModel); + models.setOntModel(ModelID.INFERRED_TBOX, inferenceTBoxModel); + models.setOntModel(ModelID.INFERRED_FULL, inferenceFullModel); + models.setOntModel(ModelID.UNION_ABOX, unionABoxModel); + models.setOntModel(ModelID.UNION_TBOX, unionTBoxModel); + models.setOntModel(ModelID.UNION_FULL, unionFullModel); + + checkForNamespaceMismatch( applicationMetadataModel, ctx ); + + log.info("Setting up DAO factories"); + + WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); + config.setDefaultNamespace(getDefaultNamespace(ctx)); + + OntModelSelector baseOms = models.getBaseOntModelSelector(); + WebappDaoFactory baseWadf = new WebappDaoFactorySDB(rdfService, baseOms, config, ASSERTIONS_ONLY); + ModelAccess.on(ctx).setBaseWebappDaoFactory(baseWadf); + + OntModelSelector unionOms = models.getUnionOntModelSelector(); + WebappDaoFactory wadf = new WebappDaoFactorySDB(rdfService, unionOms, config); + ModelAccess.on(ctx).setWebappDaoFactory(FactoryID.UNION, wadf); + + log.info("Model makers set up"); + + ctx.setAttribute("defaultNamespace", getDefaultNamespace(ctx)); + } + + private OntModel createNamedModelFromDataset(Dataset dataset, String name) { + return ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, dataset.getNamedModel(name)); + } + + private OntModel createdMemoryMappedModel(Dataset dataset, String name, String label) { + try { + Model dbModel = dataset.getNamedModel(name); + OntModel memoryModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC); + + if (dbModel != null) { + long begin = System.currentTimeMillis(); + log.info("Copying cached " + label + " into memory"); + memoryModel.add(dbModel); + log.info(secondsSince(begin) + " seconds to load " + label); + memoryModel.getBaseModel().register(new ModelSynchronizer(dbModel)); + } + return memoryModel; + } catch (Throwable e) { + throw new RuntimeException("Unable to load " + label + " from DB", e); + } + } + + private OntModel createCombinedModel(OntModel oneModel, OntModel otherModel) { + return ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, + ModelFactory.createUnion(oneModel, otherModel)); + } + + private OntModel createCombinedBulkUpdatingModel(OntModel baseModel, + OntModel otherModel) { + BulkUpdateHandler bulkUpdateHandler = baseModel.getGraph().getBulkUpdateHandler(); + Graph unionGraph = ModelFactory.createUnion(baseModel, otherModel).getGraph(); + Model unionModel = ModelFactory.createModelForGraph( + new SpecialBulkUpdateHandlerGraph(unionGraph, bulkUpdateHandler)); + return ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC, unionModel); + } + + private void loadInitialApplicationMetadataModel(OntModel applicationMetadataModel, + ServletContext ctx) { + try { + applicationMetadataModel.add( + InitialJenaModelUtils.loadInitialModel(ctx, getDefaultNamespace(ctx))); + } catch (Throwable e) { + throw new RuntimeException("Unable to load application metadata model cache from DB", e); + } + } + + private void loadDataFromFilesystem(OntModel baseABoxModel, OntModel baseTBoxModel, OntModel applicationMetadataModel, + ServletContext ctx) { + Long startTime = System.currentTimeMillis(); + log.info("Initializing models from RDF files"); + + readOntologyFilesInPathSet(USER_ABOX_PATH, ctx, baseABoxModel); + readOntologyFilesInPathSet(USER_TBOX_PATH, ctx, baseTBoxModel); + readOntologyFilesInPathSet(USER_APPMETA_PATH, ctx, applicationMetadataModel); + + log.debug(((System.currentTimeMillis() - startTime) / 1000) + + " seconds to read RDF files "); + } + + private long secondsSince(long startTime) { + return (System.currentTimeMillis() - startTime) / 1000; + } + + /* ===================================================================== */ + + /** + * If we find a "portal1" portal (and we should), its URI should use the + * default namespace. + */ + private void checkForNamespaceMismatch(OntModel model, ServletContext ctx) { + String expectedNamespace = getDefaultNamespace(ctx); + + List portals = getPortal1s(model); + + if(!portals.isEmpty() && noPortalForNamespace( + portals, expectedNamespace)) { + // There really should be only one portal 1, but if there happen to + // be multiple, just arbitrarily pick the first in the list. + Resource portal = portals.get(0); + String oldNamespace = portal.getNameSpace(); + renamePortal(portal, expectedNamespace, model); + StartupStatus ss = StartupStatus.getBean(ctx); + ss.warning(this, "\nThe default namespace has been changed \n" + + "from " + oldNamespace + + "\nto " + expectedNamespace + ".\n" + + "The application will function normally, but " + + "any individuals in the \n" + oldNamespace + " " + + "namespace will need to have their URIs \n" + + "changed in order to be served as linked data. " + + "You can use the Ingest Tools \nto change the " + + "URIs for a batch of resources."); + } + } + + private List getPortal1s(Model model) { + List portals = new ArrayList(); + try { + model.enterCriticalSection(Lock.READ); + ResIterator portalIt = model.listResourcesWithProperty( + RDF.type, PORTAL); + while (portalIt.hasNext()) { + Resource portal = portalIt.nextResource(); + if ("portal1".equals(portal.getLocalName())) { + portals.add(portal); + } + } + } finally { + model.leaveCriticalSection(); + } + return portals; + } + + private boolean noPortalForNamespace(List portals, String expectedNamespace) { + for (Resource portal : portals) { + if(expectedNamespace.equals(portal.getNameSpace())) { + return false; + } + } + return true; + } + + private void renamePortal(Resource portal, String namespace, Model model) { + model.enterCriticalSection(Lock.WRITE); + try { + ResourceUtils.renameResource(portal, namespace + portal.getLocalName()); + } finally { + model.leaveCriticalSection(); + } + } + + /* ===================================================================== */ + + @Override + public void contextDestroyed(ServletContextEvent sce) { + // Nothing to do. + } + + } + diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java index cbd3e77d9..f734f2054 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java @@ -26,7 +26,7 @@ import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; @@ -48,16 +48,16 @@ public class FileGraphSetup implements ServletContextListener { boolean tboxChanged = false; // indicates whether any TBox file graph model has changed OntModelSelector baseOms = null; + ServletContext ctx = sce.getServletContext(); + try { - - ServletContext ctx = sce.getServletContext(); OntDocumentManager.getInstance().setProcessImports(true); - baseOms = ModelContext.getBaseOntModelSelector(sce.getServletContext()); - Dataset dataset = JenaDataSourceSetupBase.getStartupDataset(sce.getServletContext()); + baseOms = ModelAccess.on(ctx).getBaseOntModelSelector(); + Dataset dataset = JenaDataSourceSetupBase.getStartupDataset(ctx); RDFServiceModelMaker maker = new RDFServiceModelMaker(RDFServiceUtils.getRDFServiceFactory(ctx)); // ABox files - Set pathSet = sce.getServletContext().getResourcePaths(PATH_ROOT + ABOX); + Set pathSet = ctx.getResourcePaths(PATH_ROOT + ABOX); cleanupDB(dataset, pathToURI(pathSet, ABOX), ABOX); @@ -67,7 +67,7 @@ public class FileGraphSetup implements ServletContextListener { } // TBox files - pathSet = sce.getServletContext().getResourcePaths(PATH_ROOT + TBOX); + pathSet = ctx.getResourcePaths(PATH_ROOT + TBOX); cleanupDB(dataset, pathToURI(pathSet, TBOX),TBOX); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java index fbe8e61f4..f56d75a3d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java @@ -471,7 +471,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { } else if (TripleStoreType.SDB.equals(type)) { StoreDesc storeDesc = new StoreDesc( LayoutType.LayoutTripleNodesHash, DatabaseType.fetch(dbtypeStr)); - DataSource bds = WebappDaoSetup.makeC3poDataSource( + DataSource bds = ContentModelSetup.makeC3poDataSource( getDbDriverClassName(ctx), jdbcUrl, username, password, ctx); // DataSource bds = WebappDaoSetup.makeBasicDataSource( // getDbDriverClassName(ctx), jdbcUrl, username, password, ctx); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ModelMakerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ModelMakerSetup.java new file mode 100644 index 000000000..8ce03734b --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ModelMakerSetup.java @@ -0,0 +1,54 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.servlet.setup; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; + +import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; +import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaModelMaker; +import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; +import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; + +/** + * Sets up the content models, OntModelSelectors and webapp DAO factories. + */ +public class ModelMakerSetup extends JenaDataSourceSetupBase + implements javax.servlet.ServletContextListener { + + @Override + public void contextInitialized(ServletContextEvent sce) { + ServletContext ctx = sce.getServletContext(); + StartupStatus ss = StartupStatus.getBean(ctx); + + long begin = System.currentTimeMillis(); + + RDFServiceFactory rdfServiceFactory = RDFServiceUtils.getRDFServiceFactory(ctx); + makeModelMakerFromConnectionProperties(TripleStoreType.RDB, ctx); + VitroJenaModelMaker vjmm = getVitroJenaModelMaker(); + setVitroJenaModelMaker(vjmm, ctx); + makeModelMakerFromConnectionProperties(TripleStoreType.SDB, ctx); + RDFServiceModelMaker vsmm = new RDFServiceModelMaker(rdfServiceFactory); + setVitroJenaSDBModelMaker(vsmm, ctx); + + //bdc34: I have no reason for vsmm vs vjmm. + //I don't know what are the implications of this choice. + setVitroModelSource( new VitroModelSource(vsmm,ctx), ctx); + + ss.info(this, secondsSince(begin) + " seconds to set up models and DAO factories"); + } + + private long secondsSince(long startTime) { + return (System.currentTimeMillis() - startTime) / 1000; + } + + /* ===================================================================== */ + + @Override + public void contextDestroyed(ServletContextEvent sce) { + // Nothing to do. + } + } + diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java index ebba991b6..2687af6fa 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java @@ -13,15 +13,15 @@ import net.sf.jga.fn.UnaryFunctor; import com.hp.hpl.jena.ontology.OntModel; import edu.cornell.mannlib.vitro.webapp.beans.Property; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.EntityPropertyListFilter; -import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDao; public class PropertyMaskingSetup implements ServletContextListener { private final static String ENTITY_PROPERTY_LIST_FILTER_ATTR_NAME = "entityPropertyListFilter"; public void contextInitialized(ServletContextEvent sce) { - OntModel jenaOntModel = (OntModel) sce.getServletContext().getAttribute(JenaBaseDao.JENA_ONT_MODEL_ATTRIBUTE_NAME); + OntModel jenaOntModel = ModelAccess.on(sce.getServletContext()).getJenaOntModel(); sce.getServletContext().setAttribute(ENTITY_PROPERTY_LIST_FILTER_ATTR_NAME, new EntityPropertyListFilter(jenaOntModel)); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RunSparqlConstructs.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RunSparqlConstructs.java index b76bebb85..c495496d7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RunSparqlConstructs.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/RunSparqlConstructs.java @@ -11,6 +11,7 @@ import java.util.Iterator; import java.util.Random; import java.util.Set; +import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; @@ -28,6 +29,7 @@ import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.util.ResourceUtils; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; public class RunSparqlConstructs implements ServletContextListener { @@ -42,18 +44,20 @@ public class RunSparqlConstructs implements ServletContextListener { public void contextInitialized(ServletContextEvent sce) { try { - WebappDaoFactory wadf = (WebappDaoFactory) sce.getServletContext().getAttribute("webappDaoFactory"); + ServletContext ctx = sce.getServletContext(); + WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory(); + String namespace = (wadf != null && wadf.getDefaultNamespace() != null) ? wadf.getDefaultNamespace() : DEFAULT_DEFAULT_NAMESPACE; - OntModel baseOntModel = (OntModel) sce.getServletContext().getAttribute("baseOntModel"); + OntModel baseOntModel = ModelAccess.on(ctx).getBaseOntModel(); Model anonModel = ModelFactory.createDefaultModel(); Model namedModel = ModelFactory.createDefaultModel(); - Set resourcePaths = sce.getServletContext().getResourcePaths(SPARQL_DIR); + Set resourcePaths = ctx.getResourcePaths(SPARQL_DIR); for (String path : resourcePaths) { log.debug("Attempting to execute SPARQL at " + path); - File file = new File(sce.getServletContext().getRealPath(path)); + File file = new File(ctx.getRealPath(path)); try { BufferedReader reader = new BufferedReader(new FileReader(file)); StringBuffer fileContents = new StringBuffer(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java index 02295bb63..b84913c54 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java @@ -22,7 +22,8 @@ import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.vocabulary.OWL; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; @@ -33,7 +34,6 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.reasoner.ReasonerPlugin; import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner; import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasonerTBoxListener; -import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase.TripleStoreType; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; public class SimpleReasonerSetup implements ServletContextListener { @@ -48,15 +48,15 @@ public class SimpleReasonerSetup implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { + ServletContext ctx = sce.getServletContext(); try { // set up Pellet reasoning for the TBox - - OntModelSelector assertionsOms = ModelContext.getBaseOntModelSelector(sce.getServletContext()); - OntModelSelector inferencesOms = ModelContext.getInferenceOntModelSelector(sce.getServletContext()); - OntModelSelector unionOms = ModelContext.getUnionOntModelSelector(sce.getServletContext()); + OntModelSelector assertionsOms = ModelAccess.on(ctx).getBaseOntModelSelector(); + OntModelSelector inferencesOms = ModelAccess.on(ctx).getInferenceOntModelSelector(); + OntModelSelector unionOms = ModelAccess.on(ctx).getUnionOntModelSelector(); - WebappDaoFactoryJena wadf = (WebappDaoFactoryJena) sce.getServletContext().getAttribute("webappDaoFactory"); + WebappDaoFactoryJena wadf = (WebappDaoFactoryJena) ModelAccess.on(ctx).getWebappDaoFactory(); if (!assertionsOms.getTBoxModel().getProfile().NAMESPACE().equals(OWL.NAMESPACE.getNameSpace())) { log.error("Not connecting Pellet reasoner - the TBox assertions model is not an OWL model"); @@ -83,7 +83,6 @@ public class SimpleReasonerSetup implements ServletContextListener { // set up simple reasoning for the ABox - ServletContext ctx = sce.getServletContext(); DataSource bds = JenaDataSourceSetupBase .getApplicationDataSource(ctx); String dbType = ConfigurationProperties.getBean(ctx).getProperty( // database type diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ThemeInfoSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ThemeInfoSetup.java index 92547ce2a..6b917c43f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ThemeInfoSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/ThemeInfoSetup.java @@ -23,7 +23,9 @@ import com.hp.hpl.jena.util.iterator.ClosableIterator; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean.ThemeInfo; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; @@ -91,8 +93,7 @@ public class ThemeInfoSetup implements ServletContextListener { } private String getCurrentThemeName(ServletContext ctx) { - OntModel ontModel = ModelContext.getBaseOntModelSelector(ctx) - .getApplicationMetadataModel(); + OntModel ontModel = ModelAccess.on(ctx).getApplicationMetadataModel(); ontModel.enterCriticalSection(Lock.READ); try { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index dcfc12e3e..28fa02f5e 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -32,8 +32,8 @@ import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDFS; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater; import edu.cornell.mannlib.vitro.webapp.ontology.update.UpdateSettings; @@ -99,14 +99,14 @@ public class UpdateKnowledgeBase implements ServletContextListener { settings.setErrorLogFile(ctx.getRealPath(errorLogFileName)); settings.setAddedDataFile(ctx.getRealPath(ADDED_DATA_FILE)); settings.setRemovedDataFile(ctx.getRealPath(REMOVED_DATA_FILE)); - WebappDaoFactory wadf = (WebappDaoFactory) ctx.getAttribute("webappDaoFactory"); + WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory(); settings.setDefaultNamespace(wadf.getDefaultNamespace()); - settings.setAssertionOntModelSelector(ModelContext.getBaseOntModelSelector(ctx)); - settings.setInferenceOntModelSelector(ModelContext.getInferenceOntModelSelector(ctx)); - settings.setUnionOntModelSelector(ModelContext.getUnionOntModelSelector(ctx)); + settings.setAssertionOntModelSelector(ModelAccess.on(ctx).getBaseOntModelSelector()); + settings.setInferenceOntModelSelector(ModelAccess.on(ctx).getInferenceOntModelSelector()); + settings.setUnionOntModelSelector(ModelAccess.on(ctx).getUnionOntModelSelector()); boolean tryMigrateDisplay = true; try { - settings.setDisplayModel(ModelContext.getDisplayModel(ctx)); + settings.setDisplayModel(ModelAccess.on(ctx).getDisplayModel()); OntModel oldTBoxModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_MODEL_DIR)); settings.setOldTBoxModel(oldTBoxModel); OntModel newTBoxModel = loadModelFromDirectory(ctx.getRealPath(NEW_TBOX_MODEL_DIR)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdatePermissionSetUris.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdatePermissionSetUris.java index f0fffdc7b..ec03f70ff 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdatePermissionSetUris.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdatePermissionSetUris.java @@ -22,6 +22,7 @@ import javax.servlet.ServletContextListener; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; @@ -99,8 +100,7 @@ public class UpdatePermissionSetUris implements ServletContextListener { this.ctx = ctx; this.stats = stats; - WebappDaoFactory wadf = (WebappDaoFactory) ctx - .getAttribute("webappDaoFactory"); + WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory(); userAccountsDao = wadf.getUserAccountsDao(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UserModelSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UserModelSetup.java index 3d1a54d6f..47b51a5a3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UserModelSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UserModelSetup.java @@ -6,7 +6,6 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.sql.DataSource; -import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -14,6 +13,7 @@ import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; @@ -65,7 +65,7 @@ public class UserModelSetup extends JenaDataSourceSetupBase userAccountsModel.add(userAccountsDbModel); userAccountsModel.getBaseModel().register( new ModelSynchronizer(userAccountsDbModel)); - ctx.setAttribute("userAccountsOntModel", userAccountsModel); + ModelAccess.on(ctx).setUserAccountsModel(userAccountsModel); } catch (Throwable t) { log.error("Unable to load user accounts model from DB", t); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/WebappDaoSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/WebappDaoSetup.java deleted file mode 100644 index 5ad2fb4ce..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/WebappDaoSetup.java +++ /dev/null @@ -1,398 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.servlet.setup; - -import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.DISPLAY_ONT_MODEL; - -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.hp.hpl.jena.ontology.OntModel; -import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.query.Dataset; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.ResIterator; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.ResourceFactory; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.shared.Lock; -import com.hp.hpl.jena.util.ResourceUtils; -import com.hp.hpl.jena.util.iterator.ClosableIterator; -import com.hp.hpl.jena.vocabulary.RDF; - -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer; -import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; -import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelectorImpl; -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset; -import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceModelMaker; -import edu.cornell.mannlib.vitro.webapp.dao.jena.SpecialBulkUpdateHandlerGraph; -import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaModelMaker; -import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource; -import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; -import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; -import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; -import edu.cornell.mannlib.vitro.webapp.utils.jena.InitialJenaModelUtils; - -/** - * Primarily sets up webapp DAO factories. - */ -public class WebappDaoSetup extends JenaDataSourceSetupBase - implements javax.servlet.ServletContextListener { - - private static final Log log = LogFactory.getLog(WebappDaoSetup.class); - - @Override - public void contextInitialized(ServletContextEvent sce) { - ServletContext ctx = sce.getServletContext(); - StartupStatus ss = StartupStatus.getBean(ctx); - - try { - long startTime = System.currentTimeMillis(); - setUpJenaDataSource(ctx, ss); - log.info((System.currentTimeMillis() - startTime) / 1000 + - " seconds to set up models and DAO factories"); - } catch (Throwable t) { - log.error("Throwable in " + this.getClass().getName(), t); - ss.fatal(this, "Throwable in " + this.getClass().getName(), t); - } - - } - - private void setUpJenaDataSource(ServletContext ctx, StartupStatus ss) { - OntModelSelectorImpl baseOms = new OntModelSelectorImpl(); - OntModelSelectorImpl inferenceOms = new OntModelSelectorImpl(); - OntModelSelectorImpl unionOms = new OntModelSelectorImpl(); - - OntModel userAccountsModel = ontModelFromContextAttribute( - ctx, "userAccountsOntModel"); - baseOms.setUserAccountsModel(userAccountsModel); - inferenceOms.setUserAccountsModel(userAccountsModel); - unionOms.setUserAccountsModel(userAccountsModel); - - OntModel displayModel = ontModelFromContextAttribute( - ctx,DISPLAY_ONT_MODEL); - baseOms.setDisplayModel(displayModel); - inferenceOms.setDisplayModel(displayModel); - unionOms.setDisplayModel(displayModel); - - RDFServiceFactory rdfServiceFactory = RDFServiceUtils.getRDFServiceFactory(ctx); - RDFService rdfService = rdfServiceFactory.getRDFService(); - Dataset dataset = new RDFServiceDataset(rdfService); - setStartupDataset(dataset, ctx); - - // ABox assertions - Model aboxAssertions = dataset.getNamedModel( - JenaDataSourceSetupBase.JENA_DB_MODEL); - baseOms.setABoxModel( - ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, aboxAssertions)); - - // ABox inferences - Model aboxInferences = dataset.getNamedModel( - JenaDataSourceSetupBase.JENA_INF_MODEL); - inferenceOms.setABoxModel(ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, aboxInferences)); - - // TBox assertions - try { - Model tboxAssertionsDB = dataset.getNamedModel( - JENA_TBOX_ASSERTIONS_MODEL); - OntModel tboxAssertions = ModelFactory.createOntologyModel( - MEM_ONT_MODEL_SPEC); - - if (tboxAssertionsDB != null) { - long startTime = System.currentTimeMillis(); - System.out.println( - "Copying cached tbox assertions into memory"); - tboxAssertions.add(tboxAssertionsDB); - System.out.println((System.currentTimeMillis() - startTime) - / 1000 + " seconds to load tbox assertions"); - } - - tboxAssertions.getBaseModel().register(new ModelSynchronizer( - tboxAssertionsDB)); - - baseOms.setTBoxModel(tboxAssertions); - } catch (Throwable e) { - log.error("Unable to load tbox assertion cache from DB", e); - throw new RuntimeException(e); - } - - // TBox inferences - try { - Model tboxInferencesDB = dataset.getNamedModel(JENA_TBOX_INF_MODEL); - OntModel tboxInferences = ModelFactory.createOntologyModel( - MEM_ONT_MODEL_SPEC); - - if (tboxInferencesDB != null) { - long startTime = System.currentTimeMillis(); - System.out.println( - "Copying cached tbox inferences into memory"); - tboxInferences.add(tboxInferencesDB); - System.out.println((System.currentTimeMillis() - startTime) - / 1000 + " seconds to load tbox inferences"); - } - - tboxInferences.getBaseModel().register(new ModelSynchronizer( - tboxInferencesDB)); - inferenceOms.setTBoxModel(tboxInferences); - } catch (Throwable e) { - log.error("Unable to load tbox inference cache from DB", e); - throw new RuntimeException(e); - } - - // union ABox - - Model m = ModelFactory.createUnion( - baseOms.getABoxModel(), inferenceOms.getABoxModel()); - m = ModelFactory.createModelForGraph( - new SpecialBulkUpdateHandlerGraph( - m.getGraph(), - baseOms.getABoxModel().getGraph().getBulkUpdateHandler())); - OntModel unionABoxModel = ModelFactory.createOntologyModel( - MEM_ONT_MODEL_SPEC, m); - unionOms.setABoxModel(unionABoxModel); - - // union TBox - m = ModelFactory.createUnion( - baseOms.getTBoxModel(), inferenceOms.getTBoxModel()); - m = ModelFactory.createModelForGraph( - new SpecialBulkUpdateHandlerGraph( - m.getGraph(), - baseOms.getTBoxModel().getGraph().getBulkUpdateHandler())); - OntModel unionTBoxModel = ModelFactory.createOntologyModel( - MEM_ONT_MODEL_SPEC, m); - unionOms.setTBoxModel(unionTBoxModel); - - - // Application metadata model is cached in memory. - try { - - Model applicationMetadataModelDB = dataset.getNamedModel( - JENA_APPLICATION_METADATA_MODEL); - OntModel applicationMetadataModel = - ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC); - - long startTime = System.currentTimeMillis(); - System.out.println( - "Copying cached application metadata model into memory"); - applicationMetadataModel.add(applicationMetadataModelDB); - System.out.println((System.currentTimeMillis() - startTime) - / 1000 + " seconds to load application metadata model " + - "assertions of size " + applicationMetadataModel.size()); - applicationMetadataModel.getBaseModel().register( - new ModelSynchronizer(applicationMetadataModelDB)); - - if (applicationMetadataModel.size()== 0 /* isFirstStartup() */) { - JenaDataSourceSetupBase.thisIsFirstStartup(); - applicationMetadataModel.add( - InitialJenaModelUtils.loadInitialModel( - ctx, getDefaultNamespace(ctx))); - } - - baseOms.setApplicationMetadataModel(applicationMetadataModel); - inferenceOms.setApplicationMetadataModel( - baseOms.getApplicationMetadataModel()); - unionOms.setApplicationMetadataModel( - baseOms.getApplicationMetadataModel()); - - } catch (Throwable e) { - log.error("Unable to load application metadata model cache from DB" - , e); - throw new RuntimeException(e); - } - - checkForNamespaceMismatch( baseOms.getApplicationMetadataModel(), ctx ); - - if (isFirstStartup()) { - loadDataFromFilesystem(baseOms, ctx); - } - - log.info("Setting up union models and DAO factories"); - - // create TBox + ABox union models and set up webapp DAO factories - Model baseDynamicUnion = ModelFactory.createUnion(baseOms.getABoxModel(), - baseOms.getTBoxModel()); - baseDynamicUnion = ModelFactory.createModelForGraph( - new SpecialBulkUpdateHandlerGraph( - baseDynamicUnion.getGraph(), - baseOms.getABoxModel().getGraph().getBulkUpdateHandler()) ); - OntModel baseUnion = ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, baseDynamicUnion); - baseOms.setFullModel(baseUnion); - ModelContext.setBaseOntModel(baseOms.getFullModel(), ctx); - WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); - config.setDefaultNamespace(getDefaultNamespace(ctx)); - WebappDaoFactory baseWadf = new WebappDaoFactorySDB( - rdfService, baseOms, config, - WebappDaoFactorySDB.SDBDatasetMode.ASSERTIONS_ONLY); - ctx.setAttribute("assertionsWebappDaoFactory",baseWadf); - - OntModel inferenceUnion = ModelFactory.createOntologyModel( - OntModelSpec.OWL_MEM, - ModelFactory.createUnion( - inferenceOms.getABoxModel(), - inferenceOms.getTBoxModel())); - inferenceOms.setFullModel(inferenceUnion); - ModelContext.setInferenceOntModel(inferenceOms.getFullModel(), ctx); - WebappDaoFactory infWadf = new WebappDaoFactorySDB( - rdfService, inferenceOms, config, - WebappDaoFactorySDB.SDBDatasetMode.INFERENCES_ONLY); - ctx.setAttribute("deductionsWebappDaoFactory", infWadf); - - OntModel masterUnion = ModelFactory.createOntologyModel( - DB_ONT_MODEL_SPEC, dataset.getDefaultModel()); - unionOms.setFullModel(masterUnion); - ctx.setAttribute("jenaOntModel", masterUnion); - WebappDaoFactory wadf = new WebappDaoFactorySDB( - rdfService, unionOms, config); - ctx.setAttribute("webappDaoFactory",wadf); - - ModelContext.setOntModelSelector(unionOms, ctx); - ModelContext.setUnionOntModelSelector(unionOms, ctx); - // assertions and inferences - ModelContext.setBaseOntModelSelector(baseOms, ctx); - // assertions - ModelContext.setInferenceOntModelSelector(inferenceOms, ctx); - // inferences - - ctx.setAttribute("defaultNamespace", getDefaultNamespace(ctx)); - - makeModelMakerFromConnectionProperties(TripleStoreType.RDB, ctx); - VitroJenaModelMaker vjmm = getVitroJenaModelMaker(); - setVitroJenaModelMaker(vjmm, ctx); - makeModelMakerFromConnectionProperties(TripleStoreType.SDB, ctx); - RDFServiceModelMaker vsmm = new RDFServiceModelMaker(rdfServiceFactory); - setVitroJenaSDBModelMaker(vsmm, ctx); - - //bdc34: I have no reason for vsmm vs vjmm. - //I don't know what are the implications of this choice. - setVitroModelSource( new VitroModelSource(vsmm,ctx), ctx); - - log.info("Model makers set up"); - } - - - /** - * If we find a "portal1" portal (and we should), its URI should use the - * default namespace. - */ - private void checkForNamespaceMismatch(OntModel model, ServletContext ctx) { - String expectedNamespace = getDefaultNamespace(ctx); - - List portals = getPortal1s(model); - - if(!portals.isEmpty() && noPortalForNamespace( - portals, expectedNamespace)) { - // There really should be only one portal 1, but if there happen to - // be multiple, just arbitrarily pick the first in the list. - Resource portal = portals.get(0); - String oldNamespace = portal.getNameSpace(); - renamePortal(portal, expectedNamespace, model); - StartupStatus ss = StartupStatus.getBean(ctx); - ss.warning(this, "\nThe default namespace has been changed \n" + - "from " + oldNamespace + - "\nto " + expectedNamespace + ".\n" + - "The application will function normally, but " + - "any individuals in the \n" + oldNamespace + " " + - "namespace will need to have their URIs \n" + - "changed in order to be served as linked data. " + - "You can use the Ingest Tools \nto change the " + - "URIs for a batch of resources."); - } - } - - private List getPortal1s(Model model) { - List portals = new ArrayList(); - try { - model.enterCriticalSection(Lock.READ); - ResIterator portalIt = model.listResourcesWithProperty( - RDF.type, PORTAL); - while (portalIt.hasNext()) { - Resource portal = portalIt.nextResource(); - if ("portal1".equals(portal.getLocalName())) { - portals.add(portal); - } - } - } finally { - model.leaveCriticalSection(); - } - return portals; - } - - private boolean noPortalForNamespace(List portals, - String expectedNamespace) { - for (Resource portal : portals) { - if(expectedNamespace.equals(portal.getNameSpace())) { - return false; - } - } - return true; - } - - private void renamePortal(Resource portal, String namespace, Model model) { - model.enterCriticalSection(Lock.WRITE); - try { - ResourceUtils.renameResource( - portal, namespace + portal.getLocalName()); - } finally { - model.leaveCriticalSection(); - } - } - - - /* ===================================================================== */ - - - @Override - public void contextDestroyed(ServletContextEvent sce) { - // Nothing to do. - } - - private boolean isEmpty(Model model) { - ClosableIterator closeIt = model.listStatements( - null, RDF.type, ResourceFactory.createResource( - VitroVocabulary.PORTAL)); - try { - if (closeIt.hasNext()) { - return false; - } else { - return true; - } - } finally { - closeIt.close(); - } - } - - private void loadDataFromFilesystem(OntModelSelector baseOms, - ServletContext ctx) { - Long startTime = System.currentTimeMillis(); - log.info("Initializing models from RDF files"); - - readOntologyFilesInPathSet(USER_ABOX_PATH, ctx, baseOms.getABoxModel()); - readOntologyFilesInPathSet(USER_TBOX_PATH, ctx, baseOms.getTBoxModel()); - readOntologyFilesInPathSet( - USER_APPMETA_PATH, ctx, baseOms.getApplicationMetadataModel()); - - log.debug(((System.currentTimeMillis() - startTime) / 1000) - + " seconds to read RDF files "); - } - - - - - } - diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java new file mode 100644 index 000000000..9aab09eab --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ApplicationConfigurationOntologyUtils.java @@ -0,0 +1,109 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.utils; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.ServletContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.Resource; + +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; + +public class ApplicationConfigurationOntologyUtils { + + private static final Log log = LogFactory.getLog(ApplicationConfigurationOntologyUtils.class); + + public static List getAdditionalFauxSubpropertiesForList(List propList, VitroRequest vreq) { + ServletContext ctx = vreq.getSession().getServletContext(); + Model displayModel = ModelAccess.on(ctx).getDisplayModel(); + Model tboxModel = ModelAccess.on(ctx).getOntModel(ModelID.UNION_TBOX); + return getAdditionalFauxSubpropertiesForList(propList, displayModel, tboxModel); + } + + + + public static List getAdditionalFauxSubpropertiesForList(List propList, + Model displayModel, + Model tboxModel) { + List additionalProps = new ArrayList(); + Model union = ModelFactory.createUnion(displayModel, tboxModel); + String propQuery = "PREFIX rdfs: \n" + + "PREFIX config: \n" + + "PREFIX vitro: \n" + + "SELECT ?range ?label ?group ?customForm WHERE { \n" + + " ?p rdfs:subPropertyOf ?property . \n" + + " ?context config:configContextFor ?p . \n" + + " ?context config:qualifiedBy ?range . \n" + + " ?context config:hasConfiguration ?configuration . \n" + + " OPTIONAL { ?configuration config:propertyGroup ?group } \n" + + " OPTIONAL { ?configuration config:displayName ?label } \n" + + " OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" + + "}"; + + for (ObjectProperty op : propList) { + log.debug("Checking " + op.getURI() + " for additional properties"); + String queryStr = propQuery.replaceAll("\\?property", "<" + op.getURI() + ">"); + log.debug(queryStr); + Query q = QueryFactory.create(queryStr); + QueryExecution qe = QueryExecutionFactory.create(q, union); + try { + ResultSet rs = qe.execSelect(); + while (rs.hasNext()) { + ObjectProperty newProp = new ObjectProperty(); + newProp.setURI(op.getURI()); + QuerySolution qsoln = rs.nextSolution(); + log.debug(qsoln); + Resource rangeRes = qsoln.getResource("range"); + if (rangeRes != null) { + newProp.setRangeVClassURI(rangeRes.getURI()); + } else { + newProp.setRangeVClassURI(op.getRangeVClassURI()); + } + Resource groupRes = qsoln.getResource("group"); + if (groupRes != null) { + newProp.setGroupURI(groupRes.getURI()); + } else { + newProp.setGroupURI(op.getURI()); + } + Literal labelLit = qsoln.getLiteral("label"); + if (labelLit != null) { + newProp.setDomainPublic(labelLit.getLexicalForm()); + } else { + newProp.setDomainPublic(op.getDomainPublic()); + } + Literal customFormLit = qsoln.getLiteral("customForm"); + if (customFormLit != null) { + newProp.setCustomEntryForm(customFormLit.getLexicalForm()); + } else { + newProp.setCustomEntryForm(op.getCustomEntryForm()); + } + additionalProps.add(newProp); + } + } finally { + qe.close(); + } + } + + return additionalProps; + } + + + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/TitleCase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/TitleCase.java deleted file mode 100644 index 16db7e8de..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/TitleCase.java +++ /dev/null @@ -1,110 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.utils; - -import java.util.StringTokenizer; - -/** - * - * -following text from http://search.cpan.org/dist/Text-Capitalize/Capitalize.pm - -This web page: - http://www.continentallocating.com/World.Literature/General2/LiteraryTitles2.htm - -presents some admirably clear rules for capitalizing titles: - ALL words in EVERY title are capitalized except - (1) a, an, and the, - (2) two and three letter conjunctions (and, or, nor, for, but, so, yet), - (3) prepositions. - Exceptions: The first word is always capitalized even - if it is among the above three groups. For the last word, we can specify the - option to always capitalize it or to treat it like a medial word. The original - method always capitalized the final word, so to support the old method calls - we have defined another method to provide this as default behavior. - - -But consider the case: - "It Waits Underneath the Sea" - -Should the word "underneath" be downcased because it's a preposition? Most English speakers -would be surprised to see it that way. Consequently, the default list of exceptions to -capitalization in this module only includes the shortest of the common prepositions -(to of by at for but in). - -The default entries on the exception list are: - a an the - and or nor for but so yet - to of by at for but in with has - de von -The observant may note that the last row is not composed of English words. The honorary -"de" has been included in honor of "Honore' de Balzac". And "von" was added for the sake -of equal time. - */ -public class TitleCase { - static String ignore[] = {"a","an","the","and","or","nor","for","but","so","yet", - "to","of","by","at","for","but","in","with","has","de","von"}; - - public static String toTitleCase(String in) { - // Support old behavior without modifying method calls - return toTitleCase(in, true); - } - - public static String toTitleCase(String in, boolean alwaysCapitalizeLast){ - if( in == null || in.length() ==0 ) - return in; - - in = in.toLowerCase(); - StringTokenizer st = new StringTokenizer(in); - StringBuilder out = new StringBuilder(); - - int count = 1; - int last = st.countTokens(); - - while(st.hasMoreTokens()){ - String token = st.nextToken(); - - // always capitalize first - if ( count == 1 || - // always capitalize last, unless we've asked not to - ( alwaysCapitalizeLast && count == last ) ) { - out.append(capitalizeWord(token)); - - } else { - - //check if on ignored list - boolean ignoreToken = false; - for(String ign:ignore){ - if( token.equals(ign) ) - ignoreToken = true; - } - if( ignoreToken ) - out.append(token); - else - out.append(capitalizeWord(token)); - } - - if(st.hasMoreTokens()) - out.append(' '); - count++; - } - return out.toString(); - } - - private static String capitalizeWord(String in){ - if( in == null || in.length() == 0 ) - return in; - if( in.length() == 1 ) - return in.toUpperCase(); - - //not trying too hard to deal with dashes. - int dash = in.indexOf('-') ; - if(dash > 0 && in.length() > dash+2 ) - in = in.substring(0, dash) - + '-' - + in.substring(dash+1,dash+2).toUpperCase() - + in.substring(dash+2); - - return in.substring(0, 1).toUpperCase() + in.substring(1); - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/BrowseDataGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/BrowseDataGetter.java index 34e14477c..4ef989663 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/BrowseDataGetter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/BrowseDataGetter.java @@ -25,6 +25,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.json.JsonServlet; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.utils.JsonToFmModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; @@ -120,7 +121,7 @@ public class BrowseDataGetter extends DataGetterBase implements DataGetter { private Map getCommonValues( ServletContext context, VitroRequest vreq){ Map values = new HashMap(); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); List cgList = vcgc.getGroups(); LinkedList cgtmList = new LinkedList(); for( VClassGroup classGroup : cgList){ @@ -194,7 +195,7 @@ public class BrowseDataGetter extends DataGetterBase implements DataGetter { String vcgUri = getParam(Mode.CLASS_GROUP, request, params); VitroRequest vreq = new VitroRequest(request); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(request); VClassGroup vcg = vcgc.getGroup(vcgUri); ArrayList classes = new ArrayList(vcg.size()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupPageData.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupPageData.java index c523e3a5e..234fdabf9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupPageData.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupPageData.java @@ -19,6 +19,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; @@ -65,7 +66,7 @@ public class ClassGroupPageData extends DataGetterBase implements DataGetter{ HashMap data = new HashMap(); data.put("classGroupUri", this.classGroupUri); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); List vcgList = vcgc.getGroups(); VClassGroup group = null; for( VClassGroup vcg : vcgList){ @@ -119,7 +120,7 @@ public class ClassGroupPageData extends DataGetterBase implements DataGetter{ public static VClassGroupTemplateModel getClassGroup(String classGroupUri, ServletContext context, VitroRequest vreq){ - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); List vcgList = vcgc.getGroups(); VClassGroup group = null; for( VClassGroup vcg : vcgList){ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterBase.java index 51d5b9644..a57025796 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterBase.java @@ -1,8 +1,6 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ package edu.cornell.mannlib.vitro.webapp.utils.dataGetter; -import java.util.Map; - import javax.servlet.ServletContext; import org.apache.commons.lang.StringUtils; @@ -11,9 +9,7 @@ import com.hp.hpl.jena.rdf.model.Model; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.jena.JenaIngestController; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaModelMaker; -import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSDBModelMaker; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; public abstract class DataGetterBase implements DataGetter { @@ -29,7 +25,7 @@ public abstract class DataGetterBase implements DataGetter { }else if( REQUEST_JENA_ONT_MODEL.equals(modelName)){ return vreq.getJenaOntModel(); }else if( CONTEXT_DISPLAY_MODEL.equals(modelName)){ - return (Model)context.getAttribute( DisplayVocabulary.DISPLAY_ONT_MODEL); + return ModelAccess.on(context).getDisplayModel(); }else if( ! StringUtils.isEmpty( modelName)){ Model model = JenaIngestController.getModel( modelName, vreq, context); if( model == null ) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterUtils.java index bf9458a17..52819025a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/DataGetterUtils.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Map; import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; @@ -45,6 +46,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListCont import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.json.JsonServlet; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; @@ -102,7 +104,7 @@ public class DataGetterUtils { * May return an empty list, but will not return null. */ private static List dataGettersForURIs(VitroRequest vreq, Model displayModel, List dgUris) - throws InstantiationException, IllegalAccessException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException { + throws InstantiationException, IllegalAccessException, ClassNotFoundException, InvocationTargetException { List dgList = new ArrayList(); for( String dgURI: dgUris){ DataGetter dg =dataGetterForURI(vreq, displayModel, dgURI) ; @@ -332,7 +334,7 @@ public class DataGetterUtils { @SuppressWarnings("unchecked") Enumeration e = vreq.getParameterNames(); while(e.hasMoreElements()){ - String name = (String)e.nextElement(); + String name = e.nextElement(); log.debug("parameter: " + name); for( String value : vreq.getParameterValues(name) ){ log.debug("value for " + name + ": '" + value + "'"); @@ -550,9 +552,9 @@ public class DataGetterUtils { //Get All VClass Groups information //Used within menu management and processing //TODO: Check if more appropriate location possible - public static List> getClassGroups(ServletContext context) { + public static List> getClassGroups(HttpServletRequest req) { //Wanted this to be - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(req); List vcgList = vcgc.getGroups(); //For now encoding as hashmap with label and URI as trying to retrieve class group //results in errors for some reason @@ -570,11 +572,11 @@ public class DataGetterUtils { //TODO: Check whether this needs to be put here or elsewhere, as this is data getter specific //with respect to class groups //Need to use VClassGroupCache to retrieve class group information - this is the information returned from "for class group" - public static void getClassGroupForDataGetter(ServletContext context, Map pageData, Map templateData) { + public static void getClassGroupForDataGetter(HttpServletRequest req, Map pageData, Map templateData) { //Get the class group from VClassGroup, this is the same as the class group for the class group page data getter //and the associated class group (not custom) for individuals datagetter String classGroupUri = (String) pageData.get("classGroupUri"); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(req); VClassGroup group = vcgc.getGroup(classGroupUri); templateData.put("classGroup", group); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ExecuteDataRetrieval.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ExecuteDataRetrieval.java index 64eb31c87..7cb461648 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ExecuteDataRetrieval.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ExecuteDataRetrieval.java @@ -1,54 +1,19 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ package edu.cornell.mannlib.vitro.webapp.utils.dataGetter; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.net.URLEncoder; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import javax.servlet.ServletContext; - -import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.json.JSONArray; -import org.json.JSONObject; -import com.hp.hpl.jena.query.Query; -import com.hp.hpl.jena.query.QueryExecution; -import com.hp.hpl.jena.query.QueryExecutionFactory; -import com.hp.hpl.jena.query.QueryFactory; -import com.hp.hpl.jena.query.QuerySolution; -import com.hp.hpl.jena.query.QuerySolutionMap; -import com.hp.hpl.jena.query.ResultSet; -import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.ResourceFactory; -import com.hp.hpl.jena.shared.Lock; -import com.hp.hpl.jena.vocabulary.OWL; -import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.VClass; -import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; -import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.PageRecord; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; -import edu.cornell.mannlib.vitro.webapp.controller.json.JsonServlet; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; public class ExecuteDataRetrieval { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/IndividualsForClassesDataGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/IndividualsForClassesDataGetter.java index 1c2bc7d6c..2e5012719 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/IndividualsForClassesDataGetter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/IndividualsForClassesDataGetter.java @@ -30,6 +30,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; @@ -227,7 +228,7 @@ public class IndividualsForClassesDataGetter extends DataGetterBase implements D log.debug("Processing classes that will be displayed"); List vClasses = new ArrayList(); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); for(String classUri: classes) { //Retrieve vclass from cache to get the count VClass vclass = vcgc.getCachedVClass(classUri); @@ -262,7 +263,7 @@ public class IndividualsForClassesDataGetter extends DataGetterBase implements D List restrictVClasses = new ArrayList(); List urlEncodedRestrictClasses = new ArrayList(); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); if(restrictClasses.size() > 0) { //classes for restriction are not displayed so don't need to include their class individual counts @@ -306,7 +307,7 @@ public class IndividualsForClassesDataGetter extends DataGetterBase implements D public static VClassGroupTemplateModel getClassGroup(String classGroupUri, ServletContext context, VitroRequest vreq){ - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); List vcgList = vcgc.getGroups(); VClassGroup group = null; for( VClassGroup vcg : vcgList){ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/ProcessClassGroup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/ProcessClassGroup.java index d09c0a5cd..89baf89da 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/ProcessClassGroup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/ProcessClassGroup.java @@ -4,7 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.utils.menuManagement; import java.util.Map; -import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -28,19 +28,21 @@ public class ProcessClassGroup implements ProcessDataGetter{ //template data represents what needs to be modified and returned to template //page data is data retrieved from data getter - public void populateTemplate(ServletContext context, Map pageData, Map templateData) { + @Override + public void populateTemplate(HttpServletRequest req, Map pageData, Map templateData) { //This is a class group page so templateData.put("isClassGroupPage", true); templateData.put("includeAllClasses", true); //Get the class group from VClassGroup - DataGetterUtils.getClassGroupForDataGetter(context, pageData, templateData); + DataGetterUtils.getClassGroupForDataGetter(req, pageData, templateData); } //Process submission - public Model processSubmission(VitroRequest vreq, Resource dataGetterResource) { + @Override + public Model processSubmission(VitroRequest vreq, Resource dataGetterResource) { Model dgModel = ModelFactory.createDefaultModel(); String dataGetterTypeUri = DataGetterUtils.generateDataGetterTypeURI(ClassGroupPageData.class.getName()); dgModel.add(dgModel.createStatement(dataGetterResource, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/ProcessDataGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/ProcessDataGetter.java index 353e59e88..49c3e9263 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/ProcessDataGetter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/ProcessDataGetter.java @@ -4,18 +4,15 @@ package edu.cornell.mannlib.vitro.webapp.utils.menuManagement; import java.util.Map; -import javax.servlet.ServletContext; - -import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; - -import org.json.JSONObject; +import javax.servlet.http.HttpServletRequest; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Resource; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; + public interface ProcessDataGetter{ - public void populateTemplate(ServletContext context, Map pageData, Map templateData); + public void populateTemplate(HttpServletRequest req, Map pageData, Map templateData); public Model processSubmission(VitroRequest vreq, Resource dataGetterResource); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/ProcessIndividualsForClasses.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/ProcessIndividualsForClasses.java index 802a82e48..105c4cf0d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/ProcessIndividualsForClasses.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/ProcessIndividualsForClasses.java @@ -6,7 +6,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -34,12 +34,13 @@ public class ProcessIndividualsForClasses implements ProcessDataGetter { /**Retrieve and populate**/ //Based on institutional internal page and not general individualsForClasses - public void populateTemplate(ServletContext context, Map pageData, Map templateData) { + @Override + public void populateTemplate(HttpServletRequest req, Map pageData, Map templateData) { initTemplateData(templateData); populateIncludedClasses(pageData, templateData); populateRestrictedClasses(pageData, templateData); //Also save the class group for display - DataGetterUtils.getClassGroupForDataGetter(context, pageData, templateData); + DataGetterUtils.getClassGroupForDataGetter(req, pageData, templateData); } @@ -76,6 +77,7 @@ public class ProcessIndividualsForClasses implements ProcessDataGetter { public boolean useProcessor(VitroRequest vreq) { return(!allClassesSelected(vreq)); } + @Override public Model processSubmission(VitroRequest vreq, Resource dataGetterResource) { String[] selectedClasses = vreq.getParameterValues("classInClassGroup"); String dataGetterTypeUri = DataGetterUtils.generateDataGetterTypeURI(IndividualsForClassesDataGetter.class.getName()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/SelectDataGetterUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/SelectDataGetterUtils.java index 692ae4605..1190735cb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/SelectDataGetterUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/menuManagement/SelectDataGetterUtils.java @@ -30,7 +30,7 @@ public class SelectDataGetterUtils { public static void processAndRetrieveData(VitroRequest vreq, ServletContext context, Map pageData, String dataGetterClass, Map templateData) { //The type of the data getter will show how to process the data from the data getter ProcessDataGetter processor = selectProcessor(dataGetterClass); - processor.populateTemplate(context, pageData, templateData); + processor.populateTemplate(vreq, pageData, templateData); } //This will be different in VIVO than in VITRO diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/BrowseDataGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/BrowseDataGetter.java index 25222968e..7fbd63ada 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/BrowseDataGetter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/BrowseDataGetter.java @@ -23,6 +23,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.json.JsonServlet; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.utils.JsonToFmModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; @@ -63,7 +64,8 @@ public class BrowseDataGetter implements PageDataGetter { } //Get data servuice - public String getDataServiceUrl() { + @Override + public String getDataServiceUrl() { return UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClass=1&vclassId="); } private Map doClassAlphaDisplay( Map params, VitroRequest request, ServletContext context) throws Exception { @@ -94,7 +96,7 @@ public class BrowseDataGetter implements PageDataGetter { private Map getCommonValues( ServletContext context, VitroRequest vreq){ Map values = new HashMap(); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); List cgList = vcgc.getGroups(); LinkedList cgtmList = new LinkedList(); for( VClassGroup classGroup : cgList){ @@ -168,7 +170,7 @@ public class BrowseDataGetter implements PageDataGetter { String vcgUri = getParam(Mode.CLASS_GROUP, request, params); VitroRequest vreq = new VitroRequest(request); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(request); VClassGroup vcg = vcgc.getGroup(vcgUri); ArrayList classes = new ArrayList(vcg.size()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/ClassGroupPageData.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/ClassGroupPageData.java index 92244fe8d..0e68dd4b9 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/ClassGroupPageData.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/ClassGroupPageData.java @@ -16,7 +16,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; +import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; @@ -28,12 +28,13 @@ import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateMo public class ClassGroupPageData implements PageDataGetter{ private static final Log log = LogFactory.getLog(ClassGroupPageData.class); - public Map getData(ServletContext context, VitroRequest vreq, String pageUri, Map page ){ + @Override + public Map getData(ServletContext context, VitroRequest vreq, String pageUri, Map page ){ HashMap data = new HashMap(); String classGroupUri = vreq.getWebappDaoFactory().getPageDao().getClassGroupPage(pageUri); data.put("classGroupUri", classGroupUri); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); List vcgList = vcgc.getGroups(); VClassGroup group = null; for( VClassGroup vcg : vcgList){ @@ -87,7 +88,7 @@ public class ClassGroupPageData implements PageDataGetter{ public static VClassGroupTemplateModel getClassGroup(String classGroupUri, ServletContext context, VitroRequest vreq){ - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); List vcgList = vcgc.getGroups(); VClassGroup group = null; for( VClassGroup vcg : vcgList){ @@ -125,12 +126,14 @@ public class ClassGroupPageData implements PageDataGetter{ return new VClassGroupTemplateModel(group); } - public String getType(){ + @Override + public String getType(){ return PageDataGetterUtils.generateDataGetterTypeURI(ClassGroupPageData.class.getName()); } //Get data servuice - public String getDataServiceUrl() { + @Override + public String getDataServiceUrl() { return UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClass=1&vclassId="); } @@ -139,7 +142,8 @@ public class ClassGroupPageData implements PageDataGetter{ * For processing of JSONObject */ //Currently empty, TODO: Review requirements - public JSONObject convertToJSON(Map dataMap, VitroRequest vreq) { + @Override + public JSONObject convertToJSON(Map dataMap, VitroRequest vreq) { JSONObject rObj = null; return rObj; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/IndividualsForClassesDataGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/IndividualsForClassesDataGetter.java index c4787acfb..3e0fd62b6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/IndividualsForClassesDataGetter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/IndividualsForClassesDataGetter.java @@ -5,7 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -17,22 +16,12 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.json.JSONObject; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.ResourceFactory; -import com.hp.hpl.jena.rdf.model.Statement; -import com.hp.hpl.jena.rdf.model.StmtIterator; - -import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.PageDao; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; +import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; @@ -44,7 +33,8 @@ import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateMo public class IndividualsForClassesDataGetter implements PageDataGetter{ private static final Log log = LogFactory.getLog(IndividualsForClassesDataGetter.class); protected static String restrictClassesTemplateName = null; - public Map getData(ServletContext context, VitroRequest vreq, String pageUri, Map page ){ + @Override + public Map getData(ServletContext context, VitroRequest vreq, String pageUri, Map page ){ this.setTemplateName(); HashMap data = new HashMap(); //This is the old technique of getting class intersections @@ -158,7 +148,7 @@ public class IndividualsForClassesDataGetter implements PageDataGetter{ log.debug("Processing classes that will be displayed"); List vClasses = new ArrayList(); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); for(String classUri: classes) { //Retrieve vclass from cache to get the count VClass vclass = vcgc.getCachedVClass(classUri); @@ -193,7 +183,7 @@ public class IndividualsForClassesDataGetter implements PageDataGetter{ List restrictVClasses = new ArrayList(); List urlEncodedRestrictClasses = new ArrayList(); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); if(restrictClasses.size() > 0) { //classes for restriction are not displayed so don't need to include their class individual counts @@ -237,7 +227,7 @@ public class IndividualsForClassesDataGetter implements PageDataGetter{ public static VClassGroupTemplateModel getClassGroup(String classGroupUri, ServletContext context, VitroRequest vreq){ - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(vreq); List vcgList = vcgc.getGroups(); VClassGroup group = null; for( VClassGroup vcg : vcgList){ @@ -275,18 +265,21 @@ public class IndividualsForClassesDataGetter implements PageDataGetter{ return new VClassGroupTemplateModel(group); } - public String getType(){ + @Override + public String getType(){ return PageDataGetterUtils.generateDataGetterTypeURI(IndividualsForClassesDataGetter.class.getName()); } //Get data servuice - public String getDataServiceUrl() { + @Override + public String getDataServiceUrl() { return UrlBuilder.getUrl("/dataservice?getSolrIndividualsByVClasses=1&vclassId="); } /** * For processig of JSONObject */ - public JSONObject convertToJSON(Map map, VitroRequest vreq) { + @Override + public JSONObject convertToJSON(Map map, VitroRequest vreq) { JSONObject rObj = PageDataGetterUtils.processVclassResultsJSON(map, vreq, true); return rObj; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/PageDataGetterUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/PageDataGetterUtils.java index 59670bb02..a29e21011 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/PageDataGetterUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/PageDataGetterUtils.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Map; import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; @@ -29,9 +30,9 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListCont import edu.cornell.mannlib.vitro.webapp.controller.freemarker.IndividualListController.PageRecord; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.json.JsonServlet; +import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; -import edu.cornell.mannlib.vitro.webapp.utils.dataGetter.DataGetterUtils; public class PageDataGetterUtils { protected static final String DATA_GETTER_MAP = "pageTypeToDataGetterMap"; @@ -124,7 +125,7 @@ public class PageDataGetterUtils { for(String dgClassName: dataGetterClassNames) { String className = getClassNameFromUri(dgClassName); - Class clz = Class.forName(className); + Class clz = Class.forName(className); if( PageDataGetter.class.isAssignableFrom(clz)){ PageDataGetter pg = (PageDataGetter) clz.newInstance(); @@ -175,7 +176,7 @@ public class PageDataGetterUtils { @SuppressWarnings("unchecked") Enumeration e = vreq.getParameterNames(); while(e.hasMoreElements()){ - String name = (String)e.nextElement(); + String name = e.nextElement(); log.debug("parameter: " + name); for( String value : vreq.getParameterValues(name) ){ log.debug("value for " + name + ": '" + value + "'"); @@ -299,9 +300,9 @@ public class PageDataGetterUtils { //Get All VClass Groups information //Used within menu management and processing //TODO: Check if more appropriate location possible - public static List> getClassGroups(ServletContext context) { + public static List> getClassGroups(HttpServletRequest req) { //Wanted this to be - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(req); List vcgList = vcgc.getGroups(); //For now encoding as hashmap with label and URI as trying to retrieve class group //results in errors for some reason @@ -323,11 +324,11 @@ public class PageDataGetterUtils { //TODO: Check whether this needs to be put here or elsewhere, as this is data getter specific //with respect to class groups //Need to use VClassGroupCache to retrieve class group information - this is the information returned from "for class group" - public static void getClassGroupForDataGetter(ServletContext context, Map pageData, Map templateData) { + public static void getClassGroupForDataGetter(HttpServletRequest req, Map pageData, Map templateData) { //Get the class group from VClassGroup, this is the same as the class group for the class group page data getter //and the associated class group (not custom) for individuals datagetter String classGroupUri = (String) pageData.get("classGroupUri"); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(req); VClassGroup group = vcgc.getGroup(classGroupUri); templateData.put("classGroup", group); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/solr/SolrQueryUtils.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/solr/SolrQueryUtils.java index c90281377..608ae0efc 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/solr/SolrQueryUtils.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/solr/SolrQueryUtils.java @@ -190,6 +190,26 @@ public class SolrQueryUtils { } } + public static SolrQuery getRandomQuery(List vclassUris, int page, int pageSize){ + String queryText = ""; + + try { + queryText = makeMultiClassQuery(vclassUris); + log.debug("queryText is " + queryText); + SolrQuery query = new SolrQuery(queryText); + + //page count starts at 1, row count starts at 0 + query.setStart( page ).setRows( pageSize ); + + log.debug("Query is " + query.toString()); + return query; + + } catch (Exception ex){ + log.error("Could not make the Solr query",ex); + return new SolrQuery(); + } + } + public static String makeMultiClassQuery( List vclassUris){ List queryTypes = new ArrayList(); try { @@ -217,4 +237,16 @@ public class SolrQueryUtils { return results; } + public static IndividualListQueryResults buildAndExecuteRandomVClassQuery( + List vclassURIs, int page, int pageSize, + ServletContext context, IndividualDao indDao) + throws SolrServerException { + SolrQuery query = SolrQueryUtils.getRandomQuery(vclassURIs, page, pageSize); + IndividualListQueryResults results = IndividualListQueryResults.runQuery(query, indDao, context); + log.debug("Executed solr query for " + vclassURIs); + if (results.getIndividuals().isEmpty()) { + log.debug("entities list is null for vclass " + vclassURIs); + } + return results; + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/solr/SolrResultsParser.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/solr/SolrResultsParser.java index 92a6e9083..30b591c9d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/solr/SolrResultsParser.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/solr/SolrResultsParser.java @@ -37,13 +37,13 @@ public class SolrResultsParser { List> maps = new ArrayList>(); if (queryResponse == null) { - log.error("Query response for a search was null"); + log.debug("Query response for a search was null"); return maps; } SolrDocumentList docs = queryResponse.getResults(); if (docs == null) { - log.error("Docs for a search was null"); + log.debug("Docs for a search was null"); return maps; } log.debug("Total number of hits = " + docs.getNumFound()); @@ -65,13 +65,13 @@ public class SolrResultsParser { List> maps = new ArrayList>(); if (queryResponse == null) { - log.error("Query response for a search was null"); + log.debug("Query response for a search was null"); return maps; } SolrDocumentList docs = queryResponse.getResults(); if (docs == null) { - log.error("Docs for a search was null"); + log.debug("Docs for a search was null"); return maps; } log.debug("Total number of hits = " + docs.getNumFound()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java index 3beda0c8a..f4306cb17 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/edit/EditConfigurationTemplateModel.java @@ -175,10 +175,12 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel { //Also used above and can be used in object auto complete form public String getObjectPropertyNameForDisplay() { + // TODO modify this to get prop/class combo String propertyTitle = null; Individual objectIndividual = EditConfigurationUtils.getObjectIndividual(vreq); ObjectProperty prop = EditConfigurationUtils.getObjectProperty(vreq); Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq); + VClass rangeClass = EditConfigurationUtils.getRangeVClass(vreq); if(objectIndividual != null) { propertyTitle = prop.getDomainPublic(); } else { @@ -186,8 +188,9 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel { if ( prop.getOfferCreateNewOption() ) { //Try to get the name of the class to select from VClass classOfObjectFillers = null; - - if( prop.getRangeVClassURI() == null ) { + if (rangeClass != null) { + classOfObjectFillers = rangeClass; + } else if( prop.getRangeVClassURI() == null ) { // If property has no explicit range, try to get classes List classes = wdf.getVClassDao().getVClassesForProperty(subject.getVClassURI(), prop.getURI()); if( classes == null || classes.size() == 0 || classes.get(0) == null ){ @@ -514,12 +517,23 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel { Individual sub = wdf.getIndividualDao().getIndividualByURI(editConfig.getSubjectUri()); + VClass rangeClass = EditConfigurationUtils.getRangeVClass(vreq); + List vclasses = null; List subjectVClasses = sub.getVClasses(); if( subjectVClasses == null ) { vclasses = wdf.getVClassDao().getAllVclasses(); - } - else { + } else if (rangeClass != null) { + vclasses = new ArrayList(); + vclasses.add(rangeClass); + List subURIs = wdf.getVClassDao().getSubClassURIs(rangeClass.getURI()); + for (String subClassURI : subURIs) { + VClass subClass = wdf.getVClassDao().getVClassByURI(subClassURI); + if (subClass != null) { + vclasses.add(subClass); + } + } + } 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 vclassesURIs = new HashSet(); @@ -546,7 +560,6 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel { HashMap types = new HashMap(); for( VClass vclass : vclasses ){ - String name = null; if( vclass.getPickListName() != null && vclass.getPickListName().length() > 0){ name = vclass.getPickListName(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java index a080cde0b..e7498e668 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java @@ -25,6 +25,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; +import edu.cornell.mannlib.vitro.webapp.utils.ApplicationConfigurationOntologyUtils; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel; /* @@ -72,15 +73,29 @@ public class GroupedPropertyList extends BaseTemplateModel { // so we cannot just rely on getting that list. List populatedObjectPropertyList = subject .getPopulatedObjectPropertyList(); + + List additions = ApplicationConfigurationOntologyUtils + .getAdditionalFauxSubpropertiesForList( + populatedObjectPropertyList, vreq); + if (log.isDebugEnabled()) { + for (ObjectProperty t : additions) { + log.debug(t.getDomainPublic() + " " + t.getGroupURI()); + } + log.debug("Added " + additions.size() + + " properties due to application configuration ontology"); + } + + populatedObjectPropertyList.addAll(additions); + propertyList.addAll(populatedObjectPropertyList); // If editing this page, merge in object properties applicable to the individual that are currently // unpopulated, so the properties are displayed to allow statements to be added to these properties. // RY In future, we should limit this to properties that the user has permission to add properties to. if (editing) { - mergeAllPossibleObjectProperties(populatedObjectPropertyList, propertyList); + mergeAllPossibleObjectProperties(populatedObjectPropertyList, propertyList); } - + // Now do much the same with data properties: get the list of populated data properties, then add in placeholders for missing ones // rjy7 Currently we are getting the list of properties in one sparql query, then doing a separate query // to get values for each property. This could be optimized by doing a single query to get a map of properties to @@ -90,11 +105,11 @@ public class GroupedPropertyList extends BaseTemplateModel { List populatedDataPropertyList = subject .getPopulatedDataPropertyList(); propertyList.addAll(populatedDataPropertyList); - + if (editing) { mergeAllPossibleDataProperties(propertyList); } - + sort(propertyList); // Put the list into groups @@ -108,7 +123,7 @@ public class GroupedPropertyList extends BaseTemplateModel { subject, editing, populatedDataPropertyList, populatedObjectPropertyList)); } - + if (!editing) { pruneEmptyProperties(); } @@ -168,7 +183,7 @@ public class GroupedPropertyList extends BaseTemplateModel { if (pi != null) { if (!alreadyOnObjectPropertyList( populatedObjectPropertyList, pi)) { - addObjectPropertyToPropertyList(pi.getPropertyURI(), + addObjectPropertyToPropertyList(pi.getPropertyURI(), pi.getRangeClassURI(), propertyList); } } else { @@ -184,7 +199,7 @@ public class GroupedPropertyList extends BaseTemplateModel { // constitute a special case (i.e., included in piDao.getAllPossiblePropInstForIndividual()). for (String propertyUri : VITRO_PROPS_TO_ADD_TO_LIST) { if (!alreadyOnPropertyList(propertyList, propertyUri)) { - addObjectPropertyToPropertyList(propertyUri, propertyList); + addObjectPropertyToPropertyList(propertyUri, null, propertyList); } } } @@ -202,10 +217,10 @@ public class GroupedPropertyList extends BaseTemplateModel { return false; } - private void addObjectPropertyToPropertyList(String propertyUri, + private void addObjectPropertyToPropertyList(String propertyUri, String rangeUri, List propertyList) { ObjectPropertyDao opDao = wdf.getObjectPropertyDao(); - ObjectProperty op = opDao.getObjectPropertyByURI(propertyUri); + ObjectProperty op = opDao.getObjectPropertyByURIAndRangeURI(propertyUri, rangeUri); if (op == null) { log.error("ObjectProperty op returned null from opDao.getObjectPropertyByURI(" + propertyUri + ")"); } else if (op.getURI() == null) { @@ -351,7 +366,6 @@ public class GroupedPropertyList extends BaseTemplateModel { } else { String groupUriForProperty = p.getGroupURI(); boolean assignedToGroup = false; - if (groupUriForProperty != null) { for (PropertyGroup pg : groupList) { String groupUri = pg.getURI(); @@ -359,7 +373,7 @@ public class GroupedPropertyList extends BaseTemplateModel { pg.getPropertyList().add(p); assignedToGroup = true; break; - } + } } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java index 9d6bec0f0..49e36d284 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel.java @@ -80,6 +80,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel private PropertyListConfig config; private String objectKey; private String sortDirection; + private String rangeURI; ObjectPropertyTemplateModel(ObjectProperty op, Individual subject, VitroRequest vreq, boolean editing) @@ -89,6 +90,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel setName(op.getDomainPublic()); sortDirection = op.getDomainEntitySortDirection(); + rangeURI = op.getRangeVClassURI(); // Get the config for this object property try { @@ -120,12 +122,20 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel return; } + String rangeUri = (property instanceof ObjectProperty) + ? ((ObjectProperty) property).getRangeVClassURI() + : "data"; + if (propertyUri.equals(VitroVocabulary.IND_MAIN_IMAGE)) { addUrl = getImageUploadUrl(subjectUri, "add"); } else { ParamMap params = new ParamMap( "subjectUri", subjectUri, - "predicateUri", propertyUri); + "predicateUri", propertyUri); + + if (rangeUri != null) { + params.put("rangeUri", rangeUri); + } params.putAll(UrlBuilder.getModelParams(vreq)); @@ -147,8 +157,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel protected List> getStatementData() { ObjectPropertyStatementDao opDao = vreq.getWebappDaoFactory().getObjectPropertyStatementDao(); - - return opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, objectKey, getSelectQuery(), getConstructQueries(), sortDirection); + return opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, objectKey, rangeURI, getSelectQuery(), getConstructQueries(), sortDirection); } protected abstract boolean isEmpty(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/BrowseWidget.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/BrowseWidget.java index d48841ffc..635454ead 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/BrowseWidget.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/BrowseWidget.java @@ -21,6 +21,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.json.JsonServlet; +import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupsForRequest; import edu.cornell.mannlib.vitro.webapp.dao.jena.VClassGroupCache; import edu.cornell.mannlib.vitro.webapp.utils.JsonToFmModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.VClassGroupTemplateModel; @@ -123,7 +124,7 @@ public class BrowseWidget extends Widget { VitroRequest vreq = new VitroRequest(request); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(request); List cgList = vcgc.getGroups(); // List classGroups = @@ -186,7 +187,7 @@ public class BrowseWidget extends Widget { VitroRequest vreq = new VitroRequest(request); //VClassGroup vcg = vreq.getWebappDaoFactory().getVClassGroupDao().getGroupByURI(vcgUri); - VClassGroupCache vcgc = VClassGroupCache.getVClassGroupCache(context); + VClassGroupsForRequest vcgc = VClassGroupCache.getVClassGroups(request); VClassGroup vcg = vcgc.getGroup(vcgUri); //vreq.getWebappDaoFactory().getVClassDao().addVClassesToGroup(vcg, false, true); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/LoginWidget.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/LoginWidget.java index 559b775df..6b314b282 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/LoginWidget.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/LoginWidget.java @@ -12,6 +12,7 @@ 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.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginInProcessFlag; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; @@ -56,7 +57,8 @@ public class LoginWidget extends Widget { EXTERNAL_AUTH_NAME("externalAuthName"), EXTERNAL_AUTH_URL("externalAuthUrl"), CANCEL_URL("cancelUrl"), - SITE_NAME("siteName"); + SITE_NAME("siteName"), + MINIMUM_PASSWORD_LENGTH("minimumPasswordLength"); private final String variableName; @@ -172,6 +174,7 @@ public class LoginWidget extends Widget { Macro.FORCE_PASSWORD_CHANGE.toString()); values.put(TemplateVariable.FORM_ACTION.toString(), getAuthenticateUrl(request)); values.put(TemplateVariable.CANCEL_URL.toString(), getCancelUrl(request)); + values.put(TemplateVariable.MINIMUM_PASSWORD_LENGTH.toString(), UserAccount.MIN_PASSWORD_LENGTH); String errorMessage = bean.getErrorMessageAndClear(); if (!errorMessage.isEmpty()) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/Widget.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/Widget.java index d3e46524d..e7e2741d5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/Widget.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/widgets/Widget.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import javax.servlet.ServletContext; +import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; @@ -107,6 +108,7 @@ public abstract class Widget { private String processMacroToString(Environment env, String widgetName, Macro macro, Map map) { StringWriter out = new StringWriter(); + try { String templateString = macro.getChildNodes().get(0).toString(); // NB Using this method of creating a template from a string does not allow the widget template to import @@ -117,8 +119,16 @@ public abstract class Widget { // the same key, e.g., "widgetTemplate", since one putTemplate() call will clobber a previous one. // We need to give each widget macro template a unique key in the StringTemplateLoader, and check // if it's already there or else add it. Leave this for later. - Template template = new Template("widget", new StringReader(templateString), env.getConfiguration()); - template.process(map, out); + Template template = new Template("widget", new StringReader(templateString), env.getConfiguration()); + + // JB KLUGE The widget is processed in its own environment, which doesn't include these custom attributes. + // JB KLUGE Put them in. + Environment widgetEnv = template.createProcessingEnvironment(map, out); + ServletRequest request = (ServletRequest) env.getCustomAttribute("request"); + widgetEnv.setCustomAttribute("request", request); + widgetEnv.setCustomAttribute("context", env.getCustomAttribute("context")); + widgetEnv.setLocale(request.getLocale()); + widgetEnv.process(); } catch (Exception e) { log.error("Could not process widget " + widgetName, e); } diff --git a/webapp/test/edu/cornell/mannlib/vedit/util/OperationUtils_CloneBeanTest.java b/webapp/test/edu/cornell/mannlib/vedit/util/OperationUtils_CloneBeanTest.java new file mode 100644 index 000000000..83f93278c --- /dev/null +++ b/webapp/test/edu/cornell/mannlib/vedit/util/OperationUtils_CloneBeanTest.java @@ -0,0 +1,431 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vedit.util; + +import static org.junit.Assert.assertEquals; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; + +/** + * All of these tests are for OperationUtils.cloneBean() + */ +public class OperationUtils_CloneBeanTest extends AbstractTestClass { + + // ---------------------------------------------------------------------- + // Allow the tests to expect a RuntimeException with a particular cause. + // ---------------------------------------------------------------------- + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + Matcher causedBy(Class causeClass) { + return new CausedByMatcher(causeClass); + } + + class CausedByMatcher extends BaseMatcher { + private final Class causeClass; + + public CausedByMatcher(Class causeClass) { + this.causeClass = causeClass; + } + + @Override + public boolean matches(Object actualThrowable) { + if (!(actualThrowable instanceof RuntimeException)) { + return false; + } + Throwable cause = ((RuntimeException) actualThrowable).getCause(); + return causeClass.isInstance(cause); + } + + @Override + public void describeTo(Description d) { + d.appendText("RuntimeException caused by " + causeClass.getName()); + } + } + + // ---------------------------------------------------------------------- + // Test for invalid classes + // ---------------------------------------------------------------------- + + @Test(expected = NullPointerException.class) + public void nullArgument() { + OperationUtils.cloneBean(null); + } + + @Test(expected = NullPointerException.class) + public void nullBean() { + OperationUtils + .cloneBean(null, SimpleSuccess.class, SimpleSuccess.class); + } + + @Test(expected = NullPointerException.class) + public void nullBeanClass() { + OperationUtils + .cloneBean(new SimpleSuccess(), null, SimpleSuccess.class); + } + + @Test(expected = NullPointerException.class) + public void nullInterfaceClass() { + OperationUtils + .cloneBean(new SimpleSuccess(), SimpleSuccess.class, null); + } + + @Test(expected = IllegalAccessException.class) + @Ignore("Why doesn't this throw an exception?") + public void privateClass() { + OperationUtils.cloneBean(new PrivateClass()); + } + + @Test + public void privateConstructor() { + thrown.expect(causedBy(NoSuchMethodException.class)); + OperationUtils.cloneBean(new PrivateConstructor()); + } + + @Test + public void abstractClass() { + thrown.expect(causedBy(InstantiationException.class)); + OperationUtils.cloneBean(new ConcreteOfAbstractClass(), + AbstractClass.class, AbstractClass.class); + } + + @Test + public void interfaceClass() { + thrown.expect(causedBy(InstantiationException.class)); + OperationUtils.cloneBean(new ConcreteOfInterfaceClass(), + InterfaceClass.class, InterfaceClass.class); + } + + @Test + public void arrayClass() { + thrown.expect(causedBy(NoSuchMethodException.class)); + OperationUtils.cloneBean(new String[0]); + } + + @Test + public void primitiveTypeClass() { + thrown.expect(causedBy(NoSuchMethodException.class)); + OperationUtils.cloneBean(1, Integer.TYPE, Integer.TYPE); + } + + @Test + public void voidClass() { + thrown.expect(causedBy(NoSuchMethodException.class)); + OperationUtils.cloneBean(new Object(), Void.TYPE, Void.TYPE); + } + + @Test + public void noNullaryConstructor() { + thrown.expect(causedBy(NoSuchMethodException.class)); + OperationUtils.cloneBean(new NoNullaryConstructor(1)); + } + + @Test(expected = ExceptionInInitializerError.class) + public void classThrowsExceptionWhenLoaded() { + OperationUtils.cloneBean(new ThrowsExceptionWhenLoaded()); + } + + @Test + public void initializerThrowsException() { + thrown.expect(causedBy(InvocationTargetException.class)); + OperationUtils.cloneBean("random object", + InitializerThrowsException.class, + InitializerThrowsException.class); + } + + @Test + public void wrongInterfaceClass() { + thrown.expect(causedBy(IllegalArgumentException.class)); + OperationUtils.cloneBean(new WrongConcreteClass(), + WrongConcreteClass.class, WrongInterface.class); + } + + @Test + public void getThrowsException() { + thrown.expect(causedBy(InvocationTargetException.class)); + OperationUtils.cloneBean(new GetMethodThrowsException()); + } + + @Test + public void setThrowsException() { + thrown.expect(causedBy(InvocationTargetException.class)); + OperationUtils.cloneBean(new SetMethodThrowsException()); + } + + private static class PrivateClass { + public PrivateClass() { + } + } + + private static class PrivateConstructor { + private PrivateConstructor() { + } + } + + public abstract static class AbstractClass { + public AbstractClass() { + } + } + + public static class ConcreteOfAbstractClass extends AbstractClass { + public ConcreteOfAbstractClass() { + } + } + + public abstract static class InterfaceClass { + public InterfaceClass() { + } + } + + public static class ConcreteOfInterfaceClass extends InterfaceClass { + public ConcreteOfInterfaceClass() { + } + } + + public static class NoNullaryConstructor { + @SuppressWarnings("unused") + public NoNullaryConstructor(int i) { + // nothing to do + } + } + + public static class ThrowsExceptionWhenLoaded { + static { + if (true) + throw new IllegalArgumentException(); + } + } + + public static class InitializerThrowsException { + { + if (true) + throw new IllegalStateException("Initializer throws exception"); + } + } + + public static class WrongConcreteClass { + private String junk = "junk"; + + public String getJunk() { + return this.junk; + } + + @SuppressWarnings("unused") + private void setJunk(String junk) { + this.junk = junk; + } + } + + public static interface WrongInterface { + String getJunk(); + + void setJunk(String junk); + } + + public static class GetMethodThrowsException { + @SuppressWarnings("unused") + private String junk = "junk"; + + public String getJunk() { + throw new UnsupportedOperationException(); + } + + public void setJunk(String junk) { + this.junk = junk; + } + } + + public static class SetMethodThrowsException { + private String junk = "junk"; + + public String getJunk() { + return this.junk; + } + + @SuppressWarnings("unused") + public void setJunk(String junk) { + throw new UnsupportedOperationException(); + } + } + + // ---------------------------------------------------------------------- + // Test simple success and innocuous variations + // ---------------------------------------------------------------------- + + @Test + public void simpleSuccess() { + expectSuccess(new SimpleSuccess().insertField("label", "a prize")); + } + + @Test + public void getButNoSet() { + expectSuccess(new GetButNoSet().insertField("label", "shouldBeEqual")); + } + + @Test + public void getTakesParameters() { + expectSuccess(new GetTakesParameters().insertField("label", "fine")); + } + + @Test + public void getReturnsVoid() { + expectSuccess(new GetReturnsVoid().insertField("label", "fine")); + } + + @Test + public void getAndSetDontMatch() { + expectSuccess(new GetAndSetDontMatch().insertField("label", "fine")); + } + + @Test + public void getIsStatic() { + expectSuccess(new GetIsStatic().insertField("label", "fine") + .insertField("instanceJunk", "the junk")); + } + + @Test + public void getMethodIsPrivate() { + expectSuccess(new GetMethodIsPrivate().insertField("label", "fine")); + } + + @Test + public void setMethodIsPrivate() { + expectSuccess(new SetMethodIsPrivate().insertField("label", "fine")); + } + + private void expectSuccess(BeanBase original) { + BeanBase cloned = (BeanBase) OperationUtils.cloneBean(original); + assertEquals("Simple success", original, cloned); + } + + public static abstract class BeanBase { + protected final Map fields = new HashMap<>(); + + public BeanBase insertField(String key, Object value) { + if (value != null) { + fields.put(key, value); + } + return this; + } + + @Override + public int hashCode() { + return fields.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o == null) { + return false; + } + if (!this.getClass().equals(o.getClass())) { + return false; + } + return this.fields.equals(((BeanBase) o).fields); + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + fields; + } + } + + public static class SimpleSuccess extends BeanBase { + public String getLabel() { + return (String) fields.get("label"); + } + + public void setLabel(String label) { + insertField("label", label); + } + } + + public static class GetButNoSet extends SimpleSuccess { + public String getJunk() { + throw new UnsupportedOperationException(); + } + } + + public static class GetTakesParameters extends SimpleSuccess { + @SuppressWarnings("unused") + public String getJunk(String why) { + throw new UnsupportedOperationException(); + } + + @SuppressWarnings("unused") + public void setJunk(String junk) { + throw new UnsupportedOperationException(); + } + } + + public static class GetReturnsVoid extends SimpleSuccess { + public void getJunk() { + throw new UnsupportedOperationException(); + } + + @SuppressWarnings("unused") + public void setJunk(String junk) { + throw new UnsupportedOperationException(); + } + } + + public static class GetAndSetDontMatch extends SimpleSuccess { + public String getJunk() { + throw new UnsupportedOperationException(); + } + + @SuppressWarnings("unused") + public void setJunk(Integer junk) { + throw new UnsupportedOperationException(); + } + } + + public static class GetIsStatic extends SimpleSuccess { + public static String getJunk() { + return ("the junk"); + } + + public void setJunk(String junk) { + insertField("instanceJunk", junk); + } + } + + public static class GetMethodIsPrivate extends SimpleSuccess { + @SuppressWarnings("unused") + private String getJunk() { + return ("the junk"); + } + + public void setJunk(String junk) { + insertField("instanceJunk", junk); + } + } + + public static class SetMethodIsPrivate extends SimpleSuccess { + public String getJunk() { + return ("the junk"); + } + + @SuppressWarnings("unused") + private void setJunk(String junk) { + insertField("instanceJunk", junk); + } + } + +} diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactoryTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactoryTest.java index fb32a9728..8d6f38420 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactoryTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactoryTest.java @@ -29,6 +29,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; /** * Can we tell whether a user is logged in as root? @@ -79,7 +80,7 @@ public class HasPermissionFactoryTest extends AbstractTestClass { wdf.setUserAccountsDao(uaDao); ctx = new ServletContextStub(); - ctx.setAttribute("webappDaoFactory", wdf); + ModelAccess.on(ctx).setWebappDaoFactory(wdf); session = new HttpSessionStub(); session.setServletContext(ctx); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactoryTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactoryTest.java index 2c08c0e16..2ab4e0fff 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactoryTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactoryTest.java @@ -19,6 +19,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; /** * Can we tell whether a user is logged in as root? @@ -56,7 +57,7 @@ public class IsRootUserFactoryTest extends AbstractTestClass { wdf.setUserAccountsDao(uaDao); ctx = new ServletContextStub(); - ctx.setAttribute("webappDaoFactory", wdf); + ModelAccess.on(ctx).setWebappDaoFactory(wdf); session = new HttpSessionStub(); session.setServletContext(ctx); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactoryTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactoryTest.java index 5a5156b9e..e9c7d59fb 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactoryTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactoryTest.java @@ -19,6 +19,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsUser; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; /** * The simplest of the IdentifierBundleFactory classes. @@ -46,7 +47,7 @@ public class IsUserFactoryTest extends AbstractTestClass { wdf.setUserAccountsDao(uaDao); ctx = new ServletContextStub(); - ctx.setAttribute("webappDaoFactory", wdf); + ModelAccess.on(ctx).setWebappDaoFactory(wdf); session = new HttpSessionStub(); session.setServletContext(ctx); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java index 0daddc50a..d94efae2c 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperTest.java @@ -73,7 +73,7 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass { bean = new PropertyRestrictionPolicyHelper( Arrays.asList(PROHIBITED_NAMESPACES), Arrays.asList(PERMITTED_EXCEPTIONS), displayLevels, - modifyLevels); + modifyLevels, ModelFactory.createDefaultModel()); } @Before diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java index 10e937af9..bd13ae520 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/edit/AuthenticateTest.java @@ -26,6 +26,7 @@ import stubs.edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesStub import stubs.edu.cornell.mannlib.vitro.webapp.dao.IndividualDaoStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDaoStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; +import stubs.edu.cornell.mannlib.vitro.webapp.i18n.I18nStub; import stubs.javax.servlet.ServletConfigStub; import stubs.javax.servlet.ServletContextStub; import stubs.javax.servlet.http.HttpServletRequestStub; @@ -47,6 +48,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.AuthenticatorStub; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.State; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; /** */ @@ -119,6 +121,11 @@ public class AuthenticateTest extends AbstractTestClass { @Before public void setup() throws Exception { + // Create an I18n module that has a value for any key, but the value is + // the key itself. + @SuppressWarnings("unused") + I18nStub i18n = new I18nStub(); + authenticatorFactory = new AuthenticatorStub.Factory(); authenticator = authenticatorFactory.getInstance(request); authenticator.addUser(createUserFromUserInfo(NEW_DBA)); @@ -147,7 +154,7 @@ public class AuthenticateTest extends AbstractTestClass { webappDaoFactory.setIndividualDao(individualDao); servletContext = new ServletContextStub(); - servletContext.setAttribute("webappDaoFactory", webappDaoFactory); + ModelAccess.on(servletContext).setWebappDaoFactory(webappDaoFactory); servletContext.setAttribute(AuthenticatorStub.FACTORY_ATTRIBUTE_NAME, authenticatorFactory); @@ -313,7 +320,7 @@ public class AuthenticateTest extends AbstractTestClass { doTheRequest(); assertProcessBean(LOGGING_IN, NO_USER, NO_MSG, - "Please enter your email address.", URL_LOGIN, URL_WITH_LINK); + "error_no_email_address", URL_LOGIN, URL_WITH_LINK); assertRedirectToLoginProcessPage(); } @@ -325,8 +332,7 @@ public class AuthenticateTest extends AbstractTestClass { doTheRequest(); assertProcessBean(LOGGING_IN, "unknownBozo", NO_MSG, - "The email or password you entered is incorrect.", URL_LOGIN, - URL_WITH_LINK); + "error_incorrect_credentials", URL_LOGIN, URL_WITH_LINK); assertRedirectToLoginProcessPage(); } @@ -338,7 +344,7 @@ public class AuthenticateTest extends AbstractTestClass { doTheRequest(); assertProcessBean(LOGGING_IN, NEW_DBA_NAME, NO_MSG, - "Please enter your password.", URL_LOGIN, URL_WITH_LINK); + "error_no_password", URL_LOGIN, URL_WITH_LINK); assertRedirectToLoginProcessPage(); } @@ -350,8 +356,7 @@ public class AuthenticateTest extends AbstractTestClass { doTheRequest(); assertProcessBean(LOGGING_IN, NEW_DBA_NAME, NO_MSG, - "The email or password you entered is incorrect.", URL_LOGIN, - URL_WITH_LINK); + "error_incorrect_credentials", URL_LOGIN, URL_WITH_LINK); assertRedirectToLoginProcessPage(); } @@ -402,8 +407,7 @@ public class AuthenticateTest extends AbstractTestClass { doTheRequest(); assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG, - "Please enter a password between 6 and 12 " - + "characters in length.", URL_LOGIN, URL_WITH_LINK); + "error_password_length", URL_LOGIN, URL_WITH_LINK); assertRedirectToLoginProcessPage(); } @@ -416,7 +420,7 @@ public class AuthenticateTest extends AbstractTestClass { doTheRequest(); assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG, - "The passwords entered do not match.", URL_LOGIN, URL_WITH_LINK); + "error_passwords_dont_match", URL_LOGIN, URL_WITH_LINK); assertRedirectToLoginProcessPage(); } @@ -429,7 +433,7 @@ public class AuthenticateTest extends AbstractTestClass { doTheRequest(); assertProcessBean(FORCED_PASSWORD_CHANGE, NEW_DBA_NAME, NO_MSG, - "Your new password cannot match the current one.", URL_LOGIN, + "error_previous_password", URL_LOGIN, URL_WITH_LINK); assertRedirectToLoginProcessPage(); } diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java index ee63e2845..3b6e103be 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/controller/json/JsonServletTest.java @@ -28,6 +28,7 @@ import stubs.javax.servlet.http.HttpSessionStub; import stubs.org.apache.solr.client.solrj.SolrServerStub; import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.webapp.beans.VClass; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.search.solr.SolrSetup; /** @@ -106,8 +107,7 @@ public class JsonServletTest extends AbstractTestClass { resp = new HttpServletResponseStub(); wadf = new WebappDaoFactoryStub(); - req.setAttribute("webappDaoFactory", wadf); - ctx.setAttribute("webappDaoFactory", wadf); + ModelAccess.on(ctx).setWebappDaoFactory(wadf); vcDao = new VClassDaoStub(); wadf.setVClassDao(vcDao); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/PageDataGetterUtilsTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/PageDataGetterUtilsTest.java index 7a97f2c99..a6745102c 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/PageDataGetterUtilsTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/utils/pageDataGetter/PageDataGetterUtilsTest.java @@ -18,6 +18,7 @@ import com.hp.hpl.jena.rdf.model.impl.RDFDefaultErrorHandler; import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.SimpleOntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; @@ -48,7 +49,7 @@ public class PageDataGetterUtilsTest extends AbstractTestClass{ @Test public void testGetPageDataGetterObjects() throws Exception{ VitroRequest vreq = new VitroRequest( new HttpServletRequestStub() ); - vreq.setWebappDaoFactory(wdf); + ModelAccess.on(vreq).setWebappDaoFactory(wdf); List pdgList = PageDataGetterUtils.getPageDataGetterObjects(vreq, pageURI); Assert.assertNotNull(pdgList); @@ -58,7 +59,7 @@ public class PageDataGetterUtilsTest extends AbstractTestClass{ @Test public void testGetNonPageDataGetterObjects() throws Exception{ VitroRequest vreq = new VitroRequest( new HttpServletRequestStub() ); - vreq.setWebappDaoFactory(wdf); + ModelAccess.on(vreq).setWebappDaoFactory(wdf); List pdgList = PageDataGetterUtils.getPageDataGetterObjects(vreq, pageURI_2); Assert.assertNotNull(pdgList); diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel_PropertyListConfigTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel_PropertyListConfigTest.java index 1ab3f53f2..2ae768482 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel_PropertyListConfigTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/ObjectPropertyTemplateModel_PropertyListConfigTest.java @@ -25,6 +25,10 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import com.hp.hpl.jena.ontology.OntModel; +import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.rdf.model.ModelFactory; + import stubs.edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDaoStub; import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub; import stubs.freemarker.cache.TemplateLoaderStub; @@ -36,6 +40,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.PropertyListConfig; @@ -123,7 +129,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends hreq.setSession(session); vreq = new VitroRequest(hreq); - vreq.setWebappDaoFactory(wadf); + ModelAccess.on(vreq).setWebappDaoFactory(wadf); subject = new IndividualImpl(); @@ -273,6 +279,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends @Test public void constructQueryNodeMissing() throws InvalidConfigurationException { + ModelAccess.on(vreq).setOntModel(ModelID.UNION_FULL, emptyOntModel()); op = buildOperation("constructQueryMissing"); optm = new NonCollatingOPTM(op, subject, vreq, true); // Not an error. @@ -281,6 +288,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends @Test public void constructQueryMultipleValues() throws InvalidConfigurationException { + ModelAccess.on(vreq).setOntModel(ModelID.UNION_FULL, emptyOntModel()); op = buildOperation("constructQueryMultiple"); optm = new NonCollatingOPTM(op, subject, vreq, true); assertConstructQueries("multiple construct queries", "ONE", "TWO", @@ -367,6 +375,10 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends // Helper methods // ---------------------------------------------------------------------- + private OntModel emptyOntModel() { + return ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); + } + /** * Sets up an operation with name "foobar" and adds it to the * ObjectPropertyDaoStub. diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperStub.java index ec4a66961..0bd259d9f 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionPolicyHelperStub.java @@ -8,6 +8,9 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; + import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; @@ -57,7 +60,7 @@ public class PropertyRestrictionPolicyHelperStub extends Map displayThresholds, Map modifyThresholds) { super(modifyRestrictedNamespaces, modifyPermittedExceptions, - displayThresholds, modifyThresholds); + displayThresholds, modifyThresholds, ModelFactory.createDefaultModel()); } } diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDaoStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDaoStub.java index 37a0428f5..8bcdf87ef 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDaoStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyDaoStub.java @@ -65,6 +65,11 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao { } return opMap.get(objectPropertyURI); } + + @Override + public ObjectProperty getObjectPropertyByURIAndRangeURI(String objectPropertyURI, String rangeURI) { + return getObjectPropertyByURI(objectPropertyURI); + } @Override public String getCustomListViewConfigFileName(ObjectProperty objectProperty) { diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDaoStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDaoStub.java index aebcd0fb1..d5913a557 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDaoStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDaoStub.java @@ -216,7 +216,7 @@ public class ObjectPropertyStatementDaoStub implements @Override public List> getObjectPropertyStatementsForIndividualByProperty( - String subjectUri, String propertyUri, String objectKey, + String subjectUri, String propertyUri, String objectKey, String rangeUri, String query, Set constructQueries, String sortDir) { throw new RuntimeException( "ObjectPropertyStatementDaoStub.getObjectPropertyStatementsForIndividualByProperty() not implemented."); diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/i18n/I18nStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/i18n/I18nStub.java new file mode 100644 index 000000000..4fd6b7add --- /dev/null +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/i18n/I18nStub.java @@ -0,0 +1,78 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package stubs.edu.cornell.mannlib.vitro.webapp.i18n; + +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.Enumeration; +import java.util.ResourceBundle; + +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; + +/** + * An implementation of I18n for unit tests. Construct a new instance and it + * replaces the instance of I18n. + * + * Each bundle that you get from it is the same, returning the key itself as the + * value of that key. + */ +public class I18nStub extends I18n { + private static final Log log = LogFactory.getLog(I18nStub.class); + + // ---------------------------------------------------------------------- + // Stub infrastructure + // ---------------------------------------------------------------------- + + public I18nStub() { + try { + Field instanceField = I18n.class.getDeclaredField("instance"); + log.debug("Field is " + instanceField); + instanceField.setAccessible(true); + log.debug("Instance is " + instanceField.get(null)); + instanceField.set(null, this); + log.debug("Instance is " + instanceField.get(null)); + log.debug("Created and inserted."); + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + + @Override + protected I18nBundle getBundle(String bundleName, HttpServletRequest req) { + return new I18nBundleStub(bundleName); + } + + private class I18nBundleStub extends I18nBundle { + public I18nBundleStub(String bundleName) { + super(bundleName, new DummyResourceBundle()); + } + + @Override + public String text(String key, Object... parameters) { + return key; + } + } + + /** + * Not actually used, but the constructor of I18nBundle requires a non-null + * ResourceBundle. + */ + private class DummyResourceBundle extends ResourceBundle { + @Override + protected Object handleGetObject(String key) { + return key; + } + + @Override + public Enumeration getKeys() { + return Collections.emptyEnumeration(); + } + } +} diff --git a/webapp/test/stubs/javax/servlet/http/HttpSessionStub.java b/webapp/test/stubs/javax/servlet/http/HttpSessionStub.java index af27594d7..649e2c1e4 100644 --- a/webapp/test/stubs/javax/servlet/http/HttpSessionStub.java +++ b/webapp/test/stubs/javax/servlet/http/HttpSessionStub.java @@ -12,10 +12,11 @@ import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import stubs.javax.servlet.ServletContextStub; + /** * A simple stand-in for the HttpSession, for use in unit tests. */ -@SuppressWarnings("deprecation") public class HttpSessionStub implements HttpSession { private static final Log log = LogFactory.getLog(HttpSessionStub.class); @@ -49,7 +50,11 @@ public class HttpSessionStub implements HttpSession { @Override public ServletContext getServletContext() { - return this.context; + if (this.context == null) { + return new ServletContextStub(); + } else { + return this.context; + } } @Override @@ -149,6 +154,7 @@ public class HttpSessionStub implements HttpSession { "HttpSessionStub.putValue() not implemented."); } + @Override public void removeValue(String arg0) { throw new RuntimeException( "HttpSessionStub.removeValue() not implemented."); diff --git a/webapp/themes/vitro/css/vitroTheme.css b/webapp/themes/vitro/css/vitroTheme.css index dce6060c8..3fd41b0c4 100644 --- a/webapp/themes/vitro/css/vitroTheme.css +++ b/webapp/themes/vitro/css/vitroTheme.css @@ -622,6 +622,12 @@ body.login #login { padding-top: 18px; border-bottom: none; } +h3.internal-auth { + color: #5E6363; +} +h3.internal-auth:hover { + color: #47B6D0; +} #error-alert { margin: 0 12px; margin-bottom: 12px; @@ -742,6 +748,51 @@ p.password-note { margin-right:-10px; height:34px; } + +/* SEARCH HOME------> */ + +#search-home-field { + background: url(../images/search-field-and-button.gif) 0 0 no-repeat; +} +#search-home-field input.search { + background-color: transparent; + color: #fff; + border: none; +} + +input.search-homepage { + border: 0; + background-color: #f9fafa; + background: url('../images/limit-search.png') no-repeat; + background-position: right; + opacity: .7; +} + +.filter-default { + background: url(../images/filteredSearch.gif) 0 0 no-repeat; +} +.filter-active { + background: url(../images/filteredSearchActive.gif) 0 0 no-repeat; +} +#filter-search-nav { + background-color: #2d3535; + color: #fff; + background-color: #2d3535; + color: #fff; +} +#filter-search-nav li { + background-image: none; + padding-left: 0; + margin-left: 0; +} +#filter-search-nav a.active { + color: #fff; +} +#filter-search-nav a { + border-bottom: 1px dotted #4f5656; + color: #1483A4; +} + /* BROWSE ------> */ #browse { background-color: #f7f5f0; @@ -801,6 +852,41 @@ ul#browse-classgroups a.selected span.count-classes, ul#browse-classgroups a:hover span.count-classes { color: #fff; } + +/* HOME STATS-----> */ +#home-stats { + border-top: 1px dotted #dbe3e3; /* stroke */ + border-bottom: 1px dotted #dbe3e3; /* stroke */ + background-color: #fff; /* layer fill content */ +} +#home-stats h4 { + border-top: 1px solid rgba(220,228,227,.42); /* stroke */ + border-bottom: 1px solid rgba(220,228,227,.42); /* stroke */ + background-color: #395d7f; /* layer fill content */ + border-bottom: 2px solid #62b6d7; + color: #fff; +} +#stats li { + -moz-border-radius: 6px; + -webkit-border-radius: 6px; + border-radius: 6px; /* border radius */ + -moz-background-clip: padding; + -webkit-background-clip: padding-box; + background-clip: padding-box; /* prevents bg color from leaking outside the border */ + background: #5e6363 url(../images/stats-bg.png) repeat-x 0 0; + color: #fff; +} +#stats p { + color: #fff; +} +#stats li a:hover { + opacity: .5; +} +#stats .stats-count span { + color: #fff; + opacity: .5; +} + /* FOOTER------> */ footer { clear: both; diff --git a/webapp/themes/vitro/images/filteredSearch.gif b/webapp/themes/vitro/images/filteredSearch.gif new file mode 100644 index 000000000..16bb82be2 Binary files /dev/null and b/webapp/themes/vitro/images/filteredSearch.gif differ diff --git a/webapp/themes/vitro/images/filteredSearchActive.gif b/webapp/themes/vitro/images/filteredSearchActive.gif new file mode 100644 index 000000000..8ef75fbeb Binary files /dev/null and b/webapp/themes/vitro/images/filteredSearchActive.gif differ diff --git a/webapp/themes/vitro/images/limit-search.png b/webapp/themes/vitro/images/limit-search.png new file mode 100644 index 000000000..9eabf8cd0 Binary files /dev/null and b/webapp/themes/vitro/images/limit-search.png differ diff --git a/webapp/themes/vitro/images/search-field-and-button.gif b/webapp/themes/vitro/images/search-field-and-button.gif new file mode 100644 index 000000000..3b672288e Binary files /dev/null and b/webapp/themes/vitro/images/search-field-and-button.gif differ diff --git a/webapp/themes/vitro/templates/footer.ftl b/webapp/themes/vitro/templates/footer.ftl index 29e054ead..eb57f61e5 100644 --- a/webapp/themes/vitro/templates/footer.ftl +++ b/webapp/themes/vitro/templates/footer.ftl @@ -7,25 +7,25 @@ <#if copyright??> ©${copyright.year?c} <#if copyright.url??> - ${copyright.text} + ${copyright.text} <#else> ${copyright.text} - | Terms of Use | + | ${i18n().terms_of_use} | - Powered by Vitro + ${i18n().powered_by} Vitro <#if user.hasRevisionInfoAccess> - | Version ${version.label} + | ${i18n().version} ${version.label}

diff --git a/webapp/themes/vitro/templates/identity.ftl b/webapp/themes/vitro/templates/identity.ftl index 127c66fc6..478452f34 100644 --- a/webapp/themes/vitro/templates/identity.ftl +++ b/webapp/themes/vitro/templates/identity.ftl @@ -1,7 +1,7 @@ <#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> \ No newline at end of file + \ No newline at end of file diff --git a/webapp/themes/vitro/templates/menu.ftl b/webapp/themes/vitro/templates/menu.ftl index a09f090d5..09bb02473 100644 --- a/webapp/themes/vitro/templates/menu.ftl +++ b/webapp/themes/vitro/templates/menu.ftl @@ -1,9 +1,11 @@ <#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + + @@ -23,6 +25,6 @@ \ No newline at end of file diff --git a/webapp/themes/vitro/templates/page-home.ftl b/webapp/themes/vitro/templates/page-home.ftl index 9e03b1a9c..85b519eca 100644 --- a/webapp/themes/vitro/templates/page-home.ftl +++ b/webapp/themes/vitro/templates/page-home.ftl @@ -1,7 +1,7 @@ <#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> <@widget name="login" include="assets" /> -<#include "browse-classgroups.ftl"> +<#import "lib-home-page.ftl" as lh> @@ -15,23 +15,57 @@ <#include "menu.ftl">
-

What is VITRO?

+

${i18n().what_is_vitro}

-

Vitro is a general-purpose web-based ontology and instance editor with customizable public browsing. Vitro is a Java web application that runs in a Tomcat servlet container.

-

With Vitro, you can:

+

${i18n().vitro_description}

+

${i18n().with_vitro}

    -
  • Create or load ontologies in OWL format
  • -
  • Edit instances and relationships
  • -
  • Build a public web site to display your data
  • -
  • Search your data
  • +
  • ${i18n().vitro_bullet_one}
  • +
  • ${i18n().vitro_bullet_two}
  • +
  • ${i18n().vitro_bullet_three}
  • +
  • ${i18n().vitro_bullet_four}
+ +
+

${i18n().search_vitro} filteredSearch

+ +
+ ${i18n().search_form} + +
+
+
- <@widget name="login" /> - <@allClassGroups vClassGroups! /> + + <@widget name="login" /> + + + <@lh.allClassGroups vClassGroups! /> <#include "footer.ftl"> + \ No newline at end of file diff --git a/webapp/themes/vitro/templates/page.ftl b/webapp/themes/vitro/templates/page.ftl index 5e4577f43..f234c0dac 100644 --- a/webapp/themes/vitro/templates/page.ftl +++ b/webapp/themes/vitro/templates/page.ftl @@ -11,6 +11,19 @@ <#include "identity.ftl"> + + <#include "menu.ftl"> ${body} diff --git a/webapp/web/WEB-INF/filegraph/tbox/vitroPublic.owl b/webapp/web/WEB-INF/filegraph/tbox/vitroPublic.owl index d1f51520a..3e4afaf2a 100644 --- a/webapp/web/WEB-INF/filegraph/tbox/vitroPublic.owl +++ b/webapp/web/WEB-INF/filegraph/tbox/vitroPublic.owl @@ -48,6 +48,11 @@ + + + + + diff --git a/webapp/web/WEB-INF/resources/startup_listeners.txt b/webapp/web/WEB-INF/resources/startup_listeners.txt index 251a26458..202508ebd 100644 --- a/webapp/web/WEB-INF/resources/startup_listeners.txt +++ b/webapp/web/WEB-INF/resources/startup_listeners.txt @@ -20,8 +20,8 @@ edu.cornell.mannlib.vitro.webapp.servlet.setup.RDFServiceSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.ApplicationModelSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.UserModelSetup - -edu.cornell.mannlib.vitro.webapp.servlet.setup.WebappDaoSetup +edu.cornell.mannlib.vitro.webapp.servlet.setup.ContentModelSetup +edu.cornell.mannlib.vitro.webapp.servlet.setup.ModelMakerSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase diff --git a/webapp/web/WEB-INF/web.xml b/webapp/web/WEB-INF/web.xml index 5f5407e94..10d3944f4 100644 --- a/webapp/web/WEB-INF/web.xml +++ b/webapp/web/WEB-INF/web.xml @@ -88,6 +88,17 @@ /* + + + Recognize conditional requests, and generate Cache-Control headers. + Caching Response filter + edu.cornell.mannlib.vitro.webapp.filters.CachingResponseFilter + + + Caching Response filter + /* + + JSession Strip Filter edu.cornell.mannlib.vitro.webapp.filters.JSessionStripFilter @@ -107,20 +118,11 @@ - WebappDaoFactorySDBPrep - edu.cornell.mannlib.vitro.webapp.filters.WebappDaoFactorySDBPrep + RequestModelsPrep + edu.cornell.mannlib.vitro.webapp.filters.RequestModelsPrep - WebappDaoFactorySDBPrep - /* - - - - VitroRequestPrep - edu.cornell.mannlib.vitro.webapp.filters.VitroRequestPrep - - - VitroRequestPrep + RequestModelsPrep /* REQUEST FORWARD @@ -1083,14 +1085,6 @@ logout /logout - - pubsbyorg - /pubsbyorg - - - coauthors - /coauthors - diff --git a/webapp/web/admin/conceptRepair.jsp b/webapp/web/admin/conceptRepair.jsp index f8d0796cb..301b105e3 100644 --- a/webapp/web/admin/conceptRepair.jsp +++ b/webapp/web/admin/conceptRepair.jsp @@ -3,6 +3,7 @@ <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page import="edu.cornell.mannlib.vitro.webapp.controller.Controllers" %> +<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess"%> <%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %> <%@page import="edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission" %> @@ -21,7 +22,7 @@ " FILTER(afn:bnode(?bnode) = \"" + conceptIdStr + "\")\n" + "}"; - OntModel ontModel = (OntModel) getServletContext().getAttribute("baseOntModel"); + OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); Model conceptDescription = ModelFactory.createDefaultModel(); try { ontModel.enterCriticalSection(Lock.READ); diff --git a/webapp/web/admin/gotoIndividual.jsp b/webapp/web/admin/gotoIndividual.jsp index d01251724..b0311eb3c 100644 --- a/webapp/web/admin/gotoIndividual.jsp +++ b/webapp/web/admin/gotoIndividual.jsp @@ -1,6 +1,5 @@ <%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%> -<%@page import="edu.cornell.mannlib.vitro.webapp.filters.VitroRequestPrep"%> <%@ page import="edu.cornell.mannlib.vitro.webapp.controller.Controllers" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> diff --git a/webapp/web/admin/removeBadRestrictions.jsp b/webapp/web/admin/removeBadRestrictions.jsp index 6954e50d0..18e8e78d8 100644 --- a/webapp/web/admin/removeBadRestrictions.jsp +++ b/webapp/web/admin/removeBadRestrictions.jsp @@ -4,12 +4,13 @@ <%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %> <%@page import="edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission" %> +<%@page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess"%> <% request.setAttribute("requestedActions", SimplePermission.USE_MISCELLANEOUS_CURATOR_PAGES.ACTION); %> <% if (request.getParameter("execute") != null) { - OntModel ontModel = (OntModel) getServletContext().getAttribute(JenaBaseDao.ASSERTIONS_ONT_MODEL_ATTRIBUTE_NAME); + OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); int results = doRemoval(ontModel); request.setAttribute("removalCount", results); } @@ -66,7 +67,7 @@ " FILTER(afn:bnode(?bnode) = \"" + bnodeId + "\")\n" + "}"; - OntModel ontModel = (OntModel) getServletContext().getAttribute("baseOntModel"); + OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); Model conceptDescription = ModelFactory.createDefaultModel(); try { ontModel.enterCriticalSection(Lock.READ); diff --git a/webapp/web/admin/removeResourceDescription.jsp b/webapp/web/admin/removeResourceDescription.jsp index 080fb5f63..874e1f0cb 100644 --- a/webapp/web/admin/removeResourceDescription.jsp +++ b/webapp/web/admin/removeResourceDescription.jsp @@ -6,6 +6,7 @@ <%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %> <%@page import="edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission" %> +<%@page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess"%> <% request.setAttribute("requestedActions", SimplePermission.USE_MISCELLANEOUS_CURATOR_PAGES.ACTION); %> @@ -16,7 +17,7 @@ String describeQueryStr = "DESCRIBE <" + resourceURIStr + ">"; - OntModel ontModel = (OntModel) getServletContext().getAttribute("baseOntModel"); + OntModel ontModel = ModelAccess.on(getServletContext()).getBaseOntModel(); Model resourceDescription = ModelFactory.createDefaultModel(); try { ontModel.enterCriticalSection(Lock.READ); diff --git a/webapp/web/admin/syncSesame.jsp b/webapp/web/admin/syncSesame.jsp index d97aa3f56..5f2acffbc 100644 --- a/webapp/web/admin/syncSesame.jsp +++ b/webapp/web/admin/syncSesame.jsp @@ -7,6 +7,7 @@ <%@page import="edu.cornell.mannlib.vitro.webapp.dao.jena.JenaModelUtils"%> <%@page import="com.hp.hpl.jena.rdf.model.Model"%> <%@page import="edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDao"%> +<%@page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess"%> <%@page import="java.io.InputStream"%> <%@page import="java.util.Properties"%> <%@ page import="edu.cornell.mannlib.vitro.webapp.controller.Controllers" %> @@ -54,7 +55,7 @@ } String contextId = sesameProperties.getProperty(SESAME_CONTEXT); - Model fullModel = (Model) getServletContext().getAttribute(JenaBaseDao.JENA_ONT_MODEL_ATTRIBUTE_NAME); + Model fullModel = ModelAccess.on(getServletContext()).getJenaOntModel(); // Copy the model to avoid locking the main model during sync. Assumes enough memory. Model copyModel = ModelFactory.createDefaultModel(); fullModel.enterCriticalSection(Lock.READ); diff --git a/webapp/web/css/login.css b/webapp/web/css/login.css index 04f6e3d42..816dce895 100644 --- a/webapp/web/css/login.css +++ b/webapp/web/css/login.css @@ -59,11 +59,21 @@ p.request-account { font-size: .8em; } h3.internal-auth { - margin-left: 38px; - color: #5F6464; + margin-left: 20px; font-size: 1em; margin-bottom: 0; padding-bottom: 0; + text-decoration: none; + cursor: hand; + cursor: pointer; + text-align: center; + line-height: 1.4em; +} +.vivoAccount { + display: none; +} +#vivoAccountError { + display: block; } .formFieldAlert { border: 2px solid #900; diff --git a/webapp/web/css/menupage/menupage.css b/webapp/web/css/menupage/menupage.css index 8a2205fd9..7a41e3767 100644 --- a/webapp/web/css/menupage/menupage.css +++ b/webapp/web/css/menupage/menupage.css @@ -197,9 +197,12 @@ ul#alpha-browse-individuals { } ul#alpha-browse-individuals li { float: left; - margin-right: 4px; + margin-right: 5px; padding-top: 0px; } +ul#alpha-browse-individuals li:first-child { + padding-left: 1px; +} ul#alpha-browse-individuals li:last-child { border-bottom: 0; } @@ -208,7 +211,6 @@ ul#alpha-browse-individuals a { height: 35px; margin-left: 0; padding-left: 8px; - width: 10px; } nav#alpha-browse-container { width: 619px; diff --git a/webapp/web/css/search.css b/webapp/web/css/search.css index 35b6857eb..b3717888a 100644 --- a/webapp/web/css/search.css +++ b/webapp/web/css/search.css @@ -79,7 +79,22 @@ ul.searchTips li { } span#searchHelp { float:right; - margin-top:-45px; + margin-top:10px; font-size:.825em; padding-right:32px +} + +span#downloadResults { + float:left; + margin-top:10px; + font-size:.825em; + padding-left:10px +} + +img#downloadIcon { + cursor: pointer; +} + +.download-url { + padding: 5px 25px 5px; } \ No newline at end of file diff --git a/webapp/web/css/vitro.css b/webapp/web/css/vitro.css index 4a10bf0d4..c2001d95b 100644 --- a/webapp/web/css/vitro.css +++ b/webapp/web/css/vitro.css @@ -133,10 +133,17 @@ border-bottom: none } .searchTOC ul a { - display: block; + display: inline; padding-left: 25px; } +.searchTOC ul span { + float:right; + padding-right: 10px; + color:grey; + font-size:smaller; +} + /* -------------------------------------------------> */ /* DROP DOWN USER MENU ----------------------------> */ /* -------------------------------------------------> */ @@ -246,4 +253,152 @@ section#rdfsLabels a.cancel { p#mngLabelsText { margin-left:25px; margin-bottom:12px; +} + +/* SEARCH HOME------> */ +#search-home { + margin-top: 2em; + width: 570px; +} + +#search-home h3 { + padding-left: 24px; +} +#search-homepage { + position: relative; + padding-left: 24px; +} +#search-home-field { + width: 530px; + height: 44px; +} +#search-home-field input.search { + text-decoration: none; + font-size: 18px; + border: none; + padding-left: 13px; + padding-top: 8px; + cursor: pointer; +} +span.search-filter-selected { + display: none; +} +input.search-homepage { + float: left; + height: 20px; + border: 0; + font-size: 18px; + margin-left: 4px; + margin-top: 2px; + margin-right: 40px; + margin-top: 2px; + width: 351px; + background-position: right; +} +a.filter-search { + position: absolute; + vertical-align: middle; + display: inline-block; + width: 39px; + height: 43px; + z-index: 9999; + top: 0; + right: 135px; + z-index: 9999; +} +.filter-default { + +} +.filter-active { + +} +#filter-search-nav { + position: absolute; + width: 184px; + top: 0; + right: 135px; + z-index: 9998; + display: none; + list-style-type: none; +} +#filter-search-nav li { + padding-left: 0; + margin-left: 0; + list-style-type: none; + background-image: none; +} +#filter-search-nav { + z-index: 9998; +} +#filter-search-nav a.active { + +} +#filter-search-nav a { + font-size: 17px; + display: block; + margin-left: 15px; + margin-right: 15px; + padding-top: 8px; + padding-bottom: 8px; + text-decoration: none; + +} + +/* HOME STATS-----> */ +#home-stats { + margin-top: 1em; + width: 921px; + height: 213px; + clear: both; +} +.home-sections h4 { + margin-top: 0; + height: 34px; + font-size: 18px; + text-align: center; + margin-left: 35px; + padding: 0; + line-height: 35px; +} +#home-stats h4 { + width: 102px; +} +#stats { + margin: 0 auto; + width: 875px; +} +#stats li { + float: left; + width: 108px; + height: 102px; + margin-top: 35px; + margin-right: 25px; +} +#stats p { + +} +#stats li a { + text-decoration: none; +} +#stats li a:hover { + +} +#stats li:first-child { + margin-left: 50px; +} +#stats .stats-count { + text-align: center; + font-size: 42px; + margin: 0; + padding-top: 30px; +} +#stats .stats-count span { + font-size: 18px; + padding-left: 2px; +} +#stats .stats-type { + font-size: 13px; + text-align: center; + margin: 0; + margin-top: 13px; } \ No newline at end of file diff --git a/webapp/web/i18n/all.properties b/webapp/web/i18n/all.properties new file mode 100644 index 000000000..c5192e028 --- /dev/null +++ b/webapp/web/i18n/all.properties @@ -0,0 +1,857 @@ +# +# Text strings for the controllers and templates +# +# Default (English) +# +save_changes = Save changes +cancel_link = Cancel +cancel_title = cancel +required_fields = required fields +or = or +alt_error_alert = Error alert icon +alt_confirmation = Confirmation icon + +email_address = Email address +first_name = First name +last_name = Last name +roles = Roles +status = Status + +ascending_order = ascending order +descending_order = descending order +select_one = Select one + +type_more_characters = type more characters +no_match = no match + +request_failed = Request failed. Please contact your system administrator. + +# +# Image upload pages +# +upload_page_title = Upload image +upload_page_title_with_name = Upload image for {0} +upload_heading = Photo Upload + +replace_page_title = Replace image +replace_page_title_with_name = Replace image for {0} + +crop_page_title = Crop image +crop_page_title_with_name = Crop image for {0} + +current_photo = Current Photo +upload_photo = Upload a photo +replace_photo = Replace Photo +photo_types = (JPEG, GIF or PNG) +maximum_file_size = Maximum file size: {0} megabytes +minimum_image_dimensions = Minimum image dimensions: {0} x {1} pixels + +cropping_caption = Your profile photo will look like the image below. +cropping_note = To make adjustments, you can drag around and resize the photo to the right. \ + When you are happy with your photo click the "Save Photo" button. + +alt_thumbnail_photo = Individual photo +alt_image_to_crop = Image to be cropped +alt_preview_crop = Preview of photo cropped + +delete_link = Delete photo +submit_upload = Upload photo +submit_save = Save photo + +confirm_delete = Are you sure you want to delete this photo? + +imageUpload.errorNoURI = No entity URI was provided +imageUpload.errorUnrecognizedURI = This URI is not recognized as belonging to anyone: ''{0}'' +imageUpload.errorNoImageForCropping = There is no image file to be cropped. +imageUpload.errorImageTooSmall = The uploaded image should be at least {0} pixels high and {1} pixels wide. +imageUpload.errorUnknown = Sorry, we were unable to process the photo you provided. Please try another photo. +imageUpload.errorFileTooBig = Please upload an image smaller than {0} megabytes. +imageUpload.errorUnrecognizedFileType = ''{0}'' is not a recognized image file type. Please upload JPEG, GIF, or PNG files only. +imageUpload.errorNoPhotoSelected = Please browse and select a photo. +imageUpload.errorBadMultipartRequest = Failed to parse the multi-part request for uploading an image. +imageUpload.errorFormFieldMissing = The form did not contain a ''{0}'' field." + +# +# User Accounts pages +# +account_management = Account Management +user_accounts_link = User accounts +user_accounts_title = user accounts + +login_count = Login count +last_login = Last Login + +add_new_account = Add new account +edit_account = Edit account +external_auth_only = Externally Authenticated Only +reset_password = Reset password +reset_password_note = Note: Instructions for resetting the password will \ + be emailed to the address entered above. The password will not \ + be reset until the user follows the link provided in this email. +new_password = New password +confirm_password = Confirm new password +minimum_password_length = Minimum of {0} characters in length. +leave_password_unchanged = Leaving this blank means that the password will not be changed. +confirm_initial_password = Confirm initial password + +new_account_1 = A new account for +new_account_2 = was successfully created. +new_account_title = new account +new_account_notification = A notification email has been sent to {0} \ + with instructions for activating the account and creating a password. +updated_account_1 = The account for +updated_account_2 = has been updated. +updated_account_title = updated account +updated_account_notification = A confirmation email has been sent to {0} \ + with instructions for resetting a password. \ + The password will not be reset until the user follows the link provided in this email. +deleted_accounts = Deleted {0} {0, choice, 0#accounts |1#account |1 + + {1} + + +

+ {2} {3} +

+ +

+ Congratulations! +

+ +

+ We have created your new account on {0}, associated with {4}. +

+ +

+ If you did not request this new account you can safely ignore this email. + This request will expire if not acted upon for 30 days. +

+ +

+ Click the link below to create your password for your new account using our secure server. +

+ +

+ {5} +

+ +

+ If the link above doesn't work, you can copy and paste the link directly into your browser's address bar. +

+ +

+ Thanks! +

+ + diff --git a/webapp/web/i18n/files/accountCreatedEmail.txt b/webapp/web/i18n/files/accountCreatedEmail.txt new file mode 100644 index 000000000..4dcd900c8 --- /dev/null +++ b/webapp/web/i18n/files/accountCreatedEmail.txt @@ -0,0 +1,17 @@ +{2} {3} + +Congratulations! + +We have created your new account on {0}, +associated with {4}. + +If you did not request this new account you can safely ignore this email. +This request will expire if not acted upon for 30 days. + +Paste the link below into your browser's address bar to create your password +for your new account using our secure server. + +{5} + +Thanks! + diff --git a/webapp/web/i18n/files/accountCreatedExternalOnlyEmail.html b/webapp/web/i18n/files/accountCreatedExternalOnlyEmail.html new file mode 100644 index 000000000..164bf87ae --- /dev/null +++ b/webapp/web/i18n/files/accountCreatedExternalOnlyEmail.html @@ -0,0 +1,22 @@ + + + ${1} + + +

+ ${2} ${3} +

+ +

+ Congratulations! +

+ +

+ We have created your new VIVO account associated with ${4}. +

+ +

+ Thanks! +

+ + diff --git a/webapp/web/i18n/files/accountCreatedExternalOnlyEmail.txt b/webapp/web/i18n/files/accountCreatedExternalOnlyEmail.txt new file mode 100644 index 000000000..c55cb3f9a --- /dev/null +++ b/webapp/web/i18n/files/accountCreatedExternalOnlyEmail.txt @@ -0,0 +1,9 @@ +${2} ${3} + +Congratulations! + +We have created your new VIVO account associated with +${4}. + +Thanks! + diff --git a/webapp/web/i18n/files/accountEmailChanged.html b/webapp/web/i18n/files/accountEmailChanged.html new file mode 100644 index 000000000..5a2e51e50 --- /dev/null +++ b/webapp/web/i18n/files/accountEmailChanged.html @@ -0,0 +1,19 @@ + + + {1} + + +

+ Hi, {2} ${3} +

+ +

+ You recently changed the email address associated with + ${2} ${3} +

+ +

+ Thank you. +

+ + diff --git a/webapp/web/i18n/files/accountEmailChanged.txt b/webapp/web/i18n/files/accountEmailChanged.txt new file mode 100644 index 000000000..5f560dca1 --- /dev/null +++ b/webapp/web/i18n/files/accountEmailChanged.txt @@ -0,0 +1,6 @@ +Hi, {2} {3} + +You recently changed the email address associated with +{2} {3} + +Thank you. diff --git a/webapp/web/i18n/files/accountFirstTimeExternal.html b/webapp/web/i18n/files/accountFirstTimeExternal.html new file mode 100644 index 000000000..61dca7f3c --- /dev/null +++ b/webapp/web/i18n/files/accountFirstTimeExternal.html @@ -0,0 +1,22 @@ + + + {1} + + +

+ {2} {3} +

+ +

+ Congratulations! +

+ +

+ We have created your new {0} account associated with {4}. +

+ +

+ Thanks! +

+ + diff --git a/webapp/web/i18n/files/accountFirstTimeExternal.txt b/webapp/web/i18n/files/accountFirstTimeExternal.txt new file mode 100644 index 000000000..1cb60552b --- /dev/null +++ b/webapp/web/i18n/files/accountFirstTimeExternal.txt @@ -0,0 +1,8 @@ +{2} {3} + +Congratulations! + +We have created your new {0} account associated with +{4} + +Thanks! diff --git a/webapp/web/i18n/files/passwordCreatedEmail.html b/webapp/web/i18n/files/passwordCreatedEmail.html new file mode 100644 index 000000000..15cf8bb0d --- /dev/null +++ b/webapp/web/i18n/files/passwordCreatedEmail.html @@ -0,0 +1,22 @@ + + + {1} + + +

+ {2} {3} +

+ +

+ Password successfully created. +

+ +

+ Your new password associated with {4} has been created. +

+ +

+ Thank you. +

+ + diff --git a/webapp/web/i18n/files/passwordCreatedEmail.txt b/webapp/web/i18n/files/passwordCreatedEmail.txt new file mode 100644 index 000000000..dbd9e9da0 --- /dev/null +++ b/webapp/web/i18n/files/passwordCreatedEmail.txt @@ -0,0 +1,8 @@ +{2} {3} + +Password successfully created. + +Your new password associated with {4} +has been created. + +Thank you. diff --git a/webapp/web/i18n/files/passwordRequestPending.html b/webapp/web/i18n/files/passwordRequestPending.html new file mode 100644 index 000000000..bd20cb392 --- /dev/null +++ b/webapp/web/i18n/files/passwordRequestPending.html @@ -0,0 +1,34 @@ + + + {1} + + +

+ Dear {2} {3}: +

+ +

+ We have received a request to reset the password for your {0} account ({4}). +

+ +

+ Please follow the instructions below to proceed with your password reset. +

+ +

+ If you did not request this new account you can safely ignore this email. + This request will expire if not acted upon within 30 days. +

+ +

+ Click on the link below or paste it into your browser's address bar to reset your password + using our secure server. +

+ +

+ {5} +

+ +

Thank you!

+ + diff --git a/webapp/web/i18n/files/passwordRequestPending.txt b/webapp/web/i18n/files/passwordRequestPending.txt new file mode 100644 index 000000000..e8c92b5f2 --- /dev/null +++ b/webapp/web/i18n/files/passwordRequestPending.txt @@ -0,0 +1,16 @@ +Dear {2} {3}: + +We have received a request to reset the password for your {0} account +({4}). + +Please follow the instructions below to proceed with your password reset. + +If you did not request this new account you can safely ignore this email. +This request will expire if not acted upon within 30 days. + +Paste the link below into your browser's address bar to reset your password +using our secure server. + +{5} + +Thank you! diff --git a/webapp/web/i18n/files/passwordResetComplete.html b/webapp/web/i18n/files/passwordResetComplete.html new file mode 100644 index 000000000..bfa756f15 --- /dev/null +++ b/webapp/web/i18n/files/passwordResetComplete.html @@ -0,0 +1,22 @@ + + + {1} + + +

+ {2} {3} +

+ +

+ Password successfully changed. +

+ +

+ Your new password associated with {4} has been changed. +

+ +

+ Thank you. +

+ + diff --git a/webapp/web/i18n/files/passwordResetComplete.txt b/webapp/web/i18n/files/passwordResetComplete.txt new file mode 100644 index 000000000..99503085c --- /dev/null +++ b/webapp/web/i18n/files/passwordResetComplete.txt @@ -0,0 +1,8 @@ +{2} {3} + +Password successfully changed. + +Your new password associated with {4} +has been changed. + +Thank you. diff --git a/webapp/web/i18n/files/passwordResetPending.html b/webapp/web/i18n/files/passwordResetPending.html new file mode 100644 index 000000000..bd20cb392 --- /dev/null +++ b/webapp/web/i18n/files/passwordResetPending.html @@ -0,0 +1,34 @@ + + + {1} + + +

+ Dear {2} {3}: +

+ +

+ We have received a request to reset the password for your {0} account ({4}). +

+ +

+ Please follow the instructions below to proceed with your password reset. +

+ +

+ If you did not request this new account you can safely ignore this email. + This request will expire if not acted upon within 30 days. +

+ +

+ Click on the link below or paste it into your browser's address bar to reset your password + using our secure server. +

+ +

+ {5} +

+ +

Thank you!

+ + diff --git a/webapp/web/i18n/files/passwordResetPending.txt b/webapp/web/i18n/files/passwordResetPending.txt new file mode 100644 index 000000000..5d34952f3 --- /dev/null +++ b/webapp/web/i18n/files/passwordResetPending.txt @@ -0,0 +1,16 @@ +Dear {2} {3}: + +We have received a request to reset the password for your {0} account +({4}). + +Please follow the instructions below to proceed with your password reset. + +If you did not request this new account you can safely ignore this email. +This request will expire if not acted upon within 30 days. + +Paste the link below into your browser's address bar to reset your password +using our secure server. + +{5} + +Thank you! \ No newline at end of file diff --git a/webapp/web/images/download-icon.png b/webapp/web/images/download-icon.png new file mode 100644 index 000000000..dd3213204 Binary files /dev/null and b/webapp/web/images/download-icon.png differ diff --git a/webapp/web/images/individual/individual--foaf-person.png b/webapp/web/images/individual/individual--foaf-person.png deleted file mode 100644 index 2cfbfbc37..000000000 Binary files a/webapp/web/images/individual/individual--foaf-person.png and /dev/null differ diff --git a/webapp/web/images/mail.gif b/webapp/web/images/mail.gif deleted file mode 100644 index 7611727ab..000000000 Binary files a/webapp/web/images/mail.gif and /dev/null differ diff --git a/webapp/web/images/people/erb_hollis_thumb.gif b/webapp/web/images/people/erb_hollis_thumb.gif deleted file mode 100644 index 0d6fb5b08..000000000 Binary files a/webapp/web/images/people/erb_hollis_thumb.gif and /dev/null differ diff --git a/webapp/web/images/share-uri-icon.png b/webapp/web/images/share-uri-icon.png new file mode 100644 index 000000000..a79edd97b Binary files /dev/null and b/webapp/web/images/share-uri-icon.png differ diff --git a/webapp/web/jenaIngest/executeWorkflow.jsp b/webapp/web/jenaIngest/executeWorkflow.jsp index 46aeeecc2..8f5751f83 100644 --- a/webapp/web/jenaIngest/executeWorkflow.jsp +++ b/webapp/web/jenaIngest/executeWorkflow.jsp @@ -3,6 +3,7 @@ <%@ page import="com.hp.hpl.jena.ontology.Individual" %> <%@ page import="com.hp.hpl.jena.ontology.OntModel" %> <%@ page import="com.hp.hpl.jena.rdf.model.ModelMaker" %> +<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess"%> <%@ page import="com.hp.hpl.jena.shared.Lock" %> <%@ page import="java.util.Iterator" %> <%@ page import="java.util.List" %> @@ -23,7 +24,7 @@ <% - OntModel jenaOntModel = (OntModel) getServletContext().getAttribute("jenaOntModel"); + OntModel jenaOntModel = ModelAccess.on(getServletContext()).getJenaOntModel(); jenaOntModel.enterCriticalSection(Lock.READ); try { List savedQueries = (List) request.getAttribute("savedQueries"); diff --git a/webapp/web/jenaIngest/workflowStep.jsp b/webapp/web/jenaIngest/workflowStep.jsp index 9ea99e7ae..360093eb2 100644 --- a/webapp/web/jenaIngest/workflowStep.jsp +++ b/webapp/web/jenaIngest/workflowStep.jsp @@ -3,6 +3,7 @@ <%@ page import="com.hp.hpl.jena.ontology.Individual" %> <%@ page import="com.hp.hpl.jena.ontology.OntModel" %> <%@ page import="com.hp.hpl.jena.rdf.model.ModelMaker" %> +<%@ page import="edu.cornell.mannlib.vitro.webapp.dao.ModelAccess"%> <%@ page import="com.hp.hpl.jena.shared.Lock" %> <%@ page import="java.util.Iterator" %> <%@ page import="java.util.List" %> @@ -25,7 +26,7 @@
view profile in RDF format
close' + text: '
' + i18nStringsUriRdf.shareProfileUri + '
' + i18nStringsUriRdf.viewRDFProfile + '
' + i18nStringsUriRdf.closeString + '' }, position: { corner: { @@ -40,7 +43,7 @@ $(document).ready(function(){ { content: { prerender: true, // We need this for the .click() event listener on 'a.close' - text: '
share the URI for this profile
view profile in RDF format
close' + text: '
' + i18nStringsUriRdf.shareProfileUri + '
' + i18nStringsUriRdf.viewRDFProfile + '
' + i18nStringsUriRdf.closeString + '' }, position: { corner: { @@ -72,7 +75,7 @@ $(document).ready(function(){ { content: { prerender: true, // We need this for the .click() event listener on 'a.close' - text: '
share the URI for this profile
view profile in RDF format
close' + text: '
' + i18nStringsUriRdf.shareProfileUri + '
' + i18nStringsUriRdf.viewRDFProfile + '
' + i18nStringsUriRdf.closeString + '' }, position: { corner: { diff --git a/webapp/web/js/individual/manageLabelsForIndividual.js b/webapp/web/js/individual/manageLabelsForIndividual.js index c51597d91..cd91e9033 100644 --- a/webapp/web/js/individual/manageLabelsForIndividual.js +++ b/webapp/web/js/individual/manageLabelsForIndividual.js @@ -16,6 +16,7 @@ var manageLabels = { // Get the custom form data from the page $.extend(this, customFormData); + $.extend(this, i18nStrings); }, // Initial page setup. Called only at page load. @@ -37,6 +38,11 @@ var manageLabels = { $('input#submit').click( function() { manageLabels.processLabel(manageLabels.selectedRadio); + $('span.or').hide(); + $('a.cancel').hide(); + $('span#indicator').removeClass('hidden'); + $('input.submit').addClass('disabledSubmit'); + $('input.submit').attr('disabled', 'disabled'); }); }, @@ -70,11 +76,19 @@ var manageLabels = { complete: function(request, status) { if (status == 'success') { + $('span.or').show(); + $('a.cancel').show(); + $('span#indicator').addClass('hidden'); window.location = $('a.cancel').attr('href'); } else { - alert('Error processing request: the unchecked labels could not be deleted.'); + alert(manageLabels.errorProcessingLabels); selectedRadio.removeAttr('checked'); + $('span.or').show(); + $('a.cancel').show(); + $('span#indicator').addClass('hidden'); + $('input.submit').removeClass('disabledSubmit'); + $('input.submit').attr('disabled', ''); } } }); diff --git a/webapp/web/js/individual/menuManagement.js b/webapp/web/js/individual/menuManagement.js index 5572ef7ce..bef48e786 100644 --- a/webapp/web/js/individual/menuManagement.js +++ b/webapp/web/js/individual/menuManagement.js @@ -13,6 +13,7 @@ var menuManagement = { // Add variables from menupage template mergeFromTemplate: function() { $.extend(this, menuManagementData); + $.extend(this, i18nStrings); }, // Create references to frequently used elements for convenience @@ -30,7 +31,7 @@ var menuManagement = { this.menuItemsList.addClass('dragNdrop'); - menuItems.attr('title', 'Drag and drop to reorder menu items'); + menuItems.attr('title', menuManagement.dragDropMenus); @@ -95,7 +96,7 @@ var menuManagement = { ui.item.appendTo(menuItems); } - alert('Reordering of menu items failed.'); + alert(menuManagement.reorderingFailed); } } }); diff --git a/webapp/web/js/individual/propertyGroupControls.js b/webapp/web/js/individual/propertyGroupControls.js index 6da441d5f..d8d0a51d2 100644 --- a/webapp/web/js/individual/propertyGroupControls.js +++ b/webapp/web/js/individual/propertyGroupControls.js @@ -5,7 +5,7 @@ $(document).ready(function(){ $.extend(this, individualLocalName); adjustFontSize(); padSectionBottoms(); - retrieveLocalStorage(); + checkLocationHash(); // ensures that shorter property group sections don't cause the page to "jump around" // when the tabs are clicked @@ -33,7 +33,7 @@ $(document).ready(function(){ $propertyGroupLi.removeClass("nonSelectedGroupTab clickable"); $propertyGroupLi.addClass("selectedGroupTab clickable"); } - if ( $propertyGroupLi.text() == "View All" ) { + if ( $propertyGroupLi.attr("groupname") == "viewAll" ) { processViewAllTab(); } else { @@ -59,6 +59,61 @@ $(document).ready(function(){ }); } + // If users click a marker on the home page map, they are taken to the profile + // page of the corresponding country. The url contains the word "Research" in + // the location hash. Use this to select the Research tab, which displays the + // researchers who have this countru as a geographic focus. + function checkLocationHash() { + if ( location.hash ) { + // remove the trailing white space + location.hash = location.hash.replace(/\s+/g, ''); + if ( location.hash.indexOf("map") >= 0 ) { + // get the name of the group that contains the geographicFocusOf property. + var tabName = $('h3#geographicFocusOf').parent('article').parent('div').attr("id"); + tabName = tabName.replace("Group",""); + tabNameCapped = tabName.charAt(0).toUpperCase() + tabName.slice(1); + // if the name of the first tab section = tabName we don't have to do anything; + // otherwise, select the correct tab and deselect the first one + var $firstTab = $('li.clickable').first(); + if ( $firstTab.text() != tabNameCapped ) { + // select the correct tab + $('li[groupName="' + tabName + '"]').removeClass("nonSelectedGroupTab clickable"); + $('li[groupName="' + tabName + '"]').addClass("selectedGroupTab clickable"); + // deselect the first tab + $firstTab.removeClass("selectedGroupTab clickable"); + $firstTab.addClass("nonSelectedGroupTab clickable"); + $('section.property-group:visible').hide(); + // show the selected tab section + $('section#' + tabName).show(); + } + // if there is a more link, "click" more to show all the researchers + // we need the timeout delay so that the more link can get rendered + setTimeout(geoFocusExpand,250); + } + else { + retrieveLocalStorage(); + } + } + else { + retrieveLocalStorage(); + } + } + + function geoFocusExpand() { + // if the ontology is set to collate by subclass, $list.length will be > 0 + // this ensures both possibilities are covered + var $list = $('ul#geographicFocusOfList').find('ul'); + if ( $list.length > 0 ) + { + var $more = $list.find('a.more-less'); + $more.click(); + } + else { + var $more = $('ul#geographicFocusOfList').find('a.more-less'); + $more.click(); + } + } + // Next two functions -- keep track of which property group tab was selected, // so if we return from a custom form or a related individual, even via the back button, // the same property group will be selected as before. @@ -96,15 +151,16 @@ $(document).ready(function(){ } function retrieveLocalStorage() { + var localName = this.individualLocalName; var selectedTab = amplify.store(individualLocalName); if ( selectedTab != undefined ) { var groupName = selectedTab[0]; - // unlikely, but it's possible a tab that was previously selected and stored won't be displayed - // because the object properties would have been deleted (in non-edit mode). So ensure that the tab in local - // storage has been rendered on the page. + // unlikely, but it's possible a tab that was previously selected and stored won't be + // displayed because the object properties would have been deleted (in non-edit mode). + // So ensure that the tab in local storage has been rendered on the page. if ( $("ul.propertyTabsList li[groupName='" + groupName + "']").length ) { // if the selected tab is the default first one, don't do anything if ( $('li.clickable').first().attr("groupName") != groupName ) { @@ -136,7 +192,7 @@ $(document).ready(function(){ width += $(this).outerWidth(); }); if ( width < 922 ) { - var diff = 926-width; + var diff = 927-width; $('ul.propertyTabsList li:last-child').css('width', diff + 'px'); } else { diff --git a/webapp/web/js/login/loginUtils.js b/webapp/web/js/login/loginUtils.js index 06df844a9..e11ca5b4d 100644 --- a/webapp/web/js/login/loginUtils.js +++ b/webapp/web/js/login/loginUtils.js @@ -10,5 +10,10 @@ $(document).ready(function(){ // fade in error alerts $('section#error-alert').css('display', 'none').fadeIn(1500); - + + // toggle vivo account authentication form + $('h3.internal-auth').click(function() { + $('.vivoAccount').toggle(); + }); + }); \ No newline at end of file diff --git a/webapp/web/js/menupage/browseByVClass.js b/webapp/web/js/menupage/browseByVClass.js index e22ef9c7d..ced76ada9 100644 --- a/webapp/web/js/menupage/browseByVClass.js +++ b/webapp/web/js/menupage/browseByVClass.js @@ -12,6 +12,7 @@ var browseByVClass = { // Add variables from menupage template mergeFromTemplate: function() { $.extend(this, menupageData); + $.extend(this, i18nStrings); }, // Create references to frequently used elements for convenience @@ -165,10 +166,12 @@ var browseByVClass = { // Print out the pagination nav if called pagination: function(pages, page) { var pagination = '" }); //Hide inner div var $innerDiv = $newDivContainer.children('div#innerContainer' + counter); @@ -638,7 +640,7 @@ var pageManagementUtils = { var selectedClassesList = pageManagementUtils.classesForClassGroup.children('ul#selectedClasses'); selectedClassesList.empty(); - selectedClassesList.append('
  • '); + selectedClassesList.append('
  • '); $.each(results.classes, function(i, item) { var thisClass = results.classes[i]; @@ -740,11 +742,11 @@ var pageManagementUtils = { return jsonObject; } else { //ERROR handling - alert("An error has occurred and the map of processors for this content is missing. Please contact the administrator"); + alert(pageManagementUtils.mapProcessorError); return null; } } - alert("An error has occurred and the code for processing this content is missing a component. Please contact the administrator."); + alert(pageManagementUtils.codeProcessingError); //Error handling here return null; }, @@ -785,21 +787,21 @@ var pageManagementUtils = { // Check menu name if ($('input[type=text][name=pageName]').val() == "") { - validationError += "You must supply a name
    "; + validationError += pageManagementUtils.supplyName + "
    "; } // Check pretty url if ($('input[type=text][name=prettyUrl]').val() == "") { - validationError += "You must supply a pretty URL
    "; + validationError += pageManagementUtils.supplyPrettyUrl + "
    "; } if ($('input[type=text][name=prettyUrl]').val().charAt(0) != "/") { - validationError += "The pretty URL must begin with a leading forward slash
    "; + validationError += pageManagementUtils.startUrlWithSlash + "
    "; } // Check custom template and self contained template var selectedTemplateValue = $('input:radio[name=selectedTemplate]:checked').val(); if (selectedTemplateValue == "custom" || selectedTemplateValue == "selfContained") { if ($('input[name=customTemplate]').val() == "") { - validationError += "You must supply a template
    "; + validationError += pageManagementUtils.supplyTemplate + "
    "; } } @@ -813,7 +815,7 @@ var pageManagementUtils = { var validationErrorMsg = ""; //If there ARE not contents selected, then error message should indicate user needs to add them if(pageContentSections.length == 0) { - validationErrorMsg = "You must select content to be included on the page
    "; + validationErrorMsg = pageManagementUtils.selectContentType + "
    "; } else { //For each, based on type, validate if a validation function exists $.each(pageContentSections, function(i) { diff --git a/webapp/web/js/menupage/processClassGroupDataGetterContent.js b/webapp/web/js/menupage/processClassGroupDataGetterContent.js index e413a8b70..938064cd5 100644 --- a/webapp/web/js/menupage/processClassGroupDataGetterContent.js +++ b/webapp/web/js/menupage/processClassGroupDataGetterContent.js @@ -1,5 +1,6 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ +$.extend(this, i18nStringsBrowseGroups); //Process sparql data getter and provide a json object with the necessary information //Depending on what is included here, a different type of data getter might be used var processClassGroupDataGetterContent = { @@ -34,7 +35,7 @@ var processClassGroupDataGetterContent = { }, //For the label of the content section for editing, need to add additional value retrieveContentLabel:function() { - return "Browse Class Group"; + return i18nStringsBrowseGroups.browseClassGroup; }, retrieveAdditionalLabelText:function(existingContentObject) { var label = ""; @@ -61,7 +62,7 @@ var processClassGroupDataGetterContent = { selectedClassesList.empty(); var newId = "allSelected" + contentNumber; - selectedClassesList.append('
  • '); + selectedClassesList.append('
  • '); $.each(results.classes, function(i, item) { var thisClass = results.classes[i]; @@ -134,14 +135,14 @@ var processClassGroupDataGetterContent = { validateFormSubmission: function(pageContentSection, pageContentSectionLabel) { var validationError = ""; if (pageContentSection.find('select[name="selectClassGroup"]').val() =='-1') { - validationError += pageContentSectionLabel + ": You must supply a class group
    "; + validationError += pageContentSectionLabel + ": " + i18nStringsBrowseGroups.supplyClassGroup + "
    "; } else { //class group has been selected, make sure there is at least one class selected var allSelected = pageContentSection.find('input[name="allSelected"]:checked').length; var noClassesSelected = pageContentSection.find('input[name="classInClassGroup"]:checked').length; if (allSelected == 0 && noClassesSelected == 0) { //at least one class should be selected - validationError += pageContentSectionLabel + ":You must select the classes to display
    "; + validationError += pageContentSectionLabel + ": " + i18nStringsBrowseGroups.selectClasses + "
    "; } } return validationError; diff --git a/webapp/web/js/menupage/processFixedHTMLDataGetterContent.js b/webapp/web/js/menupage/processFixedHTMLDataGetterContent.js index 00395c7dd..25fc5d1d4 100644 --- a/webapp/web/js/menupage/processFixedHTMLDataGetterContent.js +++ b/webapp/web/js/menupage/processFixedHTMLDataGetterContent.js @@ -1,5 +1,6 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ +$.extend(this, i18nStringsFixedHtml); //Process sparql data getter and provide a json object with the necessary information var processFixedHTMLDataGetterContent = { dataGetterClass:null, @@ -30,7 +31,7 @@ var processFixedHTMLDataGetterContent = { }, //For the label of the content section for editing, need to add additional value retrieveContentLabel:function() { - return "Fixed HTML"; + return i18nStringsFixedHtml.fixedHtml; }, //For the label of the content section for editing, need to add additional value retrieveAdditionalLabelText:function(existingContentObject) { @@ -43,17 +44,17 @@ var processFixedHTMLDataGetterContent = { //Check that query and saveToVar have been input var variableValue = pageContentSection.find("input[name='saveToVar']").val(); if(variableValue == "") { - validationError += pageContentSectionLabel + ": You must supply a variable to save HTML content.
    "; + validationError += pageContentSectionLabel + ": " + i18nStringsFixedHtml.supplyVariableName + "
    "; } if(processFixedHTMLDataGetterContent.stringHasSingleQuote(variableValue)) { - validationError += pageContentSectionLabel + ": The variable name should not have an apostrophe .
    "; + validationError += pageContentSectionLabel + ": " + i18nStringsFixedHtml.noApostrophes + "
    "; } if(processFixedHTMLDataGetterContent.stringHasDoubleQuote(variableValue)) { - validationError += pageContentSectionLabel + ": The variable name should not have a double quote .
    "; + validationError += pageContentSectionLabel + ": " + i18nStringsFixedHtml.noDoubleQuotes + "
    "; } var htmlValue = pageContentSection.find("textarea[name='htmlValue']").val(); if(htmlValue == "") { - validationError += pageContentSectionLabel + ": You must supply some HTML or text.
    "; + validationError += pageContentSectionLabel + ": " + i18nStringsFixedHtml.supplyHtml + "
    "; } return validationError; }, diff --git a/webapp/web/js/menupage/processSparqlDataGetterContent.js b/webapp/web/js/menupage/processSparqlDataGetterContent.js index ee54c1bb6..f371de215 100644 --- a/webapp/web/js/menupage/processSparqlDataGetterContent.js +++ b/webapp/web/js/menupage/processSparqlDataGetterContent.js @@ -1,5 +1,7 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ +$.extend(this, i18nStringsSparqlQuery); + //Process sparql data getter and provide a json object with the necessary information var processSparqlDataGetterContent = { dataGetterClass:null, @@ -35,7 +37,7 @@ var processSparqlDataGetterContent = { }, //For the label of the content section for editing, need to add additional value retrieveContentLabel:function() { - return "SPARQL Query Results"; + return i18nStringsSparqlQuery.sparqlResults; }, //For the label of the content section for editing, need to add additional value retrieveAdditionalLabelText:function(existingContentObject) { @@ -48,13 +50,13 @@ var processSparqlDataGetterContent = { //Check that query and saveToVar have been input var variableValue = pageContentSection.find("input[name='saveToVar']").val(); if(variableValue == "") { - validationError += pageContentSectionLabel + ": You must supply a variable to save query results.
    " + validationError += pageContentSectionLabel + ": " + i18nStringsSparqlQuery.supplyQueryVariable + "
    " } if(processSparqlDataGetterContent.stringHasSingleQuote(variableValue)) { - validationError += pageContentSectionLabel + ": The variable name should not have an apostrophe .
    "; + validationError += pageContentSectionLabel + ": " + i18nStringsSparqlQuery.noApostrophes + "
    "; } if(processSparqlDataGetterContent.stringHasDoubleQuote(variableValue)) { - validationError += pageContentSectionLabel + ": The variable name should not have a double quote .
    "; + validationError += pageContentSectionLabel + ": " + i18nStringsSparqlQuery.noDoubleQuotes + "
    "; } //Check that query model does not have single or double quotes within it //Uncomment this/adapt this when we actually allow display the query model input @@ -71,7 +73,7 @@ var processSparqlDataGetterContent = { var queryValue = pageContentSection.find("textarea[name='query']").val(); if(queryValue == "") { - validationError += pageContentSectionLabel + ": You must supply a Sparql query.
    "; + validationError += pageContentSectionLabel + ": " + i18nStringsSparqlQuery.supplyQuery + "
    "; } return validationError; }, diff --git a/webapp/web/js/pageDeletion.js b/webapp/web/js/pageDeletion.js index feab7c3e4..49bff3a6b 100644 --- a/webapp/web/js/pageDeletion.js +++ b/webapp/web/js/pageDeletion.js @@ -1,5 +1,7 @@ /* $This file is distributed under the terms of the license in /doc/license.txt$ */ +$.extend(this, i18nStrings); + var pageDeletion = { // on initial page setup onLoad:function(){ @@ -17,7 +19,7 @@ var pageDeletion = { this.deleteLinks.click(function(event) { var href=$(this).attr("href"); var pageTitle = $(this).attr("pageTitle"); - var confirmResult = confirm("Are you sure you wish to delete this page: " + pageTitle + "?"); + var confirmResult = confirm( i18nStrings.confirmPageDeletion + " " + pageTitle + "?"); if(confirmResult) { //Continue with the link return true; diff --git a/webapp/web/js/searchDownload.js b/webapp/web/js/searchDownload.js new file mode 100644 index 000000000..1bcec1607 --- /dev/null +++ b/webapp/web/js/searchDownload.js @@ -0,0 +1,70 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +$(document).ready(function(){ + // This function creates and styles the "qTip" tooltip that displays the resource uri and the rdf link when the user clicks the uri/rdf icon. + + $('span#downloadResults').children('img#downloadIcon').each(function() + { + $(this).qtip( + { + content: { + prerender: true, // We need this for the .click() event listener on 'a.close' + text: '
    ' + +'

    ' + +'

    ' + +'
    ' + +'
    ' + +'
    Download the results from this search
    ' + +'
    download results in XML format
    ' + +'
    download results in CSV format
    ' + +'
    close
    ' + + }, + position: { + corner: { + target: 'bottomLeft', + tooltip: 'topLeft' + } + }, + show: { + when: {event: 'click'} + }, + hide: { + fixed: true, // Make it fixed so it can be hovered over and interacted with + when: { + target: $('a.close'), + event: 'click' + } + }, + style: { + padding: '1em', + width: 500, + backgroundColor: '#f1f2ee' + } + }); + + }); + + $( "#slider-vertical" ).slider({ + orientation: "vertical", + range: "min", + min: 10, + max: 1000, + value: 500, + slide: function( event, ui ) { + $( "#amount" ).val( ui.value ); + $('#csvDownload').attr("href", urlsBase + '/search?' + queryText +'&csv=1&hitsPerPage=' + ui.value); + $('#xmlDownload').attr("href", urlsBase + '/search?' + queryText +'&xml=1&hitsPerPage=' + ui.value); + } + }); + $( "#amount" ).val( $( "#slider-vertical" ).slider( "value" ) ); + + + // Prevent close link for URI qTip from requesting bogus '#' href + $('a.close').click(function() { + $('#downloadIcon').qtip("hide"); + return false; + }); + + +}); \ No newline at end of file diff --git a/webapp/web/js/siteAdmin/classHierarchyUtils.js b/webapp/web/js/siteAdmin/classHierarchyUtils.js index db9319f61..083224cb0 100644 --- a/webapp/web/js/siteAdmin/classHierarchyUtils.js +++ b/webapp/web/js/siteAdmin/classHierarchyUtils.js @@ -2,6 +2,7 @@ var classHierarchyUtils = { onLoad: function(urlBase,displayOption) { + $.extend(this, i18nStrings); this.imagePath = urlBase + "/images/"; this.displayOption = displayOption; this.initObjects(); @@ -58,15 +59,15 @@ if ( this.displayOption == "group" ) { this.expandAll.click(function() { - if ( classHierarchyUtils.expandAll.text() == "hide subclasses" ) { + if ( classHierarchyUtils.expandAll.text() == i18nStrings.hideSubclasses ) { $('td.subclassCell').parent('tr').hide(); $('table.innerDefinition').hide(); - classHierarchyUtils.expandAll.text("show subclasses"); + classHierarchyUtils.expandAll.text(i18nStrings.showSubclasses); } else { $('td.subclassCell').parent('tr').show(); $('table.innerDefinition').show(); - classHierarchyUtils.expandAll.text("hide subclasses"); + classHierarchyUtils.expandAll.text(i18nStrings.hideSubclasses); } }); } @@ -98,10 +99,10 @@ } if ( this.data.classGroup.length > 0 ) { - classHierarchyUtils.classHtml += "Class Group:" + this.data.classGroup + ""; + classHierarchyUtils.classHtml += "" + i18nStrings.classGroup + ":" + this.data.classGroup + ""; } - classHierarchyUtils.classHtml += "Ontology:" + this.data.ontology + ""; + classHierarchyUtils.classHtml += "" + i18nStrings.ontologyString + ":" + this.data.ontology + ""; if ( descendants.length > 1 ) { @@ -129,7 +130,7 @@ var ctr = 0 $.each(node.children, function() { if ( ctr == 0 ) { - childDetails += "Subclasses:"; + childDetails += "" + i18nStrings.subclassesString + ":"; ctr = ctr + 1; } else { @@ -156,10 +157,10 @@ } if ( this.data.classGroup.length > 0 ) { - childDetails += "Class Group:" + this.data.classGroup + ""; + childDetails += "" + i18nStrings.classGroup + ":" + this.data.classGroup + ""; } - childDetails += "Ontology:" + this.data.ontology + ""; + childDetails += "" + i18nStrings.ontologyString + ":" + this.data.ontology + ""; if ( this.children ) { var grandChildren = classHierarchyUtils.getTheChildren(this); @@ -213,15 +214,15 @@ wireExpandLink: function() { this.expandAll.click(function() { - if ( classHierarchyUtils.expandAll.text() == "expand all" ) { - classHierarchyUtils.expandAll.text("collapse all"); + if ( classHierarchyUtils.expandAll.text() == i18nStrings.expandAll ) { + classHierarchyUtils.expandAll.text(i18nStrings.collapseAll); $('span.headerSpanPlus').addClass("headerSpanMinus"); $('table.classHierarchy').find('span.subclassExpandPlus').addClass("subclassExpandMinus"); $('table.classHierarchy').find('table.subclassTable').show(); $('section#container').find('span.headerSpanPlus').attr('view','more'); } else { - classHierarchyUtils.expandAll.text("expand all"); + classHierarchyUtils.expandAll.text(i18nStrings.expandAll); $('span.headerSpanPlus').removeClass("headerSpanMinus"); $('table.classHierarchy').find('span.subclassExpandPlus').removeClass("subclassExpandMinus"); $('table.classHierarchy').find('table.subclassTable').hide(); @@ -245,10 +246,10 @@ } if ( this.data.classGroup.length > 0 ) { - classHierarchyUtils.classHtml += "Class Group:" + this.data.classGroup + ""; + classHierarchyUtils.classHtml += "" + i18nStrings.classGroup + ":" + this.data.classGroup + ""; } - classHierarchyUtils.classHtml += "Ontology:" + this.data.ontology + ""; + classHierarchyUtils.classHtml += "" + i18nStrings.ontologyString + ":" + this.data.ontology + ""; classHierarchyUtils.classHtml += ""; @@ -271,7 +272,7 @@ var ctr = 0; $.each(this.children, function() { if ( ctr == 0 ) { - descendants += "Classes:"; + descendants += "" + i18nStrings.classesString + ":"; ctr = ctr + 1; } else { @@ -289,7 +290,7 @@ + classHierarchyUtils.classCounter + "'>" ; if ( this.data.displayRank.length > 0 ) { - classHierarchyUtils.classHtml += "Display Rank:" + this.data.displayRank + "" + classHierarchyUtils.classHtml += "" + i18nStrings.displayRank + ":" + this.data.displayRank + "" } classHierarchyUtils.classHtml += descendants; diff --git a/webapp/web/js/siteAdmin/objectPropertyHierarchyUtils.js b/webapp/web/js/siteAdmin/objectPropertyHierarchyUtils.js index 4e5eb28ce..e9ab0a1d5 100644 --- a/webapp/web/js/siteAdmin/objectPropertyHierarchyUtils.js +++ b/webapp/web/js/siteAdmin/objectPropertyHierarchyUtils.js @@ -2,6 +2,7 @@ var objectPropHierarchyUtils = { onLoad: function(urlBase,displayOption,type) { + $.extend(this, i18nStrings); this.imagePath = urlBase + "/images/"; this.propType = type; this.initObjects(); @@ -89,13 +90,13 @@ if ( this.propType == "group" ) { this.expandAll.click(function() { - if ( objectPropHierarchyUtils.expandAll.text() == "hide properties" ) { + if ( objectPropHierarchyUtils.expandAll.text() == i18nStrings.hideProperties ) { $('td.subclassCell').parent('tr').hide(); - objectPropHierarchyUtils.expandAll.text("show properties"); + objectPropHierarchyUtils.expandAll.text(i18nStrings.showProperties); } else { $('td.subclassCell').parent('tr').show(); - objectPropHierarchyUtils.expandAll.text("hide properties"); + objectPropHierarchyUtils.expandAll.text(i18nStrings.hideProperties); } }); } @@ -138,16 +139,16 @@ objectPropHierarchyUtils.classHtml += "
    " + this.name + headerSpan + "
    " + "" ; - objectPropHierarchyUtils.classHtml += ""; - objectPropHierarchyUtils.classHtml += ""; - objectPropHierarchyUtils.classHtml += ""; if ( descendants.length > 1 ) { @@ -174,7 +175,7 @@ var ctr = 0 $.each(node.children, function() { if ( ctr == 0 ) { - childDetails += ""; + childDetails += ""; ctr = ctr + 1; } else { @@ -182,10 +183,10 @@ } if ( this.children.length == 1 ) { - subclassString += " (1 subproperty)"; + subclassString += " (1 " + i18nStrings.subProperty + ")"; } else if ( this.children.length > 1 ) { - subclassString += " (" + this.children.length + " subproperties)"; + subclassString += " (" + this.children.length + " " + i18nStrings.subProperties + ")"; } childDetails += ""; - childDetails += ""; - childDetails += ""; if ( this.children ) { @@ -263,15 +264,15 @@ wireExpandLink: function() { this.expandAll.click(function() { - if ( objectPropHierarchyUtils.expandAll.text() == "expand all" ) { - objectPropHierarchyUtils.expandAll.text("collapse all"); + if ( objectPropHierarchyUtils.expandAll.text() == i18nStrings.expandAll ) { + objectPropHierarchyUtils.expandAll.text(i18nStrings.collapseAll); $('span.headerSpanPlus').addClass("headerSpanMinus"); $('table.classHierarchy').find('span.subclassExpandPlus').addClass("subclassExpandMinus"); $('table.classHierarchy').find('table.subclassTable').show(); $('section#container').find('span.headerSpanPlus').attr('view','more'); } else { - objectPropHierarchyUtils.expandAll.text("expand all"); + objectPropHierarchyUtils.expandAll.text(i18nStrings.expandAll); $('span.headerSpanPlus').removeClass("headerSpanMinus"); $('table.classHierarchy').find('span.subclassExpandPlus').removeClass("subclassExpandMinus"); $('table.classHierarchy').find('table.subclassTable').hide(); @@ -290,16 +291,16 @@ objectPropHierarchyUtils.classHtml += "
    " + this.name + "
    " + "
    Local Name:" + objectPropHierarchyUtils.classHtml += "
    " + i18nStrings.localNameString + ":" + (this.data.internalName.length > 0 ? this.data.internalName : "none" ) + "
    Group:" + objectPropHierarchyUtils.classHtml += "
    " + i18nStrings.groupString + ":" + (this.data.group.length > 0 ? this.data.group : "unspecified" ) + "
    Domain Class:" + objectPropHierarchyUtils.classHtml += "
    " + i18nStrings.domainClass + ":" + (this.data.domainVClass.length > 0 ? this.data.domainVClass : "none" ) + " "; - objectPropHierarchyUtils.classHtml += "Range Class:" + objectPropHierarchyUtils.classHtml += "" + i18nStrings.rangeClass + ":" + (this.data.rangeVClass.length > 0 ? this.data.rangeVClass : "none" ) + "
    Subproperties:
    " + i18nStrings.subProperties + ":Local Name:" + childDetails += "
    " + i18nStrings.localNameString + ":" + (this.data.internalName.length > 0 ? this.data.internalName : "none" ) + "
    Group:" + childDetails += "
    " + i18nStrings.groupString + ":" + (this.data.group.length > 0 ? this.data.group : "unspecified" ) + "
    Domain Class:" + childDetails += "
    " + i18nStrings.domainClass + ":" + (this.data.domainVClass.length > 0 ? this.data.domainVClass : "none" ) + " "; - childDetails += "Range Class:" + childDetails += "" + i18nStrings.rangeClass + ":" + (this.data.rangeVClass.length > 0 ? this.data.rangeVClass : "none" ) + "
    " ; - objectPropHierarchyUtils.classHtml += ""; - objectPropHierarchyUtils.classHtml += ""; - objectPropHierarchyUtils.classHtml += ""; objectPropHierarchyUtils.classHtml += "
    Local Name:" + objectPropHierarchyUtils.classHtml += "
    " + i18nStrings.localNameString + ":" + (this.data.internalName.length > 0 ? this.data.internalName : "none" ) + "
    Group:" + objectPropHierarchyUtils.classHtml += "
    " + i18nStrings.groupString + ":" + (this.data.group.length > 0 ? this.data.group : "unspecified" ) + "
    Domain Class:" + objectPropHierarchyUtils.classHtml += "
    " + i18nStrings.domainClass + ":" + (this.data.domainVClass.length > 0 ? this.data.domainVClass : "none" ) + " "; - objectPropHierarchyUtils.classHtml += "Range Class:" + objectPropHierarchyUtils.classHtml += "" + i18nStrings.rangeClass + ":" + (this.data.rangeVClass.length > 0 ? this.data.rangeVClass : "none" ) + "
    "; @@ -337,7 +338,7 @@ var ctr = 0; $.each(this.children, function() { if ( ctr == 0 ) { - descendants += "Properties:"; + descendants += "" + i18nStrings.propertiesString + ":"; ctr = ctr + 1; } else { @@ -355,7 +356,7 @@ + objectPropHierarchyUtils.classCounter + "'>" ; if ( this.data.displayRank.length > 0 ) { - objectPropHierarchyUtils.classHtml += "Display Rank:" + this.data.displayRank + "" + objectPropHierarchyUtils.classHtml += "" + i18nStrings.displayRank + ":" + this.data.displayRank + "" } objectPropHierarchyUtils.classHtml += descendants; diff --git a/webapp/web/js/vitroUtils.js b/webapp/web/js/vitroUtils.js old mode 100755 new mode 100644 index 15594baee..cb3925dc5 --- a/webapp/web/js/vitroUtils.js +++ b/webapp/web/js/vitroUtils.js @@ -5,8 +5,111 @@ $(document).ready(function(){ // Use jQuery() instead of $() alias, because dwr/util.js, loaded on back end editing // pages, overwrites $. // fade out welcome-message when user logs in + $.extend(this, i18nStrings); + jQuery('section#welcome-message').css('display', 'block').delay(2000).fadeOut(1500); // fade in flash-message when user logs out jQuery('section#flash-message').css('display', 'none').fadeIn(1500); -}); \ No newline at end of file + + ///////////////////////////// + // Home search fiter + // Toggle filter select list + var $searchFilterList = $('#filter-search-nav'); + var $isFilterOpen = false; + + console.log("Filter is open = " + $isFilterOpen); + + $('a.filter-search').click(function(e) { + e.preventDefault(); + + if (!$isFilterOpen) { + + console.log("Filter is closed = " + $isFilterOpen); + + //Change button filter state to selected + //$(this).css('background','url(../../themes/vivo-cornell/images/filteredSearchActive.gif) no-repeat right top'); + $(this).removeClass('filter-default'); + $(this).addClass('filter-active'); + + //Reveal filter select list + $searchFilterList.css('display','block'); + + $isFilterOpen = true; + + console.log("open"); + } else { + //Change button filter state to default + //$('a.filter-search').css('background','url(../../themes/vivo-cornell/images/filteredSearch.gif) no-repeat right top'); + $(this).removeClass('filter-active'); + $(this).addClass('filter-default'); + + //Hide filter select list + $searchFilterList.css('display','none'); + + $isFilterOpen = false; + + console.log("closed"); + } + }); + + // Collect users' selection + + $('#filter-search-nav li').each(function(index){ + $(this).click(function(ev){ + ev.preventDefault(); + + if ($(this).text() == i18nStrings.allCapitalized) { + //Selected filter feedback + $('.search-filter-selected').text(''); + $('input[name="classgroup"]').val(''); + console.log("ALL"); + } else { + + $('.search-filter-selected').text($(this).text()).fadeIn('slow'); + $('input[name="classgroup"]').val($(this).children("a").attr("title")); + } + + //Hide filter select list + $searchFilterList.css('display','none'); + + //Change button filter state to default + //$('a.filter-search').css('background','url(../../themes/vivo-cornell/images/filteredSearch.gif) no-repeat right top'); + $('a.filter-search').removeClass('filter-active'); + $('a.filter-search').addClass('filter-default'); + + $isFilterOpen = false; + }); + + }); + + //When focus, hide filter select list and change filter button state to default + $('input.search-homepage').focus(function(){ + + $('input.search-homepage').attr("value",""); + $('input.search-homepage').css({ + 'text-align' : 'left', + 'opacity' : 1 + }); + + if (!$isFilterOpen) { + + $isFilterOpen = false; + + }else { + + //Hide filter select list + $('#filter-search-nav').hide(); + + //Change button filter state to default + //$('a.filter-search').css('background','url(../../themes/vivo-cornell/images/filteredSearch.gif) no-repeat right top'); + $('a.filter-search').removeClass('filter-active'); + $('a.filter-search').addClass('filter-default'); + + $isFilterOpen = false; + + } + + console.log("HIDE input value ") ; + }); +}); diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedEmail.ftl index 35bb89956..a855f13c8 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedEmail.ftl @@ -2,67 +2,22 @@ <#-- Confirmation that an account has been created. --> -<#assign subject = "Your ${siteName} account has been created." /> +<#assign strings = i18n() /> -<#assign html> - - - ${subject} - - -

    - ${userAccount.firstName} ${userAccount.lastName} -

    - -

    - Congratulations! -

    - -

    - We have created your new account on ${siteName}, associated with ${userAccount.emailAddress}. -

    - -

    - If you did not request this new account you can safely ignore this email. - This request will expire if not acted upon for 30 days. -

    - -

    - Click the link below to create your password for your new account using our secure server. -

    - -

    - ${passwordLink} -

    - -

    - If the link above doesn't work, you can copy and paste the link directly into your browser's address bar. -

    - -

    - Thanks! -

    - - - +<#assign subject = strings.account_created(siteName) /> -<#assign text> -${userAccount.firstName} ${userAccount.lastName} +<#assign html = strings.account_created_email_html(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress, + passwordLink) /> -Congratulations! - -We have created your new account on ${siteName}, -associated with ${userAccount.emailAddress}. - -If you did not request this new account you can safely ignore this email. -This request will expire if not acted upon for 30 days. - -Paste the link below into your browser's address bar to create your password -for your new account using our secure server. - -${passwordLink} - -Thanks! - +<#assign text = strings.account_created_email_text(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress, + passwordLink) /> <@email subject=subject html=html text=text /> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedExternalOnlyEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedExternalOnlyEmail.ftl index df2959656..a6bc6f0e9 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedExternalOnlyEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedExternalOnlyEmail.ftl @@ -2,42 +2,18 @@ <#-- Confirmation that an account has been created. --> -<#assign subject = "Your ${siteName} account has been created." /> +<#assign subject = strings.account_created(siteName) /> -<#assign html> - - - ${subject} - - -

    - ${userAccount.firstName} ${userAccount.lastName} -

    - -

    - Congratulations! -

    - -

    - We have created your new VIVO account associated with ${userAccount.emailAddress}. -

    - -

    - Thanks! -

    - - - +<#assign html = strings.account_created_external_email_html(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> -<#assign text> -${userAccount.firstName} ${userAccount.lastName} - -Congratulations! - -We have created your new VIVO account associated with -${userAccount.emailAddress}. - -Thanks! - +<#assign text = string.account_created_external_email_text(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> <@email subject=subject html=html text=text /> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl index 26f1eee4a..a062882b3 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-add.ftl @@ -2,71 +2,54 @@ <#-- Template for adding a user account --> -

    > Add new account

    +<#assign strings = i18n() /> +

    > ${strings.add_new_account}

    <#if errorEmailIsEmpty??> - <#assign errorMessage = "You must supply an email address." /> + <#assign errorMessage = strings.error_no_email /> + <#elseif errorEmailInUse??> + <#assign errorMessage = strings.error_email_already_exists /> + <#elseif errorEmailInvalidFormat??> + <#assign errorMessage = strings.error_invalid_email(emailAddress) /> + <#elseif errorExternalAuthIdInUse??> + <#assign errorMessage = strings.error_external_auth_already_exists /> + <#elseif errorFirstNameIsEmpty??> + <#assign errorMessage = strings.error_no_first_name /> + <#elseif errorLastNameIsEmpty??> + <#assign errorMessage = strings.error_no_last_name /> + <#elseif errorNoRoleSelected??> + <#assign errorMessage = strings.error_no_role /> + <#elseif errorPasswordIsEmpty??> + <#assign errorMessage = strings.error_no_password /> + <#elseif errorPasswordIsWrongLength??> + <#assign errorMessage = strings.error_password_length(minimumLength, maximumLength) /> + <#elseif errorPasswordsDontMatch??> + <#assign errorMessage = strings.error_password_mismatch /> - - <#if errorEmailInUse??> - <#assign errorMessage = "An account with that email address already exists." /> - - - <#if errorEmailInvalidFormat??> - <#assign errorMessage = "'${emailAddress}' is not a valid email address." /> - - - <#if errorExternalAuthIdInUse??> - <#assign errorMessage = "An account with that external authorization ID already exists." /> - - - <#if errorFirstNameIsEmpty??> - <#assign errorMessage = "You must supply a first name." /> - - - <#if errorLastNameIsEmpty??> - <#assign errorMessage = "You must supply a last name." /> - - - <#if errorNoRoleSelected??> - <#assign errorMessage = "You must select a role." /> - - - <#if errorPasswordIsEmpty??> - <#assign errorMessage = "No password supplied." /> - - - <#if errorPasswordIsWrongLength??> - <#assign errorMessage = "Password must be between ${minimumLength} and ${maximumLength} characters." /> - - - <#if errorPasswordsDontMatch??> - <#assign errorMessage = "Passwords do not match." /> - - + <#if errorMessage?has_content>
    - + - + - + <#include "userAccounts-associateProfilePanel.ftl"> -

    checked />Externally Authenticated Only

    -

    Roles *

    +

    checked />${strings.external_auth_only}

    +

    ${strings.roles} *

    <#list roles as role> @@ -74,25 +57,21 @@ <#if emailIsEnabled??> -

    - Note: An email will be sent to the address entered above - notifying that an account has been created. - It will include instructions for activating the account and creating a password. -

    +

    ${strings.new_account_note}

    <#else>
    - + -

    Minimum of ${minimumLength} characters in length.

    +

    ${strings.minimum_password_length(minimumLength)}

    - +
    -

    or Cancel

    +

    ${strings.or} ${strings.cancel_link}

    -

    * required fields

    +

    * ${strings.required_fields}

    diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-associateProfilePanel.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-associateProfilePanel.ftl index f75ef2856..3cf0bedff 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-associateProfilePanel.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-associateProfilePanel.ftl @@ -2,20 +2,22 @@ <#-- Template for setting the account reference field, which can also associate a profile with the user account --> +<#assign strings = i18n() /> + ${stylesheets.add('', '')}
    <#if showAssociation??> - + - This Identifier is already in use. -

    Can be used to associate the account with the user's profile via the matching property.

    + ${strings.auth_id_in_use} +

    ${strings.auth_id_explanation}

    <#else> - + - This Identifier is already in use. + ${strings.auth_id_in_use}
    @@ -24,10 +26,10 @@ ${stylesheets.add('

    - + - (verify this match) - (change profile) + (${strings.verify_this_match}) + (${strings.change_profile})

    @@ -37,16 +39,16 @@ ${stylesheets.add('

    - +

    -

    - or -

    +

    - ${strings.or} -

    - + - + -

    Minimum of ${minimumLength} characters in length.

    +

    ${strings.minimum_password_length(minimumLength)}

    - + -

    +

    -

    * required fields

    +

    * ${strings.required_fields}

    diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl index e5b348fdc..df5ad40c6 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl @@ -2,75 +2,58 @@ <#-- Template for editing a user account --> -

    > Edit account

    +<#assign strings = i18n() /> +

    > ${strings.edit_account}

    <#if errorEmailIsEmpty??> - <#assign errorMessage = "You must supply an email address." /> - - - <#if errorEmailInUse??> - <#assign errorMessage = "An account with that email address already exists." /> - - - <#if errorEmailInvalidFormat??> - <#assign errorMessage = "'${emailAddress}' is not a valid email address." /> - - - <#if errorExternalAuthIdInUse??> - <#assign errorMessage = "An account with that external authorization ID already exists." /> - - - <#if errorFirstNameIsEmpty??> - <#assign errorMessage = "You must supply a first name." /> - - - <#if errorLastNameIsEmpty??> - <#assign errorMessage = "You must supply a last name." /> - - - <#if errorNoRoleSelected??> - <#assign errorMessage = "You must select a role." /> - - - <#if errorPasswordIsEmpty??> - <#assign errorMessage = "No password supplied." /> - - - <#if errorPasswordIsWrongLength??> - <#assign errorMessage = "Password must be between ${minimumLength} and ${maximumLength} characters." /> - - - <#if errorPasswordsDontMatch??> - <#assign errorMessage = "Passwords do not match." /> + <#assign errorMessage = strings.error_no_email /> + <#elseif errorEmailInUse??> + <#assign errorMessage = strings.error_email_already_exists /> + <#elseif errorEmailInvalidFormat??> + <#assign errorMessage = strings.error_invalid_email(emailAddress) /> + <#elseif errorExternalAuthIdInUse??> + <#assign errorMessage = strings.error_external_auth_already_exists /> + <#elseif errorFirstNameIsEmpty??> + <#assign errorMessage = strings.error_no_first_name /> + <#elseif errorLastNameIsEmpty??> + <#assign errorMessage = strings.error_no_last_name /> + <#elseif errorNoRoleSelected??> + <#assign errorMessage = strings.error_no_role /> + <#elseif errorPasswordIsEmpty??> + <#assign errorMessage = strings.error_no_password /> + <#elseif errorPasswordIsWrongLength??> + <#assign errorMessage = strings.error_password_length(minimumLength, maximumLength) /> + <#elseif errorPasswordsDontMatch??> + <#assign errorMessage = strings.error_password_mismatch /> <#if errorMessage?has_content>
    - + - + - + <#if externalAuthPermitted??> <#include "userAccounts-associateProfilePanel.ftl"> -

    checked />Externally Authenticated Only

    +

    checked />${strings.external_auth_only}

    <#if roles?has_content> -

    Roles *

    +

    ${strings.roles} *

    <#list roles as role> @@ -81,29 +64,25 @@ <#if emailIsEnabled??>
    class="hidden" role="region"> checked /> - + -

    - Note: Instructions for resetting the password will - be emailed to the address entered above. The password will not - be reset until the user follows the link provided in this email. -

    +

    ${strings.reset_password_note}

    <#else>
    class="hidden" role="region"> - + -

    Minimum of ${minimumLength} characters in length.
    - Leaving this blank means that the password will not be changed.

    +

    ${strings.minimum_password_length(minimumLength)}
    + ${strings.leave_password_unchanged}

    - +
    -

    or Cancel

    +

    ${strings.or} ${strings.cancel_link}

    -

    * required fields

    +

    * ${strings.required_fields}

    diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternal.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternal.ftl index a1f725bca..d5aaf65a6 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternal.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternal.ftl @@ -2,59 +2,55 @@ <#-- Template for creating an account for the first time an external user logs in. --> -

    First time log in

    +<#assign strings = i18n() /> + +

    ${strings.first_time_login}

    <#if errorEmailIsEmpty??> - <#assign errorMessage = "You must supply an email address." /> + <#assign errorMessage = strings.error_no_email /> + <#elseif errorEmailInUse??> + <#assign errorMessage = strings.error_email_already_exists /> + <#elseif errorEmailInvalidFormat??> + <#assign errorMessage = strings.error_invalid_email(emailAddress) /> + <#elseif errorFirstNameIsEmpty??> + <#assign errorMessage = strings.error_no_first_name /> + <#elseif errorLastNameIsEmpty??> + <#assign errorMessage = strings.error_no_last_name /> - - <#if errorEmailInUse??> - <#assign errorMessage = "An account with that email address already exists." /> - - - <#if errorEmailInvalidFormat??> - <#assign errorMessage = "'${emailAddress}' is not a valid email address." /> - - - <#if errorFirstNameIsEmpty??> - <#assign errorMessage = "You must supply a first name." /> - - - <#if errorLastNameIsEmpty??> - <#assign errorMessage = "You must supply a last name." /> - - + <#if errorMessage?has_content>
    -

    Please provide your contact information to finish creating your account.

    +

    ${strings.please_provide_contact_information}

    - + - + - + <#if emailIsEnabled??> -

    - Note: An email will be sent to the address entered above notifying - that an account has been created. -

    +

    ${strings.first_time_login_note}

    -

    or Cancel

    +

    + ${strings.or} + ${strings.cancel_link} +

    + +

    * ${strings.required_fields}

    diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternalEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternalEmail.ftl index a7b6cae83..247cc42b4 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternalEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-firstTimeExternalEmail.ftl @@ -2,42 +2,20 @@ <#-- Confirmation that an account has been created for an externally-authenticated user. --> -<#assign subject = "Your ${siteName} account has been created." /> +<#assign strings = i18n() /> -<#assign html> - - - ${subject} - - -

    - ${userAccount.firstName} ${userAccount.lastName} -

    - -

    - Congratulations! -

    - -

    - We have created your new VIVO account associated with ${userAccount.emailAddress}. -

    - -

    - Thanks! -

    - - - +<#assign subject = strings.account_created(siteName) /> -<#assign text> -${userAccount.firstName} ${userAccount.lastName} +<#assign html = strings.first_time_external_email_html(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> -Congratulations! - -We have created your new VIVO account associated with -${userAccount.emailAddress}. - -Thanks! - +<#assign text = strings.first_time_external_email_text(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> <@email subject=subject html=html text=text /> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl index 70b9c3e60..d9c5aa06c 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-list.ftl @@ -4,20 +4,19 @@ <#import "userAccounts-accountsNav.ftl" as p> +<#assign strings = i18n() /> +
    -

    User accounts |

    +

    ${strings.user_accounts_link} |

    <#if newUserAccount?? > @@ -25,14 +24,10 @@ <#if updatedUserAccount?? > @@ -40,7 +35,7 @@ <#if deletedAccountCount?? > @@ -48,7 +43,7 @@
    <#if roleFilterUri?has_content> - View all accounts + ${strings.view_all_accounts}
    @@ -68,7 +63,7 @@
    - + <#else> @@ -156,7 +151,7 @@ <#if account.editUrl != ""> - ${account.emailAddress} + ${account.emailAddress} <#else> ${account.emailAddress} @@ -185,5 +180,10 @@ <@p.accountsNav />
    + + ${stylesheets.add('')} ${scripts.add('')} \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-myAccount.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-myAccount.ftl index 27add004a..346269405 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-myAccount.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-myAccount.ftl @@ -2,58 +2,48 @@ <#-- Template for editing a user account --> -

    My account

    +<#assign strings = i18n() /> + +

    ${strings.myAccount_heading}

    <#if errorEmailIsEmpty??> - <#assign errorMessage = "You must supply an email address." /> + <#assign errorMessage = strings.error_no_email /> + <#elseif errorEmailInUse??> + <#assign errorMessage = strings.error_email_already_exists /> + <#elseif errorEmailInvalidFormat??> + <#assign errorMessage = strings.error_invalid_email(emailAddress) /> + <#elseif errorFirstNameIsEmpty??> + <#assign errorMessage = strings.error_no_first_name /> + <#elseif errorLastNameIsEmpty??> + <#assign errorMessage = strings.error_no_last_name /> + <#elseif errorNoRoleSelected??> + <#assign errorMessage = strings.error_no_role /> + <#elseif errorPasswordIsEmpty??> + <#assign errorMessage = strings.error_no_password /> + <#elseif errorPasswordIsWrongLength??> + <#assign errorMessage = strings.error_password_length(minimumLength, maximumLength) /> + <#elseif errorPasswordsDontMatch??> + <#assign errorMessage = strings.error_password_mismatch /> - - <#if errorEmailInUse??> - <#assign errorMessage = "An account with that email address already exists." /> - - - <#if errorEmailInvalidFormat??> - <#assign errorMessage = "'${emailAddress}' is not a valid email address." /> - - - <#if errorFirstNameIsEmpty??> - <#assign errorMessage = "You must supply a first name." /> - - - <#if errorLastNameIsEmpty??> - <#assign errorMessage = "You must supply a last name." /> - - - <#if errorPasswordIsEmpty??> - <#assign errorMessage = "No password supplied." /> - - - <#if errorPasswordIsWrongLength??> - <#assign errorMessage = "Password must be between ${minimumLength} and ${maximumLength} characters." /> - - - <#if errorPasswordsDontMatch??> - <#assign errorMessage = "Passwords do not match." /> - - + <#if errorMessage?has_content> <#if confirmChange??> - <#assign confirmMessage = "Your changes have been saved." /> + <#assign confirmMessage = strings.myAccount_confirm_changes /> <#if confirmEmailSent??> - <#assign confirmMessage = "Your changes have been saved. A confirmation email has been sent to ${emailAddress}." /> + <#assign confirmMessage = strings.myAccount_confirm_changes_plus_note(emailAddress) /> <#if confirmMessage?has_content> @@ -63,30 +53,34 @@ <#include "userAccounts-myProxiesPanel.ftl"> - + -

    Note: if email changes, a confirmation email will
    be sent to the new email address entered above.

    +

    ${strings.email_change_will_be_confirmed}

    - + - + <#if !externalAuth??> - + -

    Minimum of ${minimumLength} characters in length.
    If left blank, the password will not be changed.

    +

    ${strings.minimum_password_length(minimumLength)}
    ${strings.leave_password_unchanged}

    - + -

    or Cancel

    +

    + + ${strings.or} + ${strings.cancel_link} +

    -

    * required fields

    +

    * ${strings.required_fields}

    diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-myProxiesPanel.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-myProxiesPanel.ftl index 8c27c659f..7ab9f1b19 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-myProxiesPanel.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-myProxiesPanel.ftl @@ -2,15 +2,21 @@ <#-- Template for setting the account reference field, which can also associate a profile with the user account --> +<#assign strings = i18n() /> +
    -

    Who can edit my profile

    +

    ${strings.who_can_edit_profile}

    - - + + + -

     

    +

    +   +

    ${myAccountUri}

    -

    Selected editors:

    +

    ${strings.selected_editors}:

    <#-- Magic ul that holds all of the proxy data and the template that shows how to display it. -->
      @@ -35,7 +41,7 @@

      %label% | %classLabel%
      - Remove selection + ${strings.remove_selection}

      @@ -49,6 +55,9 @@ var proxyContextInfo = { baseUrl: '${urls.base}', ajaxUrl: '${formUrls.proxyAjax}' }; +var i18nStrings = { + selectEditorAndProfile: '${i18n().select_editor_and_profile}' +}; ${stylesheets.add('', diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail.ftl index 4177027ab..1a4941549 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordCreatedEmail.ftl @@ -2,42 +2,20 @@ <#-- Confirmation that an password has been created. --> -<#assign subject = "Your ${siteName} password has successfully been created." /> +<#assign strings = i18n() /> -<#assign html> - - - ${subject} - - -

      - ${userAccount.firstName} ${userAccount.lastName} -

      - -

      - Password successfully created. -

      - -

      - Your new password associated with ${userAccount.emailAddress} has been created. -

      - -

      - Thank you. -

      - - - +<#assign subject = strings.password_created_subject(siteName) /> -<#assign text> -${userAccount.firstName} ${userAccount.lastName} +<#assign html = strings.password_created_email_html(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> -Password successfully created. - -Your new password associated with ${userAccount.emailAddress} -has been created. - -Thank you. - +<#assign text = strings.password_created_email_text(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> <@email subject=subject html=html text=text /> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetCompleteEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetCompleteEmail.ftl index 8fd529c79..8badf9f3b 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetCompleteEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetCompleteEmail.ftl @@ -2,42 +2,20 @@ <#-- Confirmation that a password has been reset. --> -<#assign subject = "Your ${siteName} password changed." /> +<#assign strings = i18n() /> -<#assign html> - - - ${subject} - - -

      - ${userAccount.firstName} ${userAccount.lastName} -

      - -

      - Password successfully changed. -

      - -

      - Your new password associated with ${userAccount.emailAddress} has been changed. -

      - -

      - Thank you. -

      - - - +<#assign subject = strings.password_reset_complete_subject(siteName) /> -<#assign text> -${userAccount.firstName} ${userAccount.lastName} +<#assign html = strings.password_reset_complete_email_html(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> -Password successfully changed. - -Your new password associated with ${userAccount.emailAddress} -has been changed. - -Thank you. - +<#assign text = strings.password_reset_complete_email_text(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress) /> <@email subject=subject html=html text=text /> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetPendingEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetPendingEmail.ftl index d6fcc59a2..e02bdfd9a 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetPendingEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-passwordResetPendingEmail.ftl @@ -2,60 +2,22 @@ <#-- Confirmation email for user account password reset --> -<#assign subject = "${siteName} reset password request" /> +<#assign strings = i18n() /> -<#assign html> - - - ${subject} - - -

      - Dear ${userAccount.firstName} ${userAccount.lastName}: -

      - -

      - We have received a request to reset the password for your ${siteName} account (${userAccount.emailAddress}). -

      - -

      - Please follow the instructions below to proceed with your password reset. -

      - -

      - If you did not request this new account you can safely ignore this email. - This request will expire if not acted upon within 30 days. -

      - -

      - Click on the link below or paste it into your browser's address bar to reset your password - using our secure server. -

      - -

      ${passwordLink}

      - -

      Thank you!

      - - - +<#assign subject = strings.password_reset_pending_subject(siteName) /> -<#assign text> -Dear ${userAccount.firstName} ${userAccount.lastName}: - -We have received a request to reset the password for your ${siteName} account -(${userAccount.emailAddress}). +<#assign html = strings.password_reset_pending_email_html(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress, + passwordLink) /> -Please follow the instructions below to proceed with your password reset. - -If you did not request this new account you can safely ignore this email. -This request will expire if not acted upon within 30 days. - -Paste the link below into your browser's address bar to reset your password -using our secure server. - -${passwordLink} - -Thank you! - +<#assign text = strings.password_reset_pending_email_text(siteName, + subject, + userAccount.firstName, + userAccount.lastName, + userAccount.emailAddress, + passwordLink) /> <@email subject=subject html=html text=text /> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl index d7630d5fb..80fb7cc18 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-resetPassword.ftl @@ -2,45 +2,43 @@ <#-- Template for adding a user account --> -

      Reset your Password

      +<#assign strings = i18n() /> -

      Please enter your new password for ${userAccount.emailAddress}

      +

      ${strings.reset_your_password}

      - <#if errorPasswordIsEmpty??> - <#assign errorMessage = "No password supplied." /> - - - <#if errorPasswordIsWrongLength??> - <#assign errorMessage = "Password must be between ${minimumLength} and ${maximumLength} characters." /> - - - <#if errorPasswordsDontMatch??> - <#assign errorMessage = "Passwords do not match." /> - - - <#if errorMessage?has_content> - - +

      ${strings.enter_new_password(userAccount.emailAddress)}

      + +<#if errorPasswordIsEmpty??> + <#assign errorMessage = strings.error_no_password /> +<#elseif errorPasswordIsWrongLength??> + <#assign errorMessage = strings.error_password_length(minimumLength, maximumLength) /> +<#elseif errorPasswordsDontMatch??> + <#assign errorMessage = strings.error_password_mismatch /> + + +<#if errorMessage?has_content> + +
      - + -

      Minimum of ${minimumLength} characters in length.

      +

      ${strings.minimum_password_length(minimumLength)}

      - + -

      +

      -

      * required fields

      +

      * ${strings.required_fields}

      diff --git a/webapp/web/templates/freemarker/body/admin/admin-restrictLogins.ftl b/webapp/web/templates/freemarker/body/admin/admin-restrictLogins.ftl index bcea8f669..31ce05919 100644 --- a/webapp/web/templates/freemarker/body/admin/admin-restrictLogins.ftl +++ b/webapp/web/templates/freemarker/body/admin/admin-restrictLogins.ftl @@ -2,28 +2,28 @@ <#-- Template for restricting (or opening) access to logins. --> -

      Restrict Logins

      +

      ${i18n().restrict_logins}

      <#if messageAlreadyRestricted??> - <#assign errorMessage = "Logins are already restricted." /> + <#assign errorMessage = "${i18n().logins_already_restricted}" /> <#if messageAlreadyOpen??> - <#assign errorMessage = "Logins are already not restricted." /> + <#assign errorMessage = "${i18n().logins_not_already_restricted}" /> <#if errorMessage?has_content> <#if messageRestricting??> - <#assign successMessage = "Logins are now restricted." /> + <#assign successMessage = "${i18n().logins_restricted}" /> <#if messageOpening??> - <#assign successMessage = "Logins are no longer restricted." /> + <#assign successMessage = "${i18n().logins_not_restricted}" /> <#if successMessage?has_content> @@ -35,10 +35,10 @@
      <#if restricted == true> -

      Logins are restricted

      -

      Remove Restrictions

      +

      ${i18n().logins_are_restricted}

      +

      ${i18n().remove_restrictions}

      <#else> -

      Logins are open to all

      -

      Restrict Logins

      +

      ${i18n().logins_are_open}

      +

      ${i18n().restrict_logins}

      diff --git a/webapp/web/templates/freemarker/body/admin/admin-showAuth.ftl b/webapp/web/templates/freemarker/body/admin/admin-showAuth.ftl index 6a7c981f4..5a4b06714 100644 --- a/webapp/web/templates/freemarker/body/admin/admin-showAuth.ftl +++ b/webapp/web/templates/freemarker/body/admin/admin-showAuth.ftl @@ -7,24 +7,24 @@ ${stylesheets.add('Authorization Info
      -

      Current user

      +

      ${i18n().current_user}

      <#if currentUser?has_content> - - - - - + + + + + <#list currentUser.permissionSetUris as role> - + <#else> - +
      URI:${currentUser.uri}
      First name:${currentUser.firstName}
      Last name:${currentUser.lastName}
      Email:${currentUser.emailAddress}
      External Auth ID:${currentUser.externalAuthId}
      Login count:${currentUser.loginCount}
      ${i18n().first_name}:${currentUser.firstName}
      ${i18n().last_name}:${currentUser.lastName}
      ${i18n().email_address}:${currentUser.emailAddress}
      ${i18n().external_auth_id}:${currentUser.externalAuthId}
      ${i18n().login_count}:${currentUser.loginCount}
      Role:${role}
      ${i18n().user_role}:${role}
      Not logged in
      ${i18n().not_logged_in}
      -

      Identifiers:

      +

      ${i18n().identifiers}:

      <#list identifiers as identifier> @@ -34,11 +34,11 @@ ${stylesheets.add('

      - AssociatedIndividuals: + ${i18n().associated_individuals}: <#if matchingProperty??> - (match by ${matchingProperty}) + (${i18n().match_by(matchingProperty)}) <#else> - (matching property is not defined) + (${i18n().matching_prop_not_defined})

      @@ -47,18 +47,18 @@ ${stylesheets.add(' <#if associatedIndividual.editable> - + <#else> - + <#else> - +
      ${associatedIndividual.uri}May edit${i18n().may_edit}May not edit${i18n().may_not_edit}
      none
      ${i18n().none}
      -

      Identifier factories:

      +

      ${i18n().identifier_factories}:

      <#list factories as factory> @@ -67,7 +67,7 @@ ${stylesheets.add('
      -

      Policies:

      +

      ${i18n().policies}:

      <#list policies as policy> @@ -76,7 +76,7 @@ ${stylesheets.add('
      -

      Authenticator:

      +

      ${i18n().authenticator}:

      diff --git a/webapp/web/templates/freemarker/body/admin/admin-showThreads.ftl b/webapp/web/templates/freemarker/body/admin/admin-showThreads.ftl index 6b2b9a127..d9b5d8e38 100644 --- a/webapp/web/templates/freemarker/body/admin/admin-showThreads.ftl +++ b/webapp/web/templates/freemarker/body/admin/admin-showThreads.ftl @@ -17,15 +17,15 @@ table.threadInfo th { -

      Background Threads

      +

      ${i18n().background_threads}

      <#list threads as threadInfo>
      ${authenticator}
      - - - - + + + +
      Name${threadInfo.name}
      WorkLevel${threadInfo.workLevel}
      Since${threadInfo.since}
      Flags${threadInfo.flags}
      ${i18n().name}${threadInfo.name}
      ${i18n().work_level}${threadInfo.workLevel}
      ${i18n().since}${threadInfo.since}
      ${i18n().flags}${threadInfo.flags}
      \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/admin/searchIndex.ftl b/webapp/web/templates/freemarker/body/admin/searchIndex.ftl index ab5ee849e..6486e17c8 100644 --- a/webapp/web/templates/freemarker/body/admin/searchIndex.ftl +++ b/webapp/web/templates/freemarker/body/admin/searchIndex.ftl @@ -4,40 +4,40 @@ Template for the page that controls the updating or rebuilding of the Search Index. --> -

      Search Index Status

      +

      ${i18n().search_index_status}

      <#if !indexIsConnected> <#elseif worklevel == "IDLE"> -

      The search indexer is idle.

      +

      ${i18n().search_indexer_idle}

      <#if hasPreviousBuild??> -

      The most recent update was at ${since?string("hh:mm:ss a, MMMM dd, yyyy")}

      +

      ${i18n().most_recent_update} ${since?string("hh:mm:ss a, MMMM dd, yyyy")}

      - - Reset the search index and re-populate it. + + ${i18n().reset_search_index}

      <#elseif totalToDo == 0> -

      Preparing to rebuild the search index.

      -

      since ${since?string("hh:mm:ss a, MMMM dd, yyyy")}, elapsed time ${elapsed}

      +

      ${i18n().preparing_to_rebuild_index}

      +

      ${i18n().since_elapsed_time(since?string("hh:mm:ss a, MMMM dd, yyyy"),elapsed)}

      <#else> -

      ${currentTask} the search index.

      -

      since ${since?string("hh:mm:ss a, MMMM dd, yyyy")}, elapsed time ${elapsed}, estimated total time ${expected}

      -

      Completed ${completedCount} out of ${totalToDo} index records.

      +

      ${i18n().current_task(currentTask)}

      +

      ${i18n().since_elapsed_time_est_total(since?string("hh:mm:ss a, MMMM dd, yyyy"),elapsed,expected)}

      +

      ${i18n().index_recs_completed(completedCount,totalToDo)}

      diff --git a/webapp/web/templates/freemarker/body/admin/startupStatus-display.ftl b/webapp/web/templates/freemarker/body/admin/startupStatus-display.ftl index f55cb53fc..1d8288d33 100644 --- a/webapp/web/templates/freemarker/body/admin/startupStatus-display.ftl +++ b/webapp/web/templates/freemarker/body/admin/startupStatus-display.ftl @@ -35,9 +35,9 @@ ${stylesheets.add('')} <#if status.errorItems?has_content> -

      Fatal error

      +

      ${i18n().fatal_error}

      -

      ${applicationName} detected a fatal error during startup.

      +

      ${i18n().fatal_error_detected(applicationName)}

      - + \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/classGroups.ftl b/webapp/web/templates/freemarker/body/classGroups.ftl index 9d12507d7..5703c6b30 100644 --- a/webapp/web/templates/freemarker/body/classGroups.ftl +++ b/webapp/web/templates/freemarker/body/classGroups.ftl @@ -8,6 +8,9 @@
      <#list classGroups as classGroup> + <#assign groupSize = classGroup.classes?size > + <#assign classCount = 0 > + <#assign splitGroup = false> <#-- Only render classgroups that have at least one populated class --> <#if (classGroup.individualCount > 0)>
      @@ -16,7 +19,15 @@ <#list classGroup.classes as class> <#-- Only render populated classes --> <#if (class.individualCount > 0)> -
    • ${class.name} (${class.individualCount})
    • +
    • ${class.name} (${class.individualCount})
    • + <#assign classCount = classCount + 1 > + + <#if (classCount > 34) && !splitGroup > + <#assign splitGroup = true > +
    +
    +

    ${classGroup.displayName} (${i18n().continued})

    +
    @@ -29,7 +40,7 @@ ${headScripts.add('')} ${stylesheets.add('', '')} diff --git a/webapp/web/templates/freemarker/body/displayEdit/displayConfig.ftl b/webapp/web/templates/freemarker/body/displayEdit/displayConfig.ftl index ab5fa51a7..40afdbf84 100644 --- a/webapp/web/templates/freemarker/body/displayEdit/displayConfig.ftl +++ b/webapp/web/templates/freemarker/body/displayEdit/displayConfig.ftl @@ -5,7 +5,7 @@ <#if errorMessage??>
    - + Error alert icon

    ${errorMessage}

    diff --git a/webapp/web/templates/freemarker/body/error/error-display.ftl b/webapp/web/templates/freemarker/body/error/error-display.ftl index bd1936097..a878bc098 100644 --- a/webapp/web/templates/freemarker/body/error/error-display.ftl +++ b/webapp/web/templates/freemarker/body/error/error-display.ftl @@ -3,27 +3,27 @@ <#-- Template for general system error. -->

    - There was an error in the system. + ${i18n().we_have_an_error} <#if sentEmail> - This error has been reported to the site administrator. + ${i18n().error_was_reported}

    <#if adminErrorData??> <#-- view for site administrators --> <#if adminErrorData.errorMessage?has_content> -

    Error message: ${adminErrorData.errorMessage?html}

    +

    ${i18n().error_message}: ${adminErrorData.errorMessage?html}

    <#if adminErrorData.stackTrace?has_content>

    - Stack trace (full trace available in the vivo log): ${adminErrorData.stackTrace?html} + ${i18n().stack_trace} (${i18n().trace_available}): ${adminErrorData.stackTrace?html}

    <#if adminErrorData.cause?has_content> -

    Caused by: ${adminErrorData.cause?html}

    +

    ${i18n().caused_by}: ${adminErrorData.cause?html}

    <#elseif ! errorOnHomePage> <#-- view for other users --> -

    Return to the home page

    +

    ${i18n().return_to_the} ${i18n().home_page}

    diff --git a/webapp/web/templates/freemarker/body/error/error-email.ftl b/webapp/web/templates/freemarker/body/error/error-email.ftl index 90963b60f..9f5b360c6 100644 --- a/webapp/web/templates/freemarker/body/error/error-email.ftl +++ b/webapp/web/templates/freemarker/body/error/error-email.ftl @@ -2,7 +2,7 @@ <#-- Template for email message sent to site administrator when an error occurs on the site. --> -<#assign subject = "An error occurred on the VIVO site" /> +<#assign subject = "${i18n().error_occurred}" /> <#assign datetime = datetime?string("yyyy-MM-dd HH:mm:ss zzz")> @@ -13,26 +13,26 @@

    - An error occurred on your VIVO site at ${datetime!}. + ${i18n().error_occurred_at(datetime!)}

    - Requested url: ${requestedUrl!} + ${i18n().requested_url}: ${requestedUrl!}

    <#if errorMessage?has_content> - Error message: ${errorMessage!} + ${i18n().error_message}: ${errorMessage!}

    - Stack trace (full trace available in the vivo log): + ${i18n().stack_trace} (${i18n().trace_available}):

    ${stackTrace!}

    <#if cause?has_content> -

    Caused by: +

    ${i18n().caused_by}:

    ${cause!}

    @@ -42,19 +42,19 @@ <#assign text> -An error occurred on your VIVO site at ${datetime!}. +${i18n().error_occurred_at(datetime!)} -Requested url: ${requestedUrl!} +${i18n().requested_url}: ${requestedUrl!} <#if errorMessage?has_content> - Error message: ${errorMessage!} + ${i18n().error_message}: ${errorMessage!} -Stack trace (full trace available in the vivo log): +${i18n().stack_trace} (${i18n().trace_available}): ${stackTrace!} <#if cause?has_content> -Caused by: +${i18n().caused_by}: ${cause!} diff --git a/webapp/web/templates/freemarker/body/error/error-standard.ftl b/webapp/web/templates/freemarker/body/error/error-standard.ftl index 1eedaf780..690f5d041 100644 --- a/webapp/web/templates/freemarker/body/error/error-standard.ftl +++ b/webapp/web/templates/freemarker/body/error/error-standard.ftl @@ -2,6 +2,6 @@ <#-- Template for general system error. --> -

    There was an error in the system.

    +

    ${i18n().we_have_an_error}.

    -

    Return to the home page.

    \ No newline at end of file +

    ${i18n().return_to_the} ${i18n().home_page}

    \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-cropImage.ftl b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-cropImage.ftl index 9f6f94ad0..bd8d7b5b0 100644 --- a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-cropImage.ftl +++ b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-cropImage.ftl @@ -21,20 +21,22 @@ ${stylesheets.add(' -

    Photo Upload

    +

    ${i18n.upload_heading}

    -

    Your profile photo will look like the image below.

    +

    ${i18n.cropping_caption}

    - Image to be cropped + ${i18n.alt_image_to_crop}
    -

    To make adjustments, you can drag around and resize the photo to the right. When you are happy with your photo click the "Save Photo" button.

    +

    ${i18n.cropping_note}

    @@ -43,15 +45,15 @@ ${stylesheets.add(' - + - or Cancel + ${i18n.or} ${i18n.cancel_link}
    - Preview of photo cropped + ${i18n.alt_preview_crop}
    diff --git a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-newImage.ftl b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-newImage.ftl index 675b63920..cf9a6b204 100644 --- a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-newImage.ftl +++ b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-newImage.ftl @@ -7,29 +7,35 @@ ${scripts.add(' diff --git a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-replaceImage.ftl b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-replaceImage.ftl index d8850d188..cc5a9b7bd 100644 --- a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-replaceImage.ftl +++ b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-replaceImage.ftl @@ -7,30 +7,36 @@ ${scripts.add(' diff --git a/webapp/web/templates/freemarker/body/individual/individual-help.ftl b/webapp/web/templates/freemarker/body/individual/individual-help.ftl index 6929787c8..09efeeacf 100644 --- a/webapp/web/templates/freemarker/body/individual/individual-help.ftl +++ b/webapp/web/templates/freemarker/body/individual/individual-help.ftl @@ -2,6 +2,6 @@ <#-- Template for help on individual page --> -

    Individual not found:

    +

    ${i18n().individual_not_found}

    -

    id is the id of the entity to query for. netid also works.

    \ No newline at end of file +

    ${i18n().entity_to_query_for}

    \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/individual/individual-menu.ftl b/webapp/web/templates/freemarker/body/individual/individual-menu.ftl index 9819b280a..039e59d17 100644 --- a/webapp/web/templates/freemarker/body/individual/individual-menu.ftl +++ b/webapp/web/templates/freemarker/body/individual/individual-menu.ftl @@ -13,7 +13,7 @@ var menuItemData = []; -

    Menu Ordering

    +

    ${i18n().menu_ordering}

    <#-- List the menu items -->
    -<#assign nameForOtherGroup = "other"> <#-- used by both individual-propertyGroupMenu.ftl and individual-properties.ftl --> +<#assign nameForOtherGroup = "${i18n().other}"> <#-- @@ -69,6 +69,13 @@ var individualRdfUrl = '${rdfUrl}'; + ${stylesheets.add('')} @@ -77,3 +84,7 @@ ${headScripts.add('', '')} + + diff --git a/webapp/web/templates/freemarker/body/individual/manageLabelsForIndividual.ftl b/webapp/web/templates/freemarker/body/individual/manageLabelsForIndividual.ftl index ded17a0e1..0e24140e2 100644 --- a/webapp/web/templates/freemarker/body/individual/manageLabelsForIndividual.ftl +++ b/webapp/web/templates/freemarker/body/individual/manageLabelsForIndividual.ftl @@ -7,11 +7,9 @@ <#if subjectName?? >

    Manage Labels for ${subjectName}

    <#else> -

    Manage Labels

    +

    ${i18n().manage_labels}

    -

    -Multiple labels exist for this profile but there should only be one. Select the label you want displayed on the profile page, and the others will be deleted. -

    +

    ${i18n().manage_labels_intro}

      @@ -43,9 +41,12 @@ Multiple labels exist for this profile but there should only be one. Select the

      - + or - Cancel + ${i18n().cancel_link} +

    @@ -54,6 +55,9 @@ var customFormData = { processingUrl: '${urls.base}/edit/primitiveRdfEdit', individualUri: '${subjectUri!}' }; +var i18nStrings = { + errorProcessingLabels: '${i18n().error_processing_labels}' +}; ${stylesheets.add('')} diff --git a/webapp/web/templates/freemarker/body/individualList-checkForData.ftl b/webapp/web/templates/freemarker/body/individualList-checkForData.ftl index 3c6fa2d0e..d87214cf8 100644 --- a/webapp/web/templates/freemarker/body/individualList-checkForData.ftl +++ b/webapp/web/templates/freemarker/body/individualList-checkForData.ftl @@ -10,19 +10,19 @@ <#if user.loggedIn> <#if user.authorizedToRebuildSearchIndex> -

    Expecting content?

    -

    Try rebuilding the search index.

    +

    ${i18n().expecting_content}

    +

    ${i18n().try_rebuilding_index}.

    <#else> -

    Please log in to manage content.

    +

    ${i18n().please} ${i18n().log_in} ${i18n().to_manage_content}

    -

    There is currently no ${title} content in the system

    +

    ${i18n().no_content_in_system(title)}

    <#if user.loggedIn && user.hasSiteAdminAccess> -

    You can add content and manage this site from the Site Administration page.

    +

    ${i18n().you_can} ${i18n().add_content_manage_site} ${i18n().from_site_admin_page}

    \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/individualList.ftl b/webapp/web/templates/freemarker/body/individualList.ftl index c03afc558..4746a0a7f 100644 --- a/webapp/web/templates/freemarker/body/individualList.ftl +++ b/webapp/web/templates/freemarker/body/individualList.ftl @@ -11,7 +11,7 @@ ${stylesheets.add('

    ${title} <#if rdfUrl?has_content> - RDF + ${i18n().rdf}

    <#if subtitle?has_content> @@ -24,7 +24,7 @@ ${stylesheets.add(' <#list pages as page> <#if page.selected> diff --git a/webapp/web/templates/freemarker/body/login/adminLogin.ftl b/webapp/web/templates/freemarker/body/login/adminLogin.ftl index d8d856dea..152b827ee 100644 --- a/webapp/web/templates/freemarker/body/login/adminLogin.ftl +++ b/webapp/web/templates/freemarker/body/login/adminLogin.ftl @@ -3,69 +3,69 @@ <#-- Template for login using internal vitro account (even when external auth is enabled). Accessible at /admin/login -->
    -

    Internal Login

    +

    ${i18n().internal_login}

    <#if errorNoEmail??> - <#assign errorMessage = "No email supplied." /> + <#assign errorMessage = "${i18n().no_email_supplied}" /> <#if errorNoPassword??> - <#assign errorMessage = "No password supplied." /> + <#assign errorMessage = "${i18n().no_password_supplied}" /> <#if errorLoginDisabled??> - <#assign errorMessage = "User logins are temporarily disabled while the system is being maintained." /> + <#assign errorMessage = "${i18n().logins_temporarily_disabled}" /> <#if errorLoginFailed??> - <#assign errorMessage = "Email or Password was incorrect." /> + <#assign errorMessage = "${i18n().incorrect_email_password}" /> <#if errorNewPasswordWrongLength??> - <#assign errorMessage = "Password must be between 6 and 12 characters." /> + <#assign errorMessage = "${i18n().password_length(minPasswordLength, maxPasswordLength)}" /> <#if errorNewPasswordsDontMatch??> - <#assign errorMessage = "Passwords do not match." /> + <#assign errorMessage = "${i18n().password_mismatch}" /> <#if errorNewPasswordMatchesOld??> - <#assign errorMessage = "Your new password must be different from your existing password." /> + <#assign errorMessage = "${i18n().new_pwd_matches_existing}" /> <#if errorMessage?has_content> <#if !newPasswordRequired??> -

    Enter the email address and password for your internal Vitro account.

    +

    ${i18n().enter_email_password}

    <#else> -

    You must change your password to log in.

    +

    ${i18n().change_password}

    <#if newPasswordRequired??> - + -

    Minimum of 6 characters in length.

    +

    ${i18n().minimum_password_length(minPasswordLength)}

    - + <#else> - + - + -

    +

    \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/login/fakeExternalAuth.ftl b/webapp/web/templates/freemarker/body/login/fakeExternalAuth.ftl index c5c30d24c..f1576b906 100644 --- a/webapp/web/templates/freemarker/body/login/fakeExternalAuth.ftl +++ b/webapp/web/templates/freemarker/body/login/fakeExternalAuth.ftl @@ -3,17 +3,17 @@ <#-- Template for the Fake External Authentication page. -->
    -

    Fake External Authentication

    +

    ${i18n().fake_external_auth}

    - Enter the userID that you want to sign in as, or click Cancel. + ${i18n().enter_id_to_login}

    - Username: + ${i18n().username}: - - + +

    diff --git a/webapp/web/templates/freemarker/body/login/login.ftl b/webapp/web/templates/freemarker/body/login/login.ftl index e310b341e..930f195ea 100644 --- a/webapp/web/templates/freemarker/body/login/login.ftl +++ b/webapp/web/templates/freemarker/body/login/login.ftl @@ -2,4 +2,7 @@ <#-- Main template for the login page --> -<@widget name="login" /> \ No newline at end of file +<@widget name="login" /> + \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/manageproxies/manageProxies-list.ftl b/webapp/web/templates/freemarker/body/manageproxies/manageProxies-list.ftl index efe74bd6b..18ad67874 100644 --- a/webapp/web/templates/freemarker/body/manageproxies/manageProxies-list.ftl +++ b/webapp/web/templates/freemarker/body/manageproxies/manageProxies-list.ftl @@ -2,36 +2,36 @@ <#-- Template for displaying list of user accounts --> -

    Manage profile editing

    +

    ${i18n().manage_profile_editing}

    <#if message??>
    -

    Relate profile editors and profiles info icon

    +

    ${i18n().relate_editors_profiles} ${i18n().info_icon}

    - Select editors + ${i18n().select_editors}
    - - -

     

    + + +

     

    <#-- Magic div that holds all of the proxy data and the template that shows how to display it. -->
    - Select profiles + ${i18n().select_profiles}
    - - + + -

     

    +

     

    <#-- Magic div thst holds all of the proxy data and the template that shows how to display it. -->
    - +
    -

    Profile editors

    +

    ${i18n().profile_editors}

    - + <#if page.previous??> - | Previous + | ${i18n().previous} <#if page.last != 0> @@ -109,11 +109,11 @@ <#if page.next??> - Next + ${i18n().next_capitalized} <#if searchTerm?has_content> -

    Search results for "${searchTerm}" | View all profile editors

    +

    ${i18n().search_results_for} '${searchTerm}' | ${i18n().view_profile_editors}

    @@ -129,22 +129,22 @@

    ${p.label} | ${p.classLabel}
    - Delete profile editor + ${i18n().delete_profile_editor}

    - Add profile + ${i18n().add_profile}
    - - + + -

     

    +

     

    ${r.proxyInfos[0].profileUri}

    -

    Selected profiles:

    +

    ${i18n().selected_profiles}:

    <#-- Magic div that holds all of the proxy data and the template that shows how to display it. -->
    - +
    @@ -188,6 +188,9 @@ var proxyContextInfo = { baseUrl: '${urls.base}', ajaxUrl: '${formUrls.ajax}' }; +var i18nStrings = { + selectEditorAndProfile: '${i18n().select_editor_and_profile}' +}; ${stylesheets.add('')} diff --git a/webapp/web/templates/freemarker/body/menuN3Edit.ftl b/webapp/web/templates/freemarker/body/menuN3Edit.ftl index f9f3ea212..b6c671054 100644 --- a/webapp/web/templates/freemarker/body/menuN3Edit.ftl +++ b/webapp/web/templates/freemarker/body/menuN3Edit.ftl @@ -1,11 +1,11 @@ <#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/menupage/emptyPage.ftl b/webapp/web/templates/freemarker/body/menupage/emptyPage.ftl index 7c1940558..fa8579b12 100644 --- a/webapp/web/templates/freemarker/body/menupage/emptyPage.ftl +++ b/webapp/web/templates/freemarker/body/menupage/emptyPage.ftl @@ -1,9 +1,9 @@ <#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
    -

    This page is not yet configured.

    +

    ${i18n().page_not_configured}

    -

    Implement a link to configure this page if the user has permission.

    +

    ${i18n().implement_capitalized} ${i18n().a_link} ${i18n().configure_page_if_permissable}

    diff --git a/webapp/web/templates/freemarker/body/menupage/menupage--defaultFixedHtml.ftl b/webapp/web/templates/freemarker/body/menupage/menupage--defaultFixedHtml.ftl index d44ca480e..ea783a5ad 100644 --- a/webapp/web/templates/freemarker/body/menupage/menupage--defaultFixedHtml.ftl +++ b/webapp/web/templates/freemarker/body/menupage/menupage--defaultFixedHtml.ftl @@ -9,7 +9,7 @@ <#if htmlExists> ${.globals[variableName]} <#else> - No HTML specified. + ${i18n().no_html_specified} diff --git a/webapp/web/templates/freemarker/body/menupage/menupage--defaultSolrIndividuals.ftl b/webapp/web/templates/freemarker/body/menupage/menupage--defaultSolrIndividuals.ftl index e987f6d0f..9e73c2446 100644 --- a/webapp/web/templates/freemarker/body/menupage/menupage--defaultSolrIndividuals.ftl +++ b/webapp/web/templates/freemarker/body/menupage/menupage--defaultSolrIndividuals.ftl @@ -21,14 +21,14 @@ ${stylesheets.add(' <#list pages as page> <#if page.selected>
  • ${page.text}
  • <#else> <#-- RY Ideally the urls would be generated by the controller; see search-pagedResults.ftl --> -
  • ${page.text}
  • +
  • ${page.text}
  • diff --git a/webapp/web/templates/freemarker/body/menupage/menupage--defaultSparql.ftl b/webapp/web/templates/freemarker/body/menupage/menupage--defaultSparql.ftl index c937ba034..2d9acfce3 100644 --- a/webapp/web/templates/freemarker/body/menupage/menupage--defaultSparql.ftl +++ b/webapp/web/templates/freemarker/body/menupage/menupage--defaultSparql.ftl @@ -10,7 +10,7 @@ <#assign sparqlResults = .globals[variableName]/> -

    Sparql Query Results

    +

    ${i18n().sparql_query_results}

    <#if resultsExist> <#assign numberRows = sparqlResults?size/> <#assign firstRow = false/> @@ -31,7 +31,7 @@
    <#else> - No results were returned. + ${i18n().no_results_returned} ${stylesheets.add('')} diff --git a/webapp/web/templates/freemarker/body/menupage/page-pageList.ftl b/webapp/web/templates/freemarker/body/menupage/page-pageList.ftl index 8553f4816..80cef6ac6 100644 --- a/webapp/web/templates/freemarker/body/menupage/page-pageList.ftl +++ b/webapp/web/templates/freemarker/body/menupage/page-pageList.ftl @@ -4,29 +4,29 @@ <#if pages?has_content > - + <#list pages as pagex> - + <#if pagex.pageUri??> - + <#else> - +
    TitleURI${i18n().title_capitalized}URI
    ${(pagex.title)!'-untitled-'}${(pagex.title)!i18n().untitled}${pagex.pageUri}${pagex.pageUri}URI for page not defined${i18n().uri_not_defined}
    <#else> -

    There are no pages defined yet.

    +

    ${i18n().no_pages_defined}

    - +
    \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/pagemanagement/page-pageList.ftl b/webapp/web/templates/freemarker/body/pagemanagement/page-pageList.ftl index 8553f4816..2884d8b09 100644 --- a/webapp/web/templates/freemarker/body/pagemanagement/page-pageList.ftl +++ b/webapp/web/templates/freemarker/body/pagemanagement/page-pageList.ftl @@ -4,29 +4,29 @@ <#if pages?has_content > - + <#list pages as pagex> <#if pagex.pageUri??> - + <#else> - +
    TitleURI${i18n().title_capitalized}URI
    ${(pagex.title)!'-untitled-'}${pagex.pageUri}${pagex.pageUri}URI for page not defined${i18n().uri_not_defined}
    <#else> -

    There are no pages defined yet.

    +

    ${i18n().no_pages_defined}

    - +
    \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/pagemanagement/pageList.ftl b/webapp/web/templates/freemarker/body/pagemanagement/pageList.ftl index 02b36df1b..426a175e5 100644 --- a/webapp/web/templates/freemarker/body/pagemanagement/pageList.ftl +++ b/webapp/web/templates/freemarker/body/pagemanagement/pageList.ftl @@ -2,21 +2,21 @@
    -

    Page Management

    +

    ${i18n().page_management}

    <#if pages?has_content > - +
    Page Management
    - - + + - - - + + + @@ -28,11 +28,11 @@ <#if pagex.listedPageTitle == "Home" > ${pagex.listedPageTitle!} <#else> - ${(pagex.listedPageTitle)!'-untitled-'} + ${(pagex.listedPageTitle)!i18n().untitled} <#else> - No URI defined for page. + ${i18n().uri_not_defined} @@ -44,12 +44,12 @@ @@ -60,20 +60,24 @@
    ${i18n().page_management}
    Title${i18n().title_capitalized} URLCustom TemplateMenu PageControls${i18n().custom_template}${i18n().menu_page}${i18n().controls}
    - edit + ${i18n().edit_page}    - profile page + ${i18n().view_profile_for_page}    <#if !pagex.listedPageCannotDeletePage?has_content > - delete + ${i18n().delete_page}
    <#else> -

    There are no pages defined yet.

    +

    ${i18n().no_pages_defined}

    - +

    -

    Use Menu Ordering to set the order of menu items.

    +

    ${i18n().use_capitalized} ${i18n().menu_orering} ${i18n().to_order_menu_items}

    - + ${stylesheets.add('', '')} diff --git a/webapp/web/templates/freemarker/body/partials/account/userAccounts-accountsNav.ftl b/webapp/web/templates/freemarker/body/partials/account/userAccounts-accountsNav.ftl index 2b2f75f1d..9af9a7ec5 100644 --- a/webapp/web/templates/freemarker/body/partials/account/userAccounts-accountsNav.ftl +++ b/webapp/web/templates/freemarker/body/partials/account/userAccounts-accountsNav.ftl @@ -11,14 +11,14 @@ <#macro accountsNav accountsCount=counts>
    - +
    diff --git a/webapp/web/templates/freemarker/body/partials/browse-classgroups.ftl b/webapp/web/templates/freemarker/body/partials/browse-classgroups.ftl index ceec3903c..d96f96129 100644 --- a/webapp/web/templates/freemarker/body/partials/browse-classgroups.ftl +++ b/webapp/web/templates/freemarker/body/partials/browse-classgroups.ftl @@ -24,7 +24,7 @@ ${stylesheets.add('${group.displayName?capitalize} (${group.individualCount}) +
  • ${group.displayName?capitalize} (${group.individualCount})
  • @@ -32,7 +32,7 @@ ${stylesheets.add(' -

    Browse by

    +

    ${i18n().browse_by}

      ${classGroupList} @@ -71,20 +71,25 @@ ${stylesheets.add('')} <#else> <#-- Would be nice to update classgroups-checkForData.ftl with macro so it could be used here as well --> <#-- <#include "classgroups-checkForData.ftl"> --> -

      There is currently no content in the system, or you need to create class groups and assign your classes to them.

      +

      ${i18n().no_content_create_groups_classes}

      <#if user.loggedIn> <#if user.hasSiteAdminAccess> -

      You can add content and manage this site from the Site Administration page.

      +

      ${i18n().you_can} ${i18n().add_content_manage_site} ${i18n().from_site_admin_page}

      <#else> -

      Please log in to manage content.

      +

      ${i18n().please} ${i18n().log_in} ${i18n().to_manage_content}

      diff --git a/webapp/web/templates/freemarker/body/partials/classgroups-checkForData.ftl b/webapp/web/templates/freemarker/body/partials/classgroups-checkForData.ftl index 51fe77fe2..8580c11be 100644 --- a/webapp/web/templates/freemarker/body/partials/classgroups-checkForData.ftl +++ b/webapp/web/templates/freemarker/body/partials/classgroups-checkForData.ftl @@ -18,19 +18,19 @@ <#if user.loggedIn> <#if user.authorizedToRebuildSearchIndex> -

      Expecting content?

      -

      Try rebuilding the search index.

      +

      ${i18n().expecting_content}

      +

      ${i18n().try_rebuilding_index}.

      <#else> -

      Please log in to manage content.

      +

      ${i18n().please} ${i18n().log_in} ${i18n().to_manage_content}

      -

      There is currently no content in the system, or you need to create class groups and assign your classes to them.

      +

      ${i18n().no_content_create_groups_classes}

      <#if user.loggedIn && user.hasSiteAdminAccess> -

      You can add content and manage this site from the Site Administration page.

      +

      ${i18n().you_can} ${i18n().add_content_manage_site} ${i18n().from_site_admin_page}

      \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/partials/individual/individual-adminPanel.ftl b/webapp/web/templates/freemarker/body/partials/individual/individual-adminPanel.ftl index 3dcca64cc..93d58850f 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/individual-adminPanel.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/individual-adminPanel.ftl @@ -6,18 +6,18 @@ <#if individual.showAdminPanel>
      -

      Admin Panel

      Edit this individual +

      ${i18n().admin_panel}

      ${i18n().edit_this_individual}
      <#if verbosePropertySwitch?has_content> <#assign anchorId = "verbosePropertySwitch"> - <#assign currentValue = verbosePropertySwitch.currentValue?string("on", "off")> - <#assign newValue = verbosePropertySwitch.currentValue?string("off", "on")> - Verbose property display is ${currentValue} | - Turn ${newValue} + <#assign currentValue = verbosePropertySwitch.currentValue?string("${i18n().verbose_status_on}", "${i18n().verbose_status_off}")> + <#assign newValue = verbosePropertySwitch.currentValue?string("${i18n().verbose_status_off}", "${i18n().verbose_status_on}")> + ${i18n().verbose_property_status} ${currentValue} | + <#if verbosePropertySwitch.currentValue!>${i18n().verbose_turn_off}<#else>${i18n().verbose_turn_on}
      - +
      \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/partials/individual/individual-properties.ftl b/webapp/web/templates/freemarker/body/partials/individual/individual-properties.ftl index 48ceefded..9854636bb 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/individual-properties.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/individual-properties.ftl @@ -7,20 +7,20 @@ <#-- Property display name --> <#if property.localName == "authorInAuthorship" && editable >

      ${property.name} <@p.addLink property editable /> <@p.verboseDisplay property /> - style="padding-top:10px" > - manage publications + style="padding-top:10px" > + ${i18n().manage_publications}

      <#elseif property.localName == "hasResearcherRole" && editable >

      ${property.name} <@p.addLink property editable /> <@p.verboseDisplay property /> - style="padding-top:10px" > - manage grants & projects + style="padding-top:10px" > + ${i18n().manage_grants_and_projects}

      <#elseif property.localName == "organizationForPosition" && editable >

      ${property.name} <@p.addLink property editable /> <@p.verboseDisplay property /> - style="padding-top:10px" > - manage affiliated people + style="padding-top:10px" > + ${i18n().manage_affiliated_people_link}

      <#else> diff --git a/webapp/web/templates/freemarker/body/partials/individual/individual-property-group-menus.ftl b/webapp/web/templates/freemarker/body/partials/individual/individual-property-group-menus.ftl index 8d5b013dc..0cd78b2b0 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/individual-property-group-menus.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/individual-property-group-menus.ftl @@ -19,7 +19,7 @@ <#assign groupnameHtmlId = p.createPropertyGroupHtmlId(groupname) > <#-- capitalize will capitalize each word in the name; cap_first only the first. We may need a custom function to capitalize all except function words. --> -
    • ${groupname?capitalize}
    • +
    • ${groupname?capitalize}
    @@ -33,8 +33,8 @@
    @@ -44,7 +44,7 @@ <#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) >

    ${groupName?capitalize}

    <#else> -

    Properties

    +

    ${i18n().properties_capitalized}

    <#-- List the properties in the group --> diff --git a/webapp/web/templates/freemarker/body/partials/individual/individual-property-group-tabs.ftl b/webapp/web/templates/freemarker/body/partials/individual/individual-property-group-tabs.ftl index e4c4a594c..3b77322c8 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/individual-property-group-tabs.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/individual-property-group-tabs.ftl @@ -15,8 +15,8 @@ <#--the function replaces spaces in the name with underscores, also called for the property group menu--> <#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) > <#else> - <#assign groupName = "Properties"> - <#assign groupNameHtmlId = "properties" > + <#assign groupName = "${i18n().properties_capitalized}"> + <#assign groupNameHtmlId = "${i18n().properties}" > <#if tabCount = 1 >
  • ${groupName?capitalize}
  • @@ -28,7 +28,7 @@ <#if (propertyGroups.all?size > 1) > -
  • View All
  • +
  • ${i18n().view_all_capitalized}
  •  
  • @@ -38,8 +38,8 @@ <#assign verbose = (verbosePropertySwitch.currentValue)!false>
    @@ -49,7 +49,7 @@ <#assign groupNameHtmlId = p.createPropertyGroupHtmlId(groupName) > <#else> - +
    <#-- List the properties in the group --> diff --git a/webapp/web/templates/freemarker/body/partials/individual/individual-propertyGroupMenu.ftl b/webapp/web/templates/freemarker/body/partials/individual/individual-propertyGroupMenu.ftl index a7b7bf618..7860975e7 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/individual-propertyGroupMenu.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/individual-propertyGroupMenu.ftl @@ -1,8 +1,8 @@ <#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> -<#-- Template for property group menu on individual profile page --> +<#-- Template for property group menu on individual profile page nameForOtherGroup! --> -<#assign nameForOtherGroup = nameForOtherGroup!"other"> +<#assign nameForOtherGroup = "${i18n().other}"> <#if (propertyGroups.all)??> <#assign groups = propertyGroups.all> @@ -18,7 +18,7 @@ <#assign groupnameHtmlId = p.createPropertyGroupHtmlId(groupname) > <#-- capitalize will capitalize each word in the name; cap_first only the first. We may need a custom function to capitalize all except function words. --> -
  • ${groupname?capitalize}
  • +
  • ${groupname?capitalize}
  • diff --git a/webapp/web/templates/freemarker/body/partials/individual/propStatement-default.ftl b/webapp/web/templates/freemarker/body/partials/individual/propStatement-default.ftl index 631af8bcd..6377a922e 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/propStatement-default.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/propStatement-default.ftl @@ -6,4 +6,4 @@ is also used to generate the property statement during a deletion. --> -${statement.label!statement.localName!} +${statement.label!statement.localName!} diff --git a/webapp/web/templates/freemarker/body/partials/individual/propStatement-simple.ftl b/webapp/web/templates/freemarker/body/partials/individual/propStatement-simple.ftl index 997619703..47c138c01 100644 --- a/webapp/web/templates/freemarker/body/partials/individual/propStatement-simple.ftl +++ b/webapp/web/templates/freemarker/body/partials/individual/propStatement-simple.ftl @@ -1,5 +1,4 @@ <#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> <#-- Simple object property statement template --> - -${statement.name!} +${statement.name!} diff --git a/webapp/web/templates/freemarker/body/partials/menupage/menupage-browse.ftl b/webapp/web/templates/freemarker/body/partials/menupage/menupage-browse.ftl index 2d8e7e34e..23ea661f1 100644 --- a/webapp/web/templates/freemarker/body/partials/menupage/menupage-browse.ftl +++ b/webapp/web/templates/freemarker/body/partials/menupage/menupage-browse.ftl @@ -4,7 +4,7 @@ <#import "lib-string.ftl" as str>