Worked on refactoring the startup listeners NIHVIVO-3700. Removed some old N3 code.
This commit is contained in:
parent
3250efd091
commit
29e4edc25d
15 changed files with 1166 additions and 2088 deletions
|
@ -1,6 +1,6 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
package edu.cornell.mannlib.vitro.webapp.config;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
@ -12,10 +12,13 @@ import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
import javax.servlet.ServletContextListener;
|
import javax.servlet.ServletContextListener;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||||
|
|
||||||
public class BasicSmokeTests implements ServletContextListener {
|
/**
|
||||||
|
* Test that gets run at servlet context startup to check for the existence and
|
||||||
|
* validity of properties in the configuration.
|
||||||
|
*/
|
||||||
|
public class ConfigurationPropertiesSmokeTests implements ServletContextListener {
|
||||||
|
|
||||||
private static final String PROPERTY_HOME_DIRECTORY = "vitro.home.directory";
|
private static final String PROPERTY_HOME_DIRECTORY = "vitro.home.directory";
|
||||||
private static final String PROPERTY_DB_URL = "VitroConnection.DataSource.url";
|
private static final String PROPERTY_DB_URL = "VitroConnection.DataSource.url";
|
|
@ -73,7 +73,7 @@ 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.jena.VitroJenaSDBModelMaker;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSpecialModelMaker;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSpecialModelMaker;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
|
||||||
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetup;
|
import edu.cornell.mannlib.vitro.webapp.servlet.setup.WebappDaoSDBSetup;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
|
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;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils.MergeResult;
|
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils.MergeResult;
|
||||||
|
@ -942,7 +942,7 @@ public class JenaIngestController extends BaseEditController {
|
||||||
log.debug("Connecting to DB at "+jdbcUrl);
|
log.debug("Connecting to DB at "+jdbcUrl);
|
||||||
StoreDesc storeDesc = new StoreDesc(LayoutType.LayoutTripleNodesHash,dbTypeObj) ;
|
StoreDesc storeDesc = new StoreDesc(LayoutType.LayoutTripleNodesHash,dbTypeObj) ;
|
||||||
ServletContext ctx = vreq.getSession().getServletContext();
|
ServletContext ctx = vreq.getSession().getServletContext();
|
||||||
BasicDataSource bds = JenaDataSourceSetup.makeBasicDataSource(
|
BasicDataSource bds = WebappDaoSDBSetup.makeBasicDataSource(
|
||||||
driver, jdbcUrl, username, password, ctx);
|
driver, jdbcUrl, username, password, ctx);
|
||||||
try {
|
try {
|
||||||
VitroJenaSDBModelMaker vsmm = new VitroJenaSDBModelMaker(storeDesc, bds);
|
VitroJenaSDBModelMaker vsmm = new VitroJenaSDBModelMaker(storeDesc, bds);
|
||||||
|
|
|
@ -1,600 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.edit.elements;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.joda.time.format.ISODateTimeFormat;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Literal;
|
|
||||||
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerConfiguration;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditSubmission;
|
|
||||||
import freemarker.template.Configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is intended to work in conjunction with a template to create the HTML for a
|
|
||||||
* datetime with precision and to convert the submitted parameters into
|
|
||||||
* varname -> Literal and varname -> URI maps.
|
|
||||||
*
|
|
||||||
* The variables that get passed to the template are defined in:
|
|
||||||
* DateTimeWithPrecision.getMapForTemplate()
|
|
||||||
*
|
|
||||||
* Two variables will be defined for the N3 edit graphs (These are NOT variables passed to FM templates):
|
|
||||||
* $fieldname.precision - URI of datetime precision
|
|
||||||
* $fieldname.value - DateTime literal
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class DateTimeWithPrecision extends BaseEditElement {
|
|
||||||
|
|
||||||
String fieldName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the minimum datetime precision that this element
|
|
||||||
* will accept. If the parameters submitted do not meet this
|
|
||||||
* requirement, then a validation error will be created.
|
|
||||||
*/
|
|
||||||
VitroVocabulary.Precision minimumPrecision;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the maximum precision that the form should
|
|
||||||
* allow the user to enter. This value is not used by
|
|
||||||
* DateTimeWithPrecision for validation, it is only passed
|
|
||||||
* to the template. This should be removed when it can be
|
|
||||||
* specified in a ftl file.
|
|
||||||
*
|
|
||||||
* This could be thought of as the maximum precision to display.
|
|
||||||
*/
|
|
||||||
VitroVocabulary.Precision displayRequiredLevel;
|
|
||||||
|
|
||||||
|
|
||||||
VitroVocabulary.Precision DEFAULT_MIN_PRECISION = VitroVocabulary.Precision.DAY;
|
|
||||||
VitroVocabulary.Precision DEFAULT_DISPLAY_LEVEL = VitroVocabulary.Precision.DAY;
|
|
||||||
VitroVocabulary.Precision[] precisions = VitroVocabulary.Precision.values();
|
|
||||||
|
|
||||||
protected static final String BLANK_SENTINEL = ">SUBMITTED VALUE WAS BLANK<";
|
|
||||||
|
|
||||||
public DateTimeWithPrecision(Field field) {
|
|
||||||
super(field);
|
|
||||||
fieldName = field.getName();
|
|
||||||
minimumPrecision = DEFAULT_MIN_PRECISION;
|
|
||||||
displayRequiredLevel = DEFAULT_DISPLAY_LEVEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTimeWithPrecision(Field field, VitroVocabulary.Precision minimumPrecision){
|
|
||||||
this(field);
|
|
||||||
if( minimumPrecision != null )
|
|
||||||
this.minimumPrecision = minimumPrecision;
|
|
||||||
else
|
|
||||||
this.minimumPrecision = DEFAULT_MIN_PRECISION;
|
|
||||||
this.displayRequiredLevel = this.minimumPrecision;
|
|
||||||
}
|
|
||||||
|
|
||||||
//it would be nice to have only the version of the constructor that takes the enum
|
|
||||||
//but this is to quickly get the JSP configuration working.
|
|
||||||
public DateTimeWithPrecision(Field field, String minimumPrecisionURI, String displayRequiredLevelUri){
|
|
||||||
this(field);
|
|
||||||
|
|
||||||
this.minimumPrecision = toPrecision( minimumPrecisionURI);
|
|
||||||
if( this.minimumPrecision == null )
|
|
||||||
throw new IllegalArgumentException(minimumPrecisionURI
|
|
||||||
+" is not a valid precision for minimumPrecision, see VitroVocabulary.Precision");
|
|
||||||
|
|
||||||
this.displayRequiredLevel = toPrecision( displayRequiredLevelUri );
|
|
||||||
if( this.displayRequiredLevel == null )
|
|
||||||
throw new IllegalArgumentException(displayRequiredLevelUri
|
|
||||||
+" is not a valid precision for displayRequiredLevel, see VitroVocabulary.Precision");
|
|
||||||
|
|
||||||
// if( this.displayRequiredLevel.ordinal() < this.minimumPrecision.ordinal() ){
|
|
||||||
// throw new IllegalArgumentException("the display precision level " + this.displayRequiredLevel
|
|
||||||
// + " is less precise than the required minimum precision of " + this.minimumPrecision);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(DateTimeWithPrecision.class);
|
|
||||||
protected String TEMPLATE_NAME = "dateTimeWithPrecision.ftl";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String draw(String fieldName, EditConfiguration editConfig,
|
|
||||||
EditSubmission editSub, Configuration fmConfig) {
|
|
||||||
Map map = getMapForTemplate( editConfig, editSub);
|
|
||||||
return merge( fmConfig, TEMPLATE_NAME, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This produces a map for use in the template.
|
|
||||||
*/
|
|
||||||
protected Map getMapForTemplate(EditConfiguration editConfig, EditSubmission editSub) {
|
|
||||||
Map<String,Object>map = new HashMap<String,Object>();
|
|
||||||
|
|
||||||
//always need the fieldName, required precision, and constants
|
|
||||||
map.put("fieldName", fieldName);
|
|
||||||
addPrecisionConstants(map);
|
|
||||||
map.put("minimumPrecision", minimumPrecision.uri());
|
|
||||||
map.put("requiredLevel", displayRequiredLevel.uri());
|
|
||||||
|
|
||||||
String precisionUri = getPrecision(editConfig,editSub);
|
|
||||||
VitroVocabulary.Precision existingPrec = toPrecision(precisionUri);
|
|
||||||
|
|
||||||
if( precisionUri != null && !"".equals(precisionUri) && existingPrec == null ){
|
|
||||||
log.error("field " + fieldName + ": existing precision uri was " +
|
|
||||||
"'" + precisionUri + "' but could not convert to Precision object");
|
|
||||||
}
|
|
||||||
|
|
||||||
if( precisionUri == null || precisionUri.isEmpty() || existingPrec == null){
|
|
||||||
map.put("existingPrecision", "");
|
|
||||||
|
|
||||||
/* no precision so there should also be no datetime */
|
|
||||||
DateTime value = getTimeValue(editConfig,editSub);
|
|
||||||
if( value != null )
|
|
||||||
log.info("Unexpected state: Precision for " + fieldName
|
|
||||||
+ " was '" + precisionUri + "' but date time was " + value);
|
|
||||||
|
|
||||||
map.put("year", "");
|
|
||||||
map.put("month", "");
|
|
||||||
map.put("day", "");
|
|
||||||
map.put("hour", "");
|
|
||||||
map.put("minute", "");
|
|
||||||
map.put("second", "") ;
|
|
||||||
} else if( VitroVocabulary.Precision.NONE.uri().equals(precisionUri) ){
|
|
||||||
//bdc34: not sure what to do with the NONE precision
|
|
||||||
map.put("existingPrecision", precisionUri);
|
|
||||||
|
|
||||||
map.put("year", "");
|
|
||||||
map.put("month", "");
|
|
||||||
map.put("day", "");
|
|
||||||
map.put("hour", "");
|
|
||||||
map.put("minute", "");
|
|
||||||
map.put("second", "") ;
|
|
||||||
}else{
|
|
||||||
map.put("existingPrecision", precisionUri);
|
|
||||||
|
|
||||||
DateTime value = getTimeValue(editConfig,editSub);
|
|
||||||
/* This is the case where there is a precision so there should be a datetime */
|
|
||||||
if( value == null )
|
|
||||||
log.error("Field " + fieldName + " has precision " + precisionUri
|
|
||||||
+ " but the date time is " + value);
|
|
||||||
|
|
||||||
/* only put the values in the map for ones which are significant based on the precision */
|
|
||||||
if( existingPrec.ordinal() >= VitroVocabulary.Precision.SECOND.ordinal() )
|
|
||||||
map.put("second", Integer.toString(value.getSecondOfMinute() )) ;
|
|
||||||
else
|
|
||||||
map.put("second", "");
|
|
||||||
|
|
||||||
if( existingPrec.ordinal() >= VitroVocabulary.Precision.MINUTE.ordinal() )
|
|
||||||
map.put("minute", Integer.toString(value.getMinuteOfHour()) );
|
|
||||||
else
|
|
||||||
map.put("minute", "");
|
|
||||||
|
|
||||||
if( existingPrec.ordinal() >= VitroVocabulary.Precision.HOUR.ordinal() )
|
|
||||||
map.put("hour", Integer.toString(value.getHourOfDay()) );
|
|
||||||
else
|
|
||||||
map.put("hour", "");
|
|
||||||
|
|
||||||
if( existingPrec.ordinal() >= VitroVocabulary.Precision.DAY.ordinal() )
|
|
||||||
map.put("day", Integer.toString(value.getDayOfMonth()) );
|
|
||||||
else
|
|
||||||
map.put("day", "");
|
|
||||||
|
|
||||||
if( existingPrec.ordinal() >= VitroVocabulary.Precision.MONTH.ordinal() )
|
|
||||||
map.put("month", Integer.toString(value.getMonthOfYear()));
|
|
||||||
else
|
|
||||||
map.put("month", "");
|
|
||||||
|
|
||||||
if( existingPrec.ordinal() >= VitroVocabulary.Precision.YEAR.ordinal() )
|
|
||||||
map.put("year", Integer.toString(value.getYear()));
|
|
||||||
else
|
|
||||||
map.put("year", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds precisionURIs for use by the templates */
|
|
||||||
private void addPrecisionConstants(Map<String,Object> map){
|
|
||||||
Map<String,Object> constants = new HashMap<String,Object>();
|
|
||||||
for( VitroVocabulary.Precision pc: VitroVocabulary.Precision.values()){
|
|
||||||
constants.put(pc.name().toLowerCase(),pc.uri());
|
|
||||||
}
|
|
||||||
map.put("precisionConstants", constants);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the currently set precision. May return null.
|
|
||||||
*/
|
|
||||||
private String getPrecision(EditConfiguration editConfig, EditSubmission editSub) {
|
|
||||||
if( editSub != null ){
|
|
||||||
String submittedPrecisionURI = editSub.getUrisFromForm().get( getPrecisionVariableName() );
|
|
||||||
if( submittedPrecisionURI != null ){
|
|
||||||
return submittedPrecisionURI;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String existingPrecisionURI = editConfig.getUrisInScope().get( getPrecisionVariableName() );
|
|
||||||
if( existingPrecisionURI != null ){
|
|
||||||
return existingPrecisionURI;
|
|
||||||
}else{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private DateTime getTimeValue(EditConfiguration editConfig, EditSubmission editSub) {
|
|
||||||
if( editSub != null ){
|
|
||||||
Literal submittedValue = editSub.getLiteralsFromForm().get( getValueVariableName() );
|
|
||||||
if( submittedValue != null )
|
|
||||||
return new DateTime( submittedValue.getLexicalForm() );
|
|
||||||
}
|
|
||||||
|
|
||||||
Literal dtValue = editConfig.getLiteralsInScope().get( getValueVariableName() );
|
|
||||||
if( dtValue != null ){
|
|
||||||
return new DateTime( dtValue.getLexicalForm() );
|
|
||||||
}else{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This gets the literals for a submitted form from the queryParmeters.
|
|
||||||
* It will only be called if getValidationErrors() doesn't return any errors.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Map<String, Literal> getLiterals(String fieldName,
|
|
||||||
EditConfiguration editConfig, Map<String, String[]> queryParameters) {
|
|
||||||
Map<String,Literal> literalMap = new HashMap<String,Literal>();
|
|
||||||
|
|
||||||
Literal datetime =getDateTime( queryParameters);
|
|
||||||
literalMap.put(fieldName+"-value", datetime);
|
|
||||||
|
|
||||||
return literalMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Literal getDateTime( Map<String, String[]> queryParameters ) {
|
|
||||||
String submittedPrec = BLANK_SENTINEL;
|
|
||||||
try {
|
|
||||||
submittedPrec = getSubmittedPrecision( queryParameters);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("could not get submitted precsion",e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( BLANK_SENTINEL.equals( submittedPrec ) )
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Integer year = parseToInt(fieldName+"-year", queryParameters);
|
|
||||||
|
|
||||||
//this is the case where date has not been filled out at all.
|
|
||||||
if( year == null )
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Integer month = parseToInt(fieldName+"-month", queryParameters);
|
|
||||||
if( month == null || month == 0 )
|
|
||||||
month = 1;
|
|
||||||
Integer day = parseToInt(fieldName+"-day", queryParameters);
|
|
||||||
if( day == null || day == 0 )
|
|
||||||
day = 1;
|
|
||||||
Integer hour = parseToInt(fieldName+"-hour", queryParameters);
|
|
||||||
if( hour == null )
|
|
||||||
hour = 0;
|
|
||||||
Integer minute = parseToInt(fieldName+"-minute", queryParameters);
|
|
||||||
if( minute == null )
|
|
||||||
minute = 0;
|
|
||||||
Integer second = parseToInt(fieldName+"-second", queryParameters);
|
|
||||||
if( second == null )
|
|
||||||
second = 0;
|
|
||||||
|
|
||||||
DateTime value = new DateTime(
|
|
||||||
year.intValue(),month.intValue(),day.intValue(),
|
|
||||||
hour.intValue(),minute.intValue(),second.intValue(),0/*millis*/
|
|
||||||
);
|
|
||||||
|
|
||||||
return ResourceFactory.createTypedLiteral(
|
|
||||||
ISODateTimeFormat.dateHourMinuteSecond().print(value), /*does not include timezone*/
|
|
||||||
XSDDatatype.XSDdateTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This gets the URIs for a submitted form from the queryParmeters.
|
|
||||||
* It will only be called if getValidationErrors() doesn't return any errors.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getURIs(String fieldName,
|
|
||||||
EditConfiguration editConfig, Map<String, String[]> queryParameters) {
|
|
||||||
String precisionUri;
|
|
||||||
try {
|
|
||||||
precisionUri = getSubmittedPrecision( queryParameters);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("getURIs() should only be called on input that passed getValidationErrors()");
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
Map<String,String> uriMap = new HashMap<String,String>();
|
|
||||||
if( precisionUri != null )
|
|
||||||
uriMap.put(fieldName+"-precision", precisionUri);
|
|
||||||
return uriMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Precision is based on the values returned by the form. Throws an exception with
|
|
||||||
* the error message if the queryParameters cannot make a valid date/precision because
|
|
||||||
* there are values missing.
|
|
||||||
*/
|
|
||||||
protected String getSubmittedPrecision(Map<String, String[]> queryParameters) throws Exception {
|
|
||||||
|
|
||||||
Integer year = parseToInt(fieldName+"-year",queryParameters);
|
|
||||||
Integer month = parseToInt(fieldName+"-month",queryParameters);
|
|
||||||
Integer day = parseToInt(fieldName+"-day",queryParameters);
|
|
||||||
Integer hour = parseToInt(fieldName+"-hour",queryParameters);
|
|
||||||
Integer minute = parseToInt(fieldName+"-minute",queryParameters);
|
|
||||||
Integer second = parseToInt(fieldName+"-second",queryParameters);
|
|
||||||
Integer[] values = { year, month, day, hour, minute, second };
|
|
||||||
|
|
||||||
/* find the most significant date field that is null. */
|
|
||||||
int indexOfFirstNull= -1;
|
|
||||||
for(int i=0; i < values.length ; i++){
|
|
||||||
if( values[i] == null ){
|
|
||||||
indexOfFirstNull = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the field wasn't filled out at all */
|
|
||||||
if( indexOfFirstNull == 0 )
|
|
||||||
//return VitroVocabulary.Precision.NONE.uri();
|
|
||||||
return BLANK_SENTINEL;
|
|
||||||
|
|
||||||
/* if they all had values then we have seconds precision */
|
|
||||||
if( indexOfFirstNull == -1 )
|
|
||||||
return VitroVocabulary.Precision.SECOND.uri();
|
|
||||||
|
|
||||||
|
|
||||||
/* check that there are no values after the most significant null field
|
|
||||||
* that are non-null. */
|
|
||||||
boolean nonNullAfterFirstNull=false;
|
|
||||||
for(int i=0; i < values.length ; i++){
|
|
||||||
if( i > indexOfFirstNull && values[i] != null ){
|
|
||||||
nonNullAfterFirstNull = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( nonNullAfterFirstNull )
|
|
||||||
throw new Exception("Invalid date-time value. When creating a date-time value, there cannot be gaps between any of the selected fields.");
|
|
||||||
else{
|
|
||||||
return precisions[ indexOfFirstNull ].uri();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getValidationMessages(String fieldName,
|
|
||||||
EditConfiguration editConfig, Map<String, String[]> queryParameters) {
|
|
||||||
Map<String,String> errorMsgMap = new HashMap<String,String>();
|
|
||||||
|
|
||||||
//check that any parameters we got are single values
|
|
||||||
String[] names = {"year","month","day","hour","minute","second", "precision"};
|
|
||||||
for( String name:names){
|
|
||||||
if ( !hasNoneOrSingle(fieldName+"-"+name, queryParameters))
|
|
||||||
errorMsgMap.put(fieldName+"-"+name, "must have only one value for " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
String precisionURI = null;
|
|
||||||
try{
|
|
||||||
precisionURI = getSubmittedPrecision( queryParameters);
|
|
||||||
}catch(Exception ex){
|
|
||||||
errorMsgMap.put(fieldName,ex.getMessage());
|
|
||||||
return errorMsgMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
errorMsgMap.putAll(checkDate( precisionURI, queryParameters) );
|
|
||||||
|
|
||||||
return errorMsgMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This checks for invalid date times.
|
|
||||||
*/
|
|
||||||
final static String NON_INTEGER_YEAR = "must enter a valid year";
|
|
||||||
final static String NON_INTEGER_MONTH = "must enter a valid month";
|
|
||||||
final static String NON_INTEGER_DAY = "must enter a valid day";
|
|
||||||
final static String NON_INTEGER_HOUR = "must enter a valid hour";
|
|
||||||
final static String NON_INTEGER_MINUTE = "must enter a valid minute";
|
|
||||||
final static String NON_INTEGER_SECOND = "must enter a valid second";
|
|
||||||
|
|
||||||
private Map<String,String> checkDate( String precisionURI, Map<String, String[]> qp){
|
|
||||||
if( precisionURI == null )
|
|
||||||
return Collections.emptyMap();
|
|
||||||
|
|
||||||
Map<String,String> errors = new HashMap<String,String>();
|
|
||||||
|
|
||||||
Integer year,month,day,hour,minute,second;
|
|
||||||
|
|
||||||
//just check if the values for the precision parse to integers
|
|
||||||
if( precisionURI.equals(VitroVocabulary.Precision.YEAR.uri() ) ){
|
|
||||||
if( ! canParseToNumber(fieldName+"-year" ,qp))
|
|
||||||
errors.put(fieldName+"-year", NON_INTEGER_YEAR);
|
|
||||||
}else if( precisionURI.equals( VitroVocabulary.Precision.MONTH.uri() )){
|
|
||||||
if( ! canParseToNumber(fieldName+"-year" ,qp))
|
|
||||||
errors.put(fieldName+"-year", NON_INTEGER_YEAR);
|
|
||||||
if( ! canParseToNumber(fieldName+"-month" ,qp))
|
|
||||||
errors.put(fieldName+"-month", NON_INTEGER_MONTH);
|
|
||||||
}else if( precisionURI.equals( VitroVocabulary.Precision.DAY.uri() )){
|
|
||||||
if( ! canParseToNumber(fieldName+"-year" ,qp))
|
|
||||||
errors.put(fieldName+"-year", NON_INTEGER_YEAR);
|
|
||||||
if( ! canParseToNumber(fieldName+"-month" ,qp))
|
|
||||||
errors.put(fieldName+"-month", NON_INTEGER_MONTH);
|
|
||||||
if( ! canParseToNumber(fieldName+"-day" ,qp))
|
|
||||||
errors.put(fieldName+"-day", NON_INTEGER_DAY);
|
|
||||||
}else if( precisionURI.equals( VitroVocabulary.Precision.HOUR.uri() )){
|
|
||||||
if( ! canParseToNumber(fieldName+"-year" ,qp))
|
|
||||||
errors.put(fieldName+"-year", NON_INTEGER_YEAR);
|
|
||||||
if( ! canParseToNumber(fieldName+"-month" ,qp))
|
|
||||||
errors.put(fieldName+"-month", NON_INTEGER_MONTH);
|
|
||||||
if( ! canParseToNumber(fieldName+"-day" ,qp))
|
|
||||||
errors.put(fieldName+"-day", NON_INTEGER_DAY);
|
|
||||||
if( ! canParseToNumber(fieldName+"-hour" ,qp))
|
|
||||||
errors.put(fieldName+"-hour", NON_INTEGER_HOUR);
|
|
||||||
}else if( precisionURI.equals( VitroVocabulary.Precision.MINUTE.uri() )){
|
|
||||||
if( ! canParseToNumber(fieldName+"-year" ,qp))
|
|
||||||
errors.put(fieldName+"-year", NON_INTEGER_YEAR);
|
|
||||||
if( ! canParseToNumber(fieldName+"-month" ,qp))
|
|
||||||
errors.put(fieldName+"-month", NON_INTEGER_MONTH);
|
|
||||||
if( ! canParseToNumber(fieldName+"-day" ,qp))
|
|
||||||
errors.put(fieldName+"-day", NON_INTEGER_DAY);
|
|
||||||
if( ! canParseToNumber(fieldName+"-hour" ,qp))
|
|
||||||
errors.put(fieldName+"-hour", NON_INTEGER_HOUR);
|
|
||||||
if( ! canParseToNumber(fieldName+"-minute" ,qp))
|
|
||||||
errors.put(fieldName+"-minute", NON_INTEGER_HOUR);
|
|
||||||
}else if( precisionURI.equals( VitroVocabulary.Precision.SECOND.uri() )){
|
|
||||||
if( ! canParseToNumber(fieldName+"-year" ,qp))
|
|
||||||
errors.put(fieldName+"-year", NON_INTEGER_YEAR);
|
|
||||||
if( ! canParseToNumber(fieldName+"-month" ,qp))
|
|
||||||
errors.put(fieldName+"-month", NON_INTEGER_MONTH);
|
|
||||||
if( ! canParseToNumber(fieldName+"-day" ,qp))
|
|
||||||
errors.put(fieldName+"-day", NON_INTEGER_DAY);
|
|
||||||
if( ! canParseToNumber(fieldName+"-hour" ,qp))
|
|
||||||
errors.put(fieldName+"-hour", NON_INTEGER_HOUR);
|
|
||||||
if( ! canParseToNumber(fieldName+"-minute" ,qp))
|
|
||||||
errors.put(fieldName+"-minute", NON_INTEGER_HOUR);
|
|
||||||
if( ! canParseToNumber(fieldName+"-second" ,qp))
|
|
||||||
errors.put(fieldName+"-second", NON_INTEGER_SECOND);
|
|
||||||
}
|
|
||||||
|
|
||||||
//check if we can make a valid date with these integers
|
|
||||||
year = parseToInt(fieldName+"-year", qp);
|
|
||||||
if( year == null )
|
|
||||||
year = 1999;
|
|
||||||
month= parseToInt(fieldName+"-month", qp);
|
|
||||||
if(month == null )
|
|
||||||
month = 1;
|
|
||||||
day = parseToInt(fieldName+"-day", qp);
|
|
||||||
if( day == null )
|
|
||||||
day = 1;
|
|
||||||
hour = parseToInt(fieldName+"-hour", qp);
|
|
||||||
if( hour == null )
|
|
||||||
hour = 0;
|
|
||||||
minute = parseToInt(fieldName+"-minute",qp);
|
|
||||||
if( minute == null )
|
|
||||||
minute = 0;
|
|
||||||
second = parseToInt(fieldName+"-second", qp);
|
|
||||||
if( second == null )
|
|
||||||
second = 0;
|
|
||||||
|
|
||||||
//initialize to something so that we can be assured not to get
|
|
||||||
//system date dependent behavior
|
|
||||||
DateTime dateTime = new DateTime("1970-01-01T00:00:00Z");
|
|
||||||
|
|
||||||
try{
|
|
||||||
dateTime = dateTime.withYear(year);
|
|
||||||
}catch(IllegalArgumentException iae){
|
|
||||||
errors.put(fieldName+"-year", iae.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
try{
|
|
||||||
dateTime = dateTime.withMonthOfYear(month);
|
|
||||||
}catch(IllegalArgumentException iae){
|
|
||||||
errors.put(fieldName+"-month", iae.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
try{
|
|
||||||
dateTime = dateTime.withDayOfMonth(day);
|
|
||||||
}catch(IllegalArgumentException iae){
|
|
||||||
errors.put(fieldName+"-day", iae.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
try{
|
|
||||||
dateTime = dateTime.withHourOfDay(hour);
|
|
||||||
}catch(IllegalArgumentException iae){
|
|
||||||
errors.put(fieldName+"-hour", iae.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
try{
|
|
||||||
dateTime = dateTime.withSecondOfMinute(second);
|
|
||||||
}catch(IllegalArgumentException iae){
|
|
||||||
errors.put(fieldName+"-second", iae.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private boolean fieldMatchesPattern( String fieldName, Map<String,String[]>queryParameters, Pattern pattern){
|
|
||||||
String[] varg = queryParameters.get(fieldName);
|
|
||||||
if( varg == null || varg.length != 1 || varg[0] == null)
|
|
||||||
return false;
|
|
||||||
String value = varg[0];
|
|
||||||
Matcher match = pattern.matcher(value);
|
|
||||||
return match.matches();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean emptyOrBlank(String key,Map<String, String[]> queryParameters){
|
|
||||||
String[] vt = queryParameters.get(key);
|
|
||||||
return ( vt == null || vt.length ==0 || vt[0] == null || vt[0].length() == 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean canParseToNumber(String key,Map<String, String[]> queryParameters){
|
|
||||||
Integer out = null;
|
|
||||||
try{
|
|
||||||
String[] vt = queryParameters.get(key);
|
|
||||||
if( vt == null || vt.length ==0 || vt[0] == null)
|
|
||||||
return false;
|
|
||||||
else{
|
|
||||||
out = Integer.parseInt(vt[0]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}catch(IndexOutOfBoundsException iex){
|
|
||||||
out = null;
|
|
||||||
}catch(NumberFormatException nfe){
|
|
||||||
out = null;
|
|
||||||
}catch(NullPointerException npe){
|
|
||||||
out = null;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Integer parseToInt(String key,Map<String, String[]> queryParameters){
|
|
||||||
Integer out = null;
|
|
||||||
try{
|
|
||||||
String[] vt = queryParameters.get(key);
|
|
||||||
if( vt == null || vt.length ==0 || vt[0] == null)
|
|
||||||
out = null;
|
|
||||||
else
|
|
||||||
out = Integer.parseInt(vt[0]);
|
|
||||||
}catch(IndexOutOfBoundsException iex){
|
|
||||||
out = null;
|
|
||||||
}catch(NumberFormatException nfe){
|
|
||||||
out = null;
|
|
||||||
}catch(NullPointerException npe){
|
|
||||||
out = null;
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VitroVocabulary.Precision getRequiredMinimumPrecision() {
|
|
||||||
return minimumPrecision;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequiredMinimumPrecision(
|
|
||||||
VitroVocabulary.Precision requiredMinimumPrecision) {
|
|
||||||
this.minimumPrecision = requiredMinimumPrecision;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns null if it cannot convert */
|
|
||||||
public static VitroVocabulary.Precision toPrecision(String precisionUri){
|
|
||||||
for( VitroVocabulary.Precision precision : VitroVocabulary.Precision.values()){
|
|
||||||
if( precision.uri().equals(precisionUri))
|
|
||||||
return precision;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValueVariableName(){ return fieldName + "-value" ; }
|
|
||||||
public String getPrecisionVariableName(){ return fieldName + "-precision" ; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -15,9 +15,6 @@ import com.hp.hpl.jena.rdf.model.Literal;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.Precision;
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.Precision;
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.elements.DateTimeWithPrecision;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditSubmission;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Assumption for date time interval validation: Only one start field/end field/and precision.
|
* Assumption for date time interval validation: Only one start field/end field/and precision.
|
||||||
|
@ -133,7 +130,7 @@ public class DateTimeIntervalValidationVTwo implements N3ValidatorVTwo {
|
||||||
//Currently checks first precision str and then returns response
|
//Currently checks first precision str and then returns response
|
||||||
if(precisionStr.size() > 0) {
|
if(precisionStr.size() > 0) {
|
||||||
String precisionString = precisionStr.get(0);
|
String precisionString = precisionStr.get(0);
|
||||||
VitroVocabulary.Precision precision = DateTimeWithPrecision.toPrecision( precisionString );
|
VitroVocabulary.Precision precision = DateTimeWithPrecisionVTwo.toPrecision( precisionString );
|
||||||
if( precision == null )
|
if( precision == null )
|
||||||
log.debug("cannot convert " + precisionStr + " to a precision");
|
log.debug("cannot convert " + precisionStr + " to a precision");
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,154 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.validators;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.datatypes.xsd.XSDDateTime;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Literal;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.Precision;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.elements.DateTimeWithPrecision;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditSubmission;
|
|
||||||
|
|
||||||
public class DateTimeIntervalValidation implements N3Validator {
|
|
||||||
private static Log log = LogFactory.getLog(DateTimeIntervalValidation.class);
|
|
||||||
|
|
||||||
private String startFieldName;
|
|
||||||
private String endFieldName;
|
|
||||||
|
|
||||||
private String startValueName;
|
|
||||||
private String endValueName;
|
|
||||||
|
|
||||||
private String startPrecisionName;
|
|
||||||
private String endPrecisionName;
|
|
||||||
|
|
||||||
public DateTimeIntervalValidation(String startFieldName, String endFieldName){
|
|
||||||
this.startFieldName = startFieldName;
|
|
||||||
this.endFieldName = endFieldName;
|
|
||||||
startValueName = startFieldName + "-value";
|
|
||||||
endValueName = endFieldName + "-value";
|
|
||||||
startPrecisionName = startFieldName + "-precision";
|
|
||||||
endPrecisionName = endFieldName + "-precision";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> validate(EditConfiguration editConfig,
|
|
||||||
EditSubmission editSub) {
|
|
||||||
Map<String, Literal> existingLiterals = editConfig.getLiteralsInScope();
|
|
||||||
Literal existingStartYear = existingLiterals.get(startValueName);
|
|
||||||
Literal existingEndYear = existingLiterals.get(endValueName);
|
|
||||||
|
|
||||||
Map<String, Literal> literalsFromForm = editSub.getLiteralsFromForm();
|
|
||||||
Literal formStartYear = literalsFromForm.get(startValueName);
|
|
||||||
Literal formEndYear = literalsFromForm.get(endValueName);
|
|
||||||
|
|
||||||
VitroVocabulary.Precision startPrecision = getPrecision(startPrecisionName, editConfig, editSub);
|
|
||||||
VitroVocabulary.Precision endPrecision = getPrecision(endPrecisionName, editConfig, editSub);
|
|
||||||
|
|
||||||
Map<String, String> errors = new HashMap<String, String>();
|
|
||||||
|
|
||||||
// NIHVIVO-2541 Commented out to allow end date with no start date
|
|
||||||
// if( formStartYear == null && formEndYear != null ){
|
|
||||||
// errors.put(startFieldName, "If there is an end date, there should be a start date");
|
|
||||||
// return errors;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (formStartYear != null && formEndYear != null) {
|
|
||||||
errors.putAll(checkDateLiterals(formStartYear, formEndYear, startPrecision, endPrecision));
|
|
||||||
} else if (formStartYear != null && existingEndYear != null) {
|
|
||||||
errors.putAll(checkDateLiterals(formStartYear, existingEndYear, startPrecision, endPrecision));
|
|
||||||
} else if (existingStartYear != null && formEndYear != null) {
|
|
||||||
errors.putAll(checkDateLiterals(existingStartYear, formEndYear, startPrecision, endPrecision));
|
|
||||||
} else if (existingStartYear != null && existingEndYear != null) {
|
|
||||||
errors.putAll(checkDateLiterals(existingStartYear, existingEndYear, startPrecision, endPrecision));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errors.size() != 0)
|
|
||||||
return errors;
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Precision getPrecision(String precisionVarName,
|
|
||||||
EditConfiguration editConfig, EditSubmission editSub) {
|
|
||||||
if( editSub != null
|
|
||||||
&& editSub.getUrisFromForm() != null
|
|
||||||
&& editSub.getUrisFromForm().containsKey(precisionVarName)){
|
|
||||||
String precisionStr = editSub.getUrisFromForm().get(precisionVarName);
|
|
||||||
VitroVocabulary.Precision precision = DateTimeWithPrecision.toPrecision( precisionStr );
|
|
||||||
if( precision == null )
|
|
||||||
log.warn("cannot convert " + precisionStr + " to a precision");
|
|
||||||
else
|
|
||||||
return precision;
|
|
||||||
}else if( editConfig != null
|
|
||||||
&& editConfig.getUrisInScope() != null
|
|
||||||
&& editConfig.getUrisInScope().containsKey(precisionVarName)){
|
|
||||||
String precisionStr = editConfig.getUrisInScope().get(precisionVarName);
|
|
||||||
VitroVocabulary.Precision precision = DateTimeWithPrecision.toPrecision( precisionStr );
|
|
||||||
if( precision == null )
|
|
||||||
log.warn("cannot convert " + precisionStr + " to a precision");
|
|
||||||
else
|
|
||||||
return precision;
|
|
||||||
}
|
|
||||||
//this is what is returned if a precision was not found in the config or submission
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> checkDateLiterals(
|
|
||||||
Literal startLit, Literal endLit,
|
|
||||||
VitroVocabulary.Precision startPrecision, VitroVocabulary.Precision endPrecision) {
|
|
||||||
Map<String, String> errors = new HashMap<String, String>();
|
|
||||||
|
|
||||||
if( endPrecision == null ){
|
|
||||||
//there is no end date, nothing to check
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
try{
|
|
||||||
XSDDateTime startDate = (XSDDateTime)startLit.getValue();
|
|
||||||
XSDDateTime endDate = (XSDDateTime)endLit.getValue();
|
|
||||||
if( startDate != null && endDate!= null ){
|
|
||||||
Calendar startCal = startDate.asCalendar();
|
|
||||||
Calendar endCal = endDate.asCalendar();
|
|
||||||
|
|
||||||
if( endCal != null ){
|
|
||||||
if( !startCal.before( endCal ) ){
|
|
||||||
if( startPrecision == VitroVocabulary.Precision.YEAR
|
|
||||||
&& endPrecision == VitroVocabulary.Precision.YEAR ){
|
|
||||||
errors.putAll( checkYears(startCal,endCal));
|
|
||||||
}else{
|
|
||||||
errors.put(startFieldName, "Start must be before end");
|
|
||||||
errors.put(endFieldName, "End must be after start");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}catch(ClassCastException cce){
|
|
||||||
errors.put(startFieldName, "could not format start or end date");
|
|
||||||
errors.put(endFieldName, "could not format start or end date");
|
|
||||||
log.debug("could not format dates " + cce);
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<? extends String, ? extends String> checkYears(
|
|
||||||
Calendar startCal, Calendar endCal) {
|
|
||||||
|
|
||||||
Map<String, String> errors = new HashMap<String, String>();
|
|
||||||
|
|
||||||
if( ! (endCal.get(Calendar.YEAR) >= startCal.get(Calendar.YEAR) )){
|
|
||||||
errors.put(startFieldName, "Start must be before end");
|
|
||||||
errors.put(endFieldName, "End must be after start");
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,251 @@
|
||||||
|
/* $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.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
import javax.servlet.ServletContextListener;
|
||||||
|
|
||||||
|
import org.apache.commons.dbcp.BasicDataSource;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.joda.time.format.ISODateTimeFormat;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.ontology.OntDocumentManager;
|
||||||
|
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.rdf.model.Model;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setups the Application Configuration TBox and ABox. This is sometimes
|
||||||
|
* called the display model.
|
||||||
|
*
|
||||||
|
* @author bdc34
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ApplicationModelSetup extends JenaDataSourceSetupBase
|
||||||
|
implements ServletContextListener {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(
|
||||||
|
ApplicationModelSetup.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the application configuration model. It is frequently called the
|
||||||
|
* display model. If this is a new DB, populate the display model with the
|
||||||
|
* initial data.
|
||||||
|
*
|
||||||
|
* Also load any files that get loaded to the display model at each tomcat
|
||||||
|
* startup.
|
||||||
|
*
|
||||||
|
* Also, at each start of tomcat, load The display TBox and the
|
||||||
|
* display/display model.
|
||||||
|
*/
|
||||||
|
private void setupDisplayModel(BasicDataSource bds, ServletContext ctx,
|
||||||
|
StartupStatus ss) {
|
||||||
|
|
||||||
|
// display, editing and navigation Model
|
||||||
|
try {
|
||||||
|
Model displayDbModel = makeDBModel(bds,
|
||||||
|
JENA_DISPLAY_METADATA_MODEL, DB_ONT_MODEL_SPEC, ctx);
|
||||||
|
if (displayDbModel.size() == 0) {
|
||||||
|
readOntologyFilesInPathSet(APPPATH, ctx,displayDbModel);
|
||||||
|
}
|
||||||
|
OntModel displayModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
|
||||||
|
displayModel.add(displayDbModel);
|
||||||
|
displayModel.getBaseModel().register(new ModelSynchronizer(displayDbModel));
|
||||||
|
ctx.setAttribute(DISPLAY_ONT_MODEL, displayModel);
|
||||||
|
|
||||||
|
//at each startup load all RDF files from directory to sub-models of display model
|
||||||
|
initializeDisplayLoadedAtStartup(ctx, displayModel);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log.error("Unable to load user application configuration model", t);
|
||||||
|
ss.fatal(this, "Unable to load user application configuration model", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
//display tbox - currently reading in every time
|
||||||
|
try {
|
||||||
|
Model displayTboxModel = makeDBModel(bds,
|
||||||
|
JENA_DISPLAY_TBOX_MODEL, DB_ONT_MODEL_SPEC, ctx);
|
||||||
|
|
||||||
|
//Reading in single file every time, needs to be cleared/removed every time
|
||||||
|
readOntologyFileFromPath(APPPATH_LOAD + "displayTBOX.n3", displayTboxModel, ctx);
|
||||||
|
OntModel appTBOXModel = ModelFactory.createOntologyModel(
|
||||||
|
MEM_ONT_MODEL_SPEC);
|
||||||
|
appTBOXModel.add(displayTboxModel);
|
||||||
|
appTBOXModel.getBaseModel().register(new ModelSynchronizer(displayTboxModel));
|
||||||
|
ctx.setAttribute("displayOntModelTBOX", 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);
|
||||||
|
ss.fatal(this, "Unable to load user application configuration model TBOX", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Display Display model, currently empty, create if doesn't exist but no files to load
|
||||||
|
try {
|
||||||
|
Model displayDisplayModel = makeDBModel(bds,
|
||||||
|
JENA_DISPLAY_DISPLAY_MODEL, DB_ONT_MODEL_SPEC, ctx);
|
||||||
|
|
||||||
|
//Reading in single file every time, needs to be cleared/removed every
|
||||||
|
readOntologyFileFromPath(APPPATH_LOAD + "displayDisplay.n3", displayDisplayModel, ctx);
|
||||||
|
OntModel appDisplayDisplayModel = ModelFactory.createOntologyModel(
|
||||||
|
MEM_ONT_MODEL_SPEC);
|
||||||
|
appDisplayDisplayModel.add(displayDisplayModel);
|
||||||
|
appDisplayDisplayModel.getBaseModel().register(new ModelSynchronizer(displayDisplayModel));
|
||||||
|
ctx.setAttribute("displayOntModelDisplayModel", 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);
|
||||||
|
ss.fatal(this, "Unable to load user application configuration model Display Model", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the RDF found in the directory DISPLAY_MODEL_LOAD_AT_STARTUP_DIR
|
||||||
|
* a sub-models of displayModel. The RDF from thes files will not be saved
|
||||||
|
* in the database and it will be reloaded each time the system starts up.
|
||||||
|
*/
|
||||||
|
private void initializeDisplayLoadedAtStartup(ServletContext ctx, OntModel displayModel){
|
||||||
|
log.info("loading display model from files in " + ctx.getRealPath(DISPLAY_MODEL_LOAD_AT_STARTUP_DIR) );
|
||||||
|
Model displayLoadAtStartup = readInDisplayModelLoadAtStartup(ctx);
|
||||||
|
|
||||||
|
if( log.isDebugEnabled() ){
|
||||||
|
log.debug("loaded display model from files in " + ctx.getRealPath(DISPLAY_MODEL_LOAD_AT_STARTUP_DIR) );
|
||||||
|
displayLoadAtStartup.write(System.out, "N3-PP");
|
||||||
|
}
|
||||||
|
|
||||||
|
checkForOldListViews(ctx,displayModel,displayLoadAtStartup);
|
||||||
|
displayModel.addSubModel( displayLoadAtStartup );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Model readInDisplayModelLoadAtStartup( ServletContext ctx ){
|
||||||
|
return getModelFromDir( new File( ctx.getRealPath( DISPLAY_MODEL_LOAD_AT_STARTUP_DIR )));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All of the list views should now reside in files in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR.
|
||||||
|
* This will check for custom list view annotation statements in the displayModel, check
|
||||||
|
* if they exist in the files in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR, and write any that don't
|
||||||
|
* exist there to a file in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR. After that the statements
|
||||||
|
* will be removed from the displayDBModel.
|
||||||
|
*
|
||||||
|
* returns true if there were old list view statements in the DB, returns false
|
||||||
|
* if there were none. displayLoadAlways should be reloaded from the file system
|
||||||
|
* if this returns true as this method may have changed the files.
|
||||||
|
*
|
||||||
|
* displayLoadAtStartup and displayModel may be modified.
|
||||||
|
*/
|
||||||
|
private void checkForOldListViews( ServletContext ctx, OntModel displayModel, Model displayLoadAtStartup){
|
||||||
|
// run construct for old custom list view statements from displayModel
|
||||||
|
Model oldListViewModel = getOldListViewStatements( displayModel );
|
||||||
|
if( log.isDebugEnabled() ){
|
||||||
|
log.debug("Printing the old list view statements from the display model to System.out.");
|
||||||
|
oldListViewModel.write(System.out,"N3-PP");
|
||||||
|
}
|
||||||
|
|
||||||
|
// find statements in old stmts that are not in loadedAtStartup and
|
||||||
|
// save them in a new file in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR
|
||||||
|
// so that in the future they will be in loadedAtStartup
|
||||||
|
Model stmtsInOldAndFiles = displayLoadAtStartup.intersection( displayModel );
|
||||||
|
Model unhandledOldListViewStmts = oldListViewModel.difference( stmtsInOldAndFiles );
|
||||||
|
|
||||||
|
boolean saved = false;
|
||||||
|
boolean neededSave = false;
|
||||||
|
|
||||||
|
if( unhandledOldListViewStmts != null && !unhandledOldListViewStmts.isEmpty() ){
|
||||||
|
log.debug("need to deal with old list view statements from the display model");
|
||||||
|
neededSave = true;
|
||||||
|
try{
|
||||||
|
//create a file for the old statements in the loadAtStartup directory
|
||||||
|
String newFileName = ctx.getRealPath(
|
||||||
|
DISPLAY_MODEL_LOAD_AT_STARTUP_DIR + File.separator
|
||||||
|
+ new DateTime().toString(ISODateTimeFormat.basicDateTime()) + ".n3" );
|
||||||
|
File file = new File( newFileName );
|
||||||
|
file.createNewFile();
|
||||||
|
|
||||||
|
log.info("Relocating " + unhandledOldListViewStmts.size() + " custom list view statements from DB and saving to "
|
||||||
|
+ file.getAbsolutePath()+ File.separator + file.getName()
|
||||||
|
+ ". These will be loaded from this file when the system starts up.");
|
||||||
|
|
||||||
|
FileOutputStream fileOut = new FileOutputStream(file);
|
||||||
|
unhandledOldListViewStmts.write(fileOut, "N3-PP");
|
||||||
|
fileOut.close();
|
||||||
|
saved = true;
|
||||||
|
}catch(Throwable th){
|
||||||
|
log.warn("Could not save old list view statements. Leaving them in the DB",th);
|
||||||
|
}
|
||||||
|
|
||||||
|
//need to reload displayLoadAlways because DISPLAY_MODEL_LOAD_AT_STARTUP_DIR may have changed
|
||||||
|
displayLoadAtStartup.removeAll().add(readInDisplayModelLoadAtStartup(ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( oldListViewModel != null && ! oldListViewModel.isEmpty() ){
|
||||||
|
//At this point, there are old list view statements in the DB but they
|
||||||
|
//should are all redundant with ones in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR
|
||||||
|
if( (neededSave && saved) || (!neededSave) ){
|
||||||
|
//if there was nothing to save, just remove the old stuff
|
||||||
|
//if there was stuff to save, only remove if it was saved.
|
||||||
|
log.debug("removing old statements from displayModel");
|
||||||
|
displayModel.remove(oldListViewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Model getOldListViewStatements(OntModel displayModel) {
|
||||||
|
//run a construct on displayModel to get all list view statements
|
||||||
|
Query query = QueryFactory.create ( listViewQuery );
|
||||||
|
QueryExecution qexec = QueryExecutionFactory.create(query, displayModel) ;
|
||||||
|
Model oldModel = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
oldModel = qexec.execConstruct();
|
||||||
|
} catch( Throwable th ){
|
||||||
|
log.error("could not check for old custom list views, query exception",th);
|
||||||
|
}finally {
|
||||||
|
qexec.close() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( oldModel != null)
|
||||||
|
return oldModel;
|
||||||
|
else
|
||||||
|
return ModelFactory.createDefaultModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String listViewQuery = "" +
|
||||||
|
"PREFIX d: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#>\n" +
|
||||||
|
"CONSTRUCT { \n" +
|
||||||
|
" ?a d:listViewConfigFile ?b . \n" +
|
||||||
|
"} WHERE {\n" +
|
||||||
|
" ?a d:listViewConfigFile ?b . \n" +
|
||||||
|
"} ";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent arg0) {
|
||||||
|
// does nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
ServletContext ctx = sce.getServletContext();
|
||||||
|
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||||
|
BasicDataSource bds = getApplicationDataSource(ctx);
|
||||||
|
|
||||||
|
setupDisplayModel(bds, ctx, ss);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,674 +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.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.ServletContextEvent;
|
|
||||||
|
|
||||||
import org.apache.commons.dbcp.BasicDataSource;
|
|
||||||
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.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.Syntax;
|
|
||||||
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.rdf.model.StmtIterator;
|
|
||||||
import com.hp.hpl.jena.sdb.SDB;
|
|
||||||
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 com.hp.hpl.jena.sdb.store.DatabaseType;
|
|
||||||
import com.hp.hpl.jena.sdb.store.LayoutType;
|
|
||||||
import com.hp.hpl.jena.sdb.util.StoreUtils;
|
|
||||||
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.config.ConfigurationProperties;
|
|
||||||
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.JenaModelUtils;
|
|
||||||
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.VitroJenaModelMaker;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSDBModelMaker;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.InitialJenaModelUtils;
|
|
||||||
|
|
||||||
public class JenaDataSourceSetup extends JenaDataSourceSetupBase
|
|
||||||
implements javax.servlet.ServletContextListener {
|
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(JenaDataSourceSetup.class);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void contextInitialized(ServletContextEvent sce) {
|
|
||||||
ServletContext ctx = sce.getServletContext();
|
|
||||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
|
||||||
|
|
||||||
try {
|
|
||||||
long startTime = System.currentTimeMillis();
|
|
||||||
setUpJenaDataSource(ctx);
|
|
||||||
log.info((System.currentTimeMillis() - startTime) / 1000 +
|
|
||||||
" seconds to set up SDB store");
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
// SQL exceptions are fatal and should halt startup
|
|
||||||
log.error("Error using SQL database; startup aborted.", sqle);
|
|
||||||
ss.fatal(this, "Error using SQL database; startup aborted.", sqle);
|
|
||||||
} 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) throws SQLException {
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// SDB setup
|
|
||||||
|
|
||||||
// union default graph
|
|
||||||
SDB.getContext().set(SDB.unionDefaultGraph, true) ;
|
|
||||||
|
|
||||||
StoreDesc storeDesc = makeStoreDesc(ctx);
|
|
||||||
setApplicationStoreDesc(storeDesc, ctx);
|
|
||||||
|
|
||||||
BasicDataSource bds = getApplicationDataSource(ctx);
|
|
||||||
if (bds == null) {
|
|
||||||
bds = makeDataSourceFromConfigurationProperties(ctx);
|
|
||||||
setApplicationDataSource(bds, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
Store store = connectStore(bds, storeDesc);
|
|
||||||
setApplicationStore(store, ctx);
|
|
||||||
|
|
||||||
if (!isSetUp(store)) {
|
|
||||||
log.info("Initializing SDB store");
|
|
||||||
if (isFirstStartup()) {
|
|
||||||
setupSDB(ctx, store);
|
|
||||||
} else {
|
|
||||||
migrateToSDBFromExistingRDBStore(ctx, store);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The code below, which sets up the OntModelSelectors, controls whether
|
|
||||||
// each model is maintained in memory, in the DB, or both while the
|
|
||||||
// application is running.
|
|
||||||
|
|
||||||
// Populate the three OntModelSelectors (BaseOntModel = assertions,
|
|
||||||
// InferenceOntModel = inferences and JenaOntModel = union of assertions
|
|
||||||
// and inferences) with the post-SDB-conversion models.
|
|
||||||
|
|
||||||
// ABox assertions
|
|
||||||
Model aboxAssertions = makeDBModel(
|
|
||||||
bds, JenaDataSourceSetupBase.JENA_DB_MODEL, DB_ONT_MODEL_SPEC,
|
|
||||||
TripleStoreType.SDB, ctx);
|
|
||||||
Model listenableAboxAssertions = ModelFactory.createUnion(
|
|
||||||
aboxAssertions, ModelFactory.createDefaultModel());
|
|
||||||
baseOms.setABoxModel(
|
|
||||||
ModelFactory.createOntologyModel(
|
|
||||||
OntModelSpec.OWL_MEM, listenableAboxAssertions));
|
|
||||||
|
|
||||||
// ABox inferences
|
|
||||||
Model aboxInferences = makeDBModel(
|
|
||||||
bds, JenaDataSourceSetupBase.JENA_INF_MODEL, DB_ONT_MODEL_SPEC,
|
|
||||||
TripleStoreType.SDB, ctx);
|
|
||||||
Model listenableAboxInferences = ModelFactory.createUnion(
|
|
||||||
aboxInferences, ModelFactory.createDefaultModel());
|
|
||||||
inferenceOms.setABoxModel(ModelFactory.createOntologyModel(
|
|
||||||
OntModelSpec.OWL_MEM, listenableAboxInferences));
|
|
||||||
|
|
||||||
|
|
||||||
// Since the TBox models are in memory, they do not have timeout issues
|
|
||||||
// like the like the ABox models do (and so don't need the extra step
|
|
||||||
// to make them listenable.)
|
|
||||||
|
|
||||||
// TBox assertions
|
|
||||||
try {
|
|
||||||
Model tboxAssertionsDB = makeDBModel(
|
|
||||||
bds, JENA_TBOX_ASSERTIONS_MODEL, DB_ONT_MODEL_SPEC,
|
|
||||||
TripleStoreType.SDB, ctx);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TBox inferences
|
|
||||||
try {
|
|
||||||
Model tboxInferencesDB = makeDBModel(
|
|
||||||
bds, JENA_TBOX_INF_MODEL, DB_ONT_MODEL_SPEC,
|
|
||||||
TripleStoreType.SDB, ctx);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// union ABox
|
|
||||||
OntModel unionABoxModel = ModelFactory.createOntologyModel(
|
|
||||||
MEM_ONT_MODEL_SPEC,ModelFactory.createUnion(
|
|
||||||
baseOms.getABoxModel(), inferenceOms.getABoxModel()));
|
|
||||||
unionOms.setABoxModel(unionABoxModel);
|
|
||||||
|
|
||||||
// union TBox
|
|
||||||
OntModel unionTBoxModel = ModelFactory.createOntologyModel(
|
|
||||||
MEM_ONT_MODEL_SPEC,ModelFactory.createUnion(
|
|
||||||
baseOms.getTBoxModel(), inferenceOms.getTBoxModel()));
|
|
||||||
unionOms.setTBoxModel(unionTBoxModel);
|
|
||||||
|
|
||||||
|
|
||||||
// Application metadata model is cached in memory.
|
|
||||||
try {
|
|
||||||
|
|
||||||
Model applicationMetadataModelDB = makeDBModel(
|
|
||||||
bds, JENA_APPLICATION_METADATA_MODEL, DB_ONT_MODEL_SPEC,
|
|
||||||
TripleStoreType.SDB, ctx);
|
|
||||||
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 (isFirstStartup()) {
|
|
||||||
applicationMetadataModel.add(
|
|
||||||
InitialJenaModelUtils.loadInitialModel(
|
|
||||||
ctx, getDefaultNamespace(ctx)));
|
|
||||||
|
|
||||||
} else if (applicationMetadataModelDB.size() == 0) {
|
|
||||||
repairAppMetadataModel(
|
|
||||||
applicationMetadataModel, aboxAssertions,
|
|
||||||
aboxInferences);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
OntModel baseUnion = ModelFactory.createOntologyModel(
|
|
||||||
OntModelSpec.OWL_MEM,
|
|
||||||
ModelFactory.createUnion(baseOms.getABoxModel(),
|
|
||||||
baseOms.getTBoxModel()));
|
|
||||||
baseOms.setFullModel(baseUnion);
|
|
||||||
ModelContext.setBaseOntModel(baseOms.getFullModel(), ctx);
|
|
||||||
WebappDaoFactoryConfig config = new WebappDaoFactoryConfig();
|
|
||||||
config.setDefaultNamespace(getDefaultNamespace(ctx));
|
|
||||||
WebappDaoFactory baseWadf = new WebappDaoFactorySDB(
|
|
||||||
baseOms, bds, storeDesc, 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(
|
|
||||||
inferenceOms, bds, storeDesc, config,
|
|
||||||
WebappDaoFactorySDB.SDBDatasetMode.INFERENCES_ONLY);
|
|
||||||
ctx.setAttribute("deductionsWebappDaoFactory", infWadf);
|
|
||||||
|
|
||||||
OntModel masterUnion = ModelFactory.createOntologyModel(
|
|
||||||
DB_ONT_MODEL_SPEC, makeDBModel(
|
|
||||||
bds, WebappDaoFactorySDB.UNION_GRAPH,
|
|
||||||
DB_ONT_MODEL_SPEC, TripleStoreType.SDB, ctx));
|
|
||||||
unionOms.setFullModel(masterUnion);
|
|
||||||
ctx.setAttribute("jenaOntModel", masterUnion);
|
|
||||||
WebappDaoFactory wadf = new WebappDaoFactorySDB(
|
|
||||||
unionOms, bds, storeDesc, 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));
|
|
||||||
|
|
||||||
log.info("SDB store ready for use");
|
|
||||||
|
|
||||||
makeModelMakerFromConnectionProperties(TripleStoreType.RDB, ctx);
|
|
||||||
VitroJenaModelMaker vjmm = getVitroJenaModelMaker();
|
|
||||||
setVitroJenaModelMaker(vjmm, ctx);
|
|
||||||
makeModelMakerFromConnectionProperties(TripleStoreType.SDB, ctx);
|
|
||||||
VitroJenaSDBModelMaker vsmm = getVitroJenaSDBModelMaker();
|
|
||||||
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<Resource> 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<Resource> getPortal1s(Model model) {
|
|
||||||
List<Resource> portals = new ArrayList<Resource>();
|
|
||||||
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<Resource> 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 OntModel ontModelFromContextAttribute(ServletContext ctx,
|
|
||||||
String attribute) {
|
|
||||||
OntModel ontModel;
|
|
||||||
Object attributeValue = ctx.getAttribute(attribute);
|
|
||||||
if (attributeValue != null && attributeValue instanceof OntModel) {
|
|
||||||
ontModel = (OntModel) attributeValue;
|
|
||||||
} else {
|
|
||||||
ontModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
|
|
||||||
ctx.setAttribute(attribute, ontModel);
|
|
||||||
}
|
|
||||||
return ontModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isEmpty(Model model) {
|
|
||||||
ClosableIterator<Statement> 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.debug("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 ");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void getTBoxModel(Model fullModel,
|
|
||||||
Model submodels,
|
|
||||||
Model tboxModel) {
|
|
||||||
|
|
||||||
JenaModelUtils modelUtils = new JenaModelUtils();
|
|
||||||
|
|
||||||
Model tempModel = ModelFactory.createUnion(fullModel, submodels);
|
|
||||||
Model tempTBoxModel = modelUtils.extractTBox(tempModel);
|
|
||||||
|
|
||||||
// copy intersection of tempTBoxModel and fullModel to tboxModel.
|
|
||||||
StmtIterator iter = tempTBoxModel.listStatements();
|
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
Statement stmt = iter.next();
|
|
||||||
if (fullModel.contains(stmt)) {
|
|
||||||
tboxModel.add(stmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy all statements from model 1 that are not in model 2 to model 3.
|
|
||||||
*/
|
|
||||||
private static void copyDifference(Model model1,
|
|
||||||
Model model2,
|
|
||||||
Model model3) {
|
|
||||||
|
|
||||||
StmtIterator iter = model1.listStatements();
|
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
Statement stmt = iter.next();
|
|
||||||
if (!model2.contains(stmt)) {
|
|
||||||
model3.add(stmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void getAppMetadata(Model source, Model target) {
|
|
||||||
|
|
||||||
String amdQuery = "DESCRIBE ?x WHERE { " +
|
|
||||||
"{?x a <" + VitroVocabulary.PORTAL +"> } UNION " +
|
|
||||||
"{?x a <" + VitroVocabulary.PROPERTYGROUP +"> } UNION " +
|
|
||||||
"{?x a <" + VitroVocabulary.CLASSGROUP +"> } } ";
|
|
||||||
|
|
||||||
try {
|
|
||||||
Query q = QueryFactory.create(amdQuery, Syntax.syntaxARQ);
|
|
||||||
QueryExecution qe = QueryExecutionFactory.create(q, source);
|
|
||||||
qe.execDescribe(target);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("unable to create the application metadata model",e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void repairAppMetadataModel(Model applicationMetadataModel,
|
|
||||||
Model aboxAssertions,
|
|
||||||
Model aboxInferences) {
|
|
||||||
|
|
||||||
log.info("Moving application metadata from ABox to dedicated model");
|
|
||||||
getAppMetadata(aboxAssertions, applicationMetadataModel);
|
|
||||||
getAppMetadata(aboxInferences, applicationMetadataModel);
|
|
||||||
aboxAssertions.remove(applicationMetadataModel);
|
|
||||||
aboxInferences.remove(applicationMetadataModel);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static StoreDesc makeStoreDesc(ServletContext ctx) {
|
|
||||||
String layoutStr = ConfigurationProperties.getBean(ctx).getProperty(
|
|
||||||
"VitroConnection.DataSource.sdb.layout", "layout2/hash");
|
|
||||||
String dbtypeStr = ConfigurationProperties.getBean(ctx).getProperty(
|
|
||||||
"VitroConnection.DataSource.dbtype", "MySQL");
|
|
||||||
return new StoreDesc(
|
|
||||||
LayoutType.fetch(layoutStr),
|
|
||||||
DatabaseType.fetch(dbtypeStr) );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Store connectStore(BasicDataSource bds, StoreDesc storeDesc)
|
|
||||||
throws SQLException {
|
|
||||||
SDBConnection conn = new SDBConnection(bds.getConnection()) ;
|
|
||||||
return SDBFactory.connectStore(conn, storeDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setupSDB(ServletContext ctx, Store store) {
|
|
||||||
setupSDB(ctx,
|
|
||||||
store,
|
|
||||||
ModelFactory.createDefaultModel(),
|
|
||||||
ModelFactory.createDefaultModel());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setupSDB(ServletContext ctx,
|
|
||||||
Store store,
|
|
||||||
Model memModel,
|
|
||||||
Model inferenceModel) {
|
|
||||||
|
|
||||||
store.getTableFormatter().create();
|
|
||||||
store.getTableFormatter().truncate();
|
|
||||||
|
|
||||||
store.getTableFormatter().dropIndexes(); // improve load performance
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
// This is a one-time copy of stored KB data - from a Jena RDB store
|
|
||||||
// to a Jena SDB store. In the process, we will also separate out
|
|
||||||
// the TBox from the Abox; these are in the same graph in pre-1.2
|
|
||||||
// VIVO versions and will now be stored and maintained in separate
|
|
||||||
// models. Access to the Jena RDB data is through the
|
|
||||||
// OntModelSelectors that have been set up earlier in the current
|
|
||||||
// session by JenaPersistentDataSourceSetup.java. In the code
|
|
||||||
// below, note that the current getABoxModel() methods on the
|
|
||||||
// OntModelSelectors return a graph with both ABox and TBox data.
|
|
||||||
|
|
||||||
OntModel submodels = ModelFactory.createOntologyModel(
|
|
||||||
MEM_ONT_MODEL_SPEC);
|
|
||||||
readOntologyFilesInPathSet(SUBMODELS, ctx, submodels);
|
|
||||||
|
|
||||||
Model tboxAssertions = SDBFactory.connectNamedModel(
|
|
||||||
store, JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL);
|
|
||||||
// initially putting the results in memory so we have a
|
|
||||||
// cheaper way of computing the difference when we copy the ABox
|
|
||||||
Model memTboxAssertions = ModelFactory.createDefaultModel();
|
|
||||||
getTBoxModel(memModel, submodels, memTboxAssertions);
|
|
||||||
tboxAssertions.add(memTboxAssertions);
|
|
||||||
|
|
||||||
Model tboxInferences = SDBFactory.connectNamedModel(
|
|
||||||
store, JenaDataSourceSetupBase.JENA_TBOX_INF_MODEL);
|
|
||||||
// initially putting the results in memory so we have a
|
|
||||||
// cheaper way of computing the difference when we copy the ABox
|
|
||||||
Model memTboxInferences = ModelFactory.createDefaultModel();
|
|
||||||
getTBoxModel(inferenceModel, submodels, memTboxInferences);
|
|
||||||
tboxInferences.add(memTboxInferences);
|
|
||||||
|
|
||||||
Model aboxAssertions = SDBFactory.connectNamedModel(
|
|
||||||
store, JenaDataSourceSetupBase.JENA_DB_MODEL);
|
|
||||||
copyDifference(memModel, memTboxAssertions, aboxAssertions);
|
|
||||||
|
|
||||||
Model aboxInferences = SDBFactory.connectNamedModel(
|
|
||||||
store, JenaDataSourceSetupBase.JENA_INF_MODEL);
|
|
||||||
copyDifference(inferenceModel, memTboxInferences, aboxInferences);
|
|
||||||
|
|
||||||
// Set up the application metadata model
|
|
||||||
Model applicationMetadataModel = SDBFactory.connectNamedModel(
|
|
||||||
store,
|
|
||||||
JenaDataSourceSetupBase.JENA_APPLICATION_METADATA_MODEL);
|
|
||||||
getAppMetadata(memModel, applicationMetadataModel);
|
|
||||||
log.info("During initial SDB setup, created an application " +
|
|
||||||
"metadata model of size " +
|
|
||||||
applicationMetadataModel.size());
|
|
||||||
|
|
||||||
// remove application metadata from ABox model
|
|
||||||
aboxAssertions.remove(applicationMetadataModel);
|
|
||||||
aboxInferences.remove(applicationMetadataModel);
|
|
||||||
|
|
||||||
// Make sure the reasoner takes into account the newly-set-up data.
|
|
||||||
SimpleReasonerSetup.setRecomputeRequired(ctx);
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
log.info("Adding indexes to SDB database tables.");
|
|
||||||
store.getTableFormatter().addIndexes();
|
|
||||||
log.info("Indexes created.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void migrateToSDBFromExistingRDBStore(ServletContext ctx,
|
|
||||||
Store store) {
|
|
||||||
Model rdbAssertionsModel = makeDBModelFromConfigurationProperties(
|
|
||||||
JENA_DB_MODEL, DB_ONT_MODEL_SPEC, ctx);
|
|
||||||
Model rdbInferencesModel = makeDBModelFromConfigurationProperties(
|
|
||||||
JENA_INF_MODEL, DB_ONT_MODEL_SPEC, ctx);
|
|
||||||
setupSDB(ctx, store, rdbAssertionsModel, rdbInferencesModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests whether an SDB store has been formatted and populated for use.
|
|
||||||
* @param store
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private boolean isSetUp(Store store) throws SQLException {
|
|
||||||
if (!(StoreUtils.isFormatted(store))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// even if the store exists, it may be empty
|
|
||||||
|
|
||||||
try {
|
|
||||||
return (SDBFactory.connectNamedModel(
|
|
||||||
store,
|
|
||||||
JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL))
|
|
||||||
.size() > 0;
|
|
||||||
} catch (Exception e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String STOREDESC_ATTR = "storeDesc";
|
|
||||||
private static final String STORE_ATTR = "kbStore";
|
|
||||||
|
|
||||||
public static void setApplicationStoreDesc(StoreDesc storeDesc,
|
|
||||||
ServletContext ctx) {
|
|
||||||
ctx.setAttribute(STOREDESC_ATTR, storeDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static StoreDesc getApplicationStoreDesc(ServletContext ctx) {
|
|
||||||
return (StoreDesc) ctx.getAttribute(STOREDESC_ATTR);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setApplicationStore(Store store,
|
|
||||||
ServletContext ctx) {
|
|
||||||
ctx.setAttribute(STORE_ATTR, store);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Store getApplicationStore(ServletContext ctx) {
|
|
||||||
return (Store) ctx.getAttribute(STORE_ATTR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,14 +18,21 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import com.hp.hpl.jena.graph.Graph;
|
import com.hp.hpl.jena.graph.Graph;
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||||
|
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.Syntax;
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
import com.hp.hpl.jena.sdb.Store;
|
||||||
import com.hp.hpl.jena.sdb.StoreDesc;
|
import com.hp.hpl.jena.sdb.StoreDesc;
|
||||||
import com.hp.hpl.jena.sdb.store.DatabaseType;
|
import com.hp.hpl.jena.sdb.store.DatabaseType;
|
||||||
import com.hp.hpl.jena.sdb.store.LayoutType;
|
import com.hp.hpl.jena.sdb.store.LayoutType;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDaoCon;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDaoCon;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDBGraphGenerator;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDBGraphGenerator;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.RegeneratingGraph;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.RegeneratingGraph;
|
||||||
|
@ -63,7 +70,6 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
|
||||||
protected static String USER_TBOX_PATH = BASE+"user/tbox";
|
protected static String USER_TBOX_PATH = BASE+"user/tbox";
|
||||||
protected static String USER_APPMETA_PATH = BASE+"user/applicationMetadata";
|
protected static String USER_APPMETA_PATH = BASE+"user/applicationMetadata";
|
||||||
protected static String SYSTEMPATH = BASE+"system/";
|
protected static String SYSTEMPATH = BASE+"system/";
|
||||||
protected static String AUTHPATH = BASE+"auth/";
|
|
||||||
public static String APPPATH = BASE+"app/";
|
public static String APPPATH = BASE+"app/";
|
||||||
//these files are loaded everytime the system starts up
|
//these files are loaded everytime the system starts up
|
||||||
public static String APPPATH_LOAD = APPPATH + "menuload/";
|
public static String APPPATH_LOAD = APPPATH + "menuload/";
|
||||||
|
@ -418,7 +424,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
|
||||||
} else if (TripleStoreType.SDB.equals(type)) {
|
} else if (TripleStoreType.SDB.equals(type)) {
|
||||||
StoreDesc storeDesc = new StoreDesc(
|
StoreDesc storeDesc = new StoreDesc(
|
||||||
LayoutType.LayoutTripleNodesHash, DatabaseType.fetch(dbtypeStr));
|
LayoutType.LayoutTripleNodesHash, DatabaseType.fetch(dbtypeStr));
|
||||||
BasicDataSource bds = JenaDataSourceSetup.makeBasicDataSource(
|
BasicDataSource bds = WebappDaoSDBSetup.makeBasicDataSource(
|
||||||
getDbDriverClassName(ctx), jdbcUrl, username, password, ctx);
|
getDbDriverClassName(ctx), jdbcUrl, username, password, ctx);
|
||||||
bds.setMaxActive(4); // for now, the SDB model makers should not use more
|
bds.setMaxActive(4); // for now, the SDB model makers should not use more
|
||||||
// than a small handful of connections
|
// than a small handful of connections
|
||||||
|
@ -524,4 +530,68 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
|
||||||
"VitroConnection.DataSource.validationQuery", "SELECT 1");
|
"VitroConnection.DataSource.validationQuery", "SELECT 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected OntModel ontModelFromContextAttribute(ServletContext ctx,
|
||||||
|
String attribute) {
|
||||||
|
OntModel ontModel;
|
||||||
|
Object attributeValue = ctx.getAttribute(attribute);
|
||||||
|
if (attributeValue != null && attributeValue instanceof OntModel) {
|
||||||
|
ontModel = (OntModel) attributeValue;
|
||||||
|
} else {
|
||||||
|
ontModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
|
||||||
|
ctx.setAttribute(attribute, ontModel);
|
||||||
|
}
|
||||||
|
return ontModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void repairAppMetadataModel(Model applicationMetadataModel,
|
||||||
|
Model aboxAssertions,
|
||||||
|
Model aboxInferences) {
|
||||||
|
|
||||||
|
log.info("Moving application metadata from ABox to dedicated model");
|
||||||
|
getAppMetadata(aboxAssertions, applicationMetadataModel);
|
||||||
|
getAppMetadata(aboxInferences, applicationMetadataModel);
|
||||||
|
aboxAssertions.remove(applicationMetadataModel);
|
||||||
|
aboxInferences.remove(applicationMetadataModel);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void getAppMetadata(Model source, Model target) {
|
||||||
|
|
||||||
|
String amdQuery = "DESCRIBE ?x WHERE { " +
|
||||||
|
"{?x a <" + VitroVocabulary.PORTAL +"> } UNION " +
|
||||||
|
"{?x a <" + VitroVocabulary.PROPERTYGROUP +"> } UNION " +
|
||||||
|
"{?x a <" + VitroVocabulary.CLASSGROUP +"> } } ";
|
||||||
|
|
||||||
|
try {
|
||||||
|
Query q = QueryFactory.create(amdQuery, Syntax.syntaxARQ);
|
||||||
|
QueryExecution qe = QueryExecutionFactory.create(q, source);
|
||||||
|
qe.execDescribe(target);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("unable to create the application metadata model",e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String STOREDESC_ATTR = "storeDesc";
|
||||||
|
private static final String STORE_ATTR = "kbStore";
|
||||||
|
|
||||||
|
public static void setApplicationStoreDesc(StoreDesc storeDesc,
|
||||||
|
ServletContext ctx) {
|
||||||
|
ctx.setAttribute(STOREDESC_ATTR, storeDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StoreDesc getApplicationStoreDesc(ServletContext ctx) {
|
||||||
|
return (StoreDesc) ctx.getAttribute(STOREDESC_ATTR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setApplicationStore(Store store,
|
||||||
|
ServletContext ctx) {
|
||||||
|
ctx.setAttribute(STORE_ATTR, store);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Store getApplicationStore(ServletContext ctx) {
|
||||||
|
return (Store) ctx.getAttribute(STORE_ATTR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,6 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
||||||
|
|
||||||
import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.DISPLAY_ONT_MODEL;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
import javax.servlet.ServletContextListener;
|
import javax.servlet.ServletContextListener;
|
||||||
|
@ -14,21 +9,18 @@ import javax.servlet.ServletContextListener;
|
||||||
import org.apache.commons.dbcp.BasicDataSource;
|
import org.apache.commons.dbcp.BasicDataSource;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.joda.time.format.ISODateTimeFormat;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.ontology.OntDocumentManager;
|
import com.hp.hpl.jena.ontology.OntDocumentManager;
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
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.rdf.model.Model;
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer;
|
||||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create connection to DB and DataSource, put them in the context.
|
||||||
|
*/
|
||||||
public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
|
public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
|
||||||
implements ServletContextListener {
|
implements ServletContextListener {
|
||||||
|
|
||||||
|
@ -45,216 +37,12 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
|
||||||
|
|
||||||
BasicDataSource bds = makeDataSourceFromConfigurationProperties(ctx);
|
BasicDataSource bds = makeDataSourceFromConfigurationProperties(ctx);
|
||||||
setApplicationDataSource(bds, ctx);
|
setApplicationDataSource(bds, ctx);
|
||||||
|
|
||||||
// user accounts Model
|
|
||||||
try {
|
|
||||||
Model userAccountsDbModel = makeDBModel(bds,
|
|
||||||
JENA_USER_ACCOUNTS_MODEL, DB_ONT_MODEL_SPEC, ctx);
|
|
||||||
if (userAccountsDbModel.size() == 0) {
|
|
||||||
firstStartup = true;
|
|
||||||
readOntologyFilesInPathSet(AUTHPATH, ctx,
|
|
||||||
userAccountsDbModel);
|
|
||||||
}
|
|
||||||
OntModel userAccountsModel = ModelFactory.createOntologyModel(
|
|
||||||
MEM_ONT_MODEL_SPEC);
|
|
||||||
userAccountsModel.add(userAccountsDbModel);
|
|
||||||
userAccountsModel.getBaseModel().register(
|
|
||||||
new ModelSynchronizer(userAccountsDbModel));
|
|
||||||
ctx.setAttribute("userAccountsOntModel", userAccountsModel);
|
|
||||||
|
|
||||||
if (userAccountsModel.isEmpty()) {
|
|
||||||
initializeUserAccounts(ctx, userAccountsModel);
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
log.error("Unable to load user accounts model from DB", t);
|
|
||||||
ss.fatal(this, "Unable to load user accounts model from DB", t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// display, editing and navigation Model
|
|
||||||
try {
|
|
||||||
Model displayDbModel = makeDBModel(bds,
|
|
||||||
JENA_DISPLAY_METADATA_MODEL, DB_ONT_MODEL_SPEC, ctx);
|
|
||||||
if (displayDbModel.size() == 0) {
|
|
||||||
readOntologyFilesInPathSet(APPPATH, ctx,displayDbModel);
|
|
||||||
}
|
|
||||||
OntModel displayModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
|
|
||||||
displayModel.add(displayDbModel);
|
|
||||||
displayModel.getBaseModel().register(new ModelSynchronizer(displayDbModel));
|
|
||||||
ctx.setAttribute(DISPLAY_ONT_MODEL, displayModel);
|
|
||||||
|
|
||||||
//at each startup load all RDF files from directory to sub-models of display model
|
|
||||||
initializeDisplayLoadedAtStartup(ctx, displayModel);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
log.error("Unable to load user application configuration model", t);
|
|
||||||
ss.fatal(this, "Unable to load user application configuration model", t);
|
|
||||||
}
|
|
||||||
|
|
||||||
//display tbox - currently reading in every time
|
|
||||||
try {
|
|
||||||
Model displayTboxModel = makeDBModel(bds,
|
|
||||||
JENA_DISPLAY_TBOX_MODEL, DB_ONT_MODEL_SPEC, ctx);
|
|
||||||
//Reading in single file every time
|
|
||||||
//TODO: Check if original needs to be cleared/removed every time?
|
|
||||||
readOntologyFileFromPath(APPPATH_LOAD + "displayTBOX.n3", displayTboxModel, ctx);
|
|
||||||
OntModel appTBOXModel = ModelFactory.createOntologyModel(
|
|
||||||
MEM_ONT_MODEL_SPEC);
|
|
||||||
appTBOXModel.add(displayTboxModel);
|
|
||||||
appTBOXModel.getBaseModel().register(new ModelSynchronizer(displayTboxModel));
|
|
||||||
ctx.setAttribute("displayOntModelTBOX", 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);
|
|
||||||
ss.fatal(this, "Unable to load user application configuration model TBOX", t);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Display Display model, currently empty, create if doesn't exist but no files to load
|
|
||||||
try {
|
|
||||||
Model displayDisplayModel = makeDBModel(bds,
|
|
||||||
JENA_DISPLAY_DISPLAY_MODEL, DB_ONT_MODEL_SPEC, ctx);
|
|
||||||
//Reading in single file every time
|
|
||||||
//TODO: Check if original needs to be cleared/removed every time?
|
|
||||||
readOntologyFileFromPath(APPPATH_LOAD + "displayDisplay.n3", displayDisplayModel, ctx);
|
|
||||||
|
|
||||||
OntModel appDisplayDisplayModel = ModelFactory.createOntologyModel(
|
|
||||||
MEM_ONT_MODEL_SPEC);
|
|
||||||
appDisplayDisplayModel.add(displayDisplayModel);
|
|
||||||
appDisplayDisplayModel.getBaseModel().register(new ModelSynchronizer(displayDisplayModel));
|
|
||||||
ctx.setAttribute("displayOntModelDisplayModel", 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);
|
|
||||||
ss.fatal(this, "Unable to load user application configuration model Display Model", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextDestroyed(ServletContextEvent sce) {
|
public void contextDestroyed(ServletContextEvent sce) {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeUserAccounts(ServletContext ctx,
|
|
||||||
Model userAccountsModel) {
|
|
||||||
readOntologyFilesInPathSet(AUTHPATH, ctx, userAccountsModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the RDF found in the directory DISPLAY_MODEL_LOAD_AT_STARTUP_DIR
|
|
||||||
* a sub-models of displayModel. The RDF from thes files will not be saved
|
|
||||||
* in the database and it will be reloaded each time the system starts up.
|
|
||||||
*/
|
|
||||||
private void initializeDisplayLoadedAtStartup(ServletContext ctx, OntModel displayModel){
|
|
||||||
log.info("loading display model from files in " + ctx.getRealPath(DISPLAY_MODEL_LOAD_AT_STARTUP_DIR) );
|
|
||||||
Model displayLoadAtStartup = readInDisplayModelLoadAtStartup(ctx);
|
|
||||||
|
|
||||||
if( log.isDebugEnabled() ){
|
|
||||||
log.debug("loaded display model from files in " + ctx.getRealPath(DISPLAY_MODEL_LOAD_AT_STARTUP_DIR) );
|
|
||||||
displayLoadAtStartup.write(System.out, "N3-PP");
|
|
||||||
}
|
|
||||||
|
|
||||||
checkForOldListViews(ctx,displayModel,displayLoadAtStartup);
|
|
||||||
displayModel.addSubModel( displayLoadAtStartup );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All of the list views should now reside in files in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR.
|
|
||||||
* This will check for custom list view annotation statements in the displayModel, check
|
|
||||||
* if they exist in the files in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR, and write any that don't
|
|
||||||
* exist there to a file in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR. After that the statements
|
|
||||||
* will be removed from the displayDBModel.
|
|
||||||
*
|
|
||||||
* returns true if there were old list view statements in the DB, returns false
|
|
||||||
* if there were none. displayLoadAlways should be reloaded from the file system
|
|
||||||
* if this returns true as this method may have changed the files.
|
|
||||||
*
|
|
||||||
* displayLoadAtStartup and displayModel may be modified.
|
|
||||||
*/
|
|
||||||
private void checkForOldListViews( ServletContext ctx, OntModel displayModel, Model displayLoadAtStartup){
|
|
||||||
// run construct for old custom list view statements from displayModel
|
|
||||||
Model oldListViewModel = getOldListViewStatements( displayModel );
|
|
||||||
if( log.isDebugEnabled() ){
|
|
||||||
log.debug("Printing the old list view statements from the display model to System.out.");
|
|
||||||
oldListViewModel.write(System.out,"N3-PP");
|
|
||||||
}
|
|
||||||
|
|
||||||
// find statements in old stmts that are not in loadedAtStartup and
|
|
||||||
// save them in a new file in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR
|
|
||||||
// so that in the future they will be in loadedAtStartup
|
|
||||||
Model stmtsInOldAndFiles = displayLoadAtStartup.intersection( displayModel );
|
|
||||||
Model unhandledOldListViewStmts = oldListViewModel.difference( stmtsInOldAndFiles );
|
|
||||||
|
|
||||||
boolean saved = false;
|
|
||||||
boolean neededSave = false;
|
|
||||||
|
|
||||||
if( unhandledOldListViewStmts != null && !unhandledOldListViewStmts.isEmpty() ){
|
|
||||||
log.debug("need to deal with old list view statements from the display model");
|
|
||||||
neededSave = true;
|
|
||||||
try{
|
|
||||||
//create a file for the old statements in the loadAtStartup directory
|
|
||||||
String newFileName = ctx.getRealPath(
|
|
||||||
DISPLAY_MODEL_LOAD_AT_STARTUP_DIR + File.separator
|
|
||||||
+ new DateTime().toString(ISODateTimeFormat.basicDateTime()) + ".n3" );
|
|
||||||
File file = new File( newFileName );
|
|
||||||
file.createNewFile();
|
|
||||||
|
|
||||||
log.info("Relocating " + unhandledOldListViewStmts.size() + " custom list view statements from DB and saving to "
|
|
||||||
+ file.getAbsolutePath()+ File.separator + file.getName()
|
|
||||||
+ ". These will be loaded from this file when the system starts up.");
|
|
||||||
|
|
||||||
FileOutputStream fileOut = new FileOutputStream(file);
|
|
||||||
unhandledOldListViewStmts.write(fileOut, "N3-PP");
|
|
||||||
fileOut.close();
|
|
||||||
saved = true;
|
|
||||||
}catch(Throwable th){
|
|
||||||
log.warn("Could not save old list view statements. Leaving them in the DB",th);
|
|
||||||
}
|
|
||||||
|
|
||||||
//need to reload displayLoadAlways because DISPLAY_MODEL_LOAD_AT_STARTUP_DIR may have changed
|
|
||||||
displayLoadAtStartup.removeAll().add(readInDisplayModelLoadAtStartup(ctx));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( oldListViewModel != null && ! oldListViewModel.isEmpty() ){
|
|
||||||
//At this point, there are old list view statements in the DB but they
|
|
||||||
//should are all redundant with ones in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR
|
|
||||||
if( (neededSave && saved) || (!neededSave) ){
|
|
||||||
//if there was nothing to save, just remove the old stuff
|
|
||||||
//if there was stuff to save, only remove if it was saved.
|
|
||||||
log.debug("removing old statements from displayModel");
|
|
||||||
displayModel.remove(oldListViewModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Model getOldListViewStatements(OntModel displayModel) {
|
|
||||||
//run a construct on displayModel to get all list view statements
|
|
||||||
Query query = QueryFactory.create ( listViewQuery );
|
|
||||||
QueryExecution qexec = QueryExecutionFactory.create(query, displayModel) ;
|
|
||||||
Model oldModel = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
oldModel = qexec.execConstruct();
|
|
||||||
} catch( Throwable th ){
|
|
||||||
log.error("could not check for old custom list views, query exception",th);
|
|
||||||
}finally {
|
|
||||||
qexec.close() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( oldModel != null)
|
|
||||||
return oldModel;
|
|
||||||
else
|
|
||||||
return ModelFactory.createDefaultModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String listViewQuery = "" +
|
|
||||||
"PREFIX d: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#>\n" +
|
|
||||||
"CONSTRUCT { \n" +
|
|
||||||
" ?a d:listViewConfigFile ?b . \n" +
|
|
||||||
"} WHERE {\n" +
|
|
||||||
" ?a d:listViewConfigFile ?b . \n" +
|
|
||||||
"} ";
|
|
||||||
|
|
||||||
protected Model readInDisplayModelLoadAtStartup( ServletContext ctx ){
|
|
||||||
return getModelFromDir( new File( ctx.getRealPath( DISPLAY_MODEL_LOAD_AT_STARTUP_DIR )));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,239 @@
|
||||||
|
/* $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 javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
|
||||||
|
import org.apache.commons.dbcp.BasicDataSource;
|
||||||
|
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.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.Syntax;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelectorImpl;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase.TripleStoreType;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.utils.jena.InitialJenaModelUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the ABox, TBox, inference and Union models.
|
||||||
|
* Also setup the OntModelSelectors.
|
||||||
|
*/
|
||||||
|
public class ModelSetup extends JenaDataSourceSetupBase
|
||||||
|
implements javax.servlet.ServletContextListener {
|
||||||
|
private static final Log log = LogFactory.getLog(ModelSetup.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
ServletContext ctx = sce.getServletContext();
|
||||||
|
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||||
|
|
||||||
|
BasicDataSource bds = getApplicationDataSource(ctx);
|
||||||
|
if( bds == null ){
|
||||||
|
ss.fatal(this, "A DataSource must be setup before ModelSetup "+
|
||||||
|
"is run. Make sure that JenaPersistentDataSourceSetup runs before "+
|
||||||
|
"ModelSetup.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setupModels(ctx,ss,bds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupModels(ServletContext ctx, StartupStatus ss, BasicDataSource bds){
|
||||||
|
log.info("Setting up model makers and union models");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
|
//set up the OntModelSelectors
|
||||||
|
|
||||||
|
OntModelSelectorImpl baseOms = new OntModelSelectorImpl();
|
||||||
|
OntModelSelectorImpl inferenceOms = new OntModelSelectorImpl();
|
||||||
|
OntModelSelectorImpl unionOms = new OntModelSelectorImpl();
|
||||||
|
|
||||||
|
//Put OntModelSelectorImpl objs into the context
|
||||||
|
ModelContext.setOntModelSelector(unionOms, ctx);
|
||||||
|
ModelContext.setUnionOntModelSelector(unionOms, ctx);
|
||||||
|
// assertions and inferences
|
||||||
|
ModelContext.setBaseOntModelSelector(baseOms, ctx);
|
||||||
|
// assertions
|
||||||
|
ModelContext.setInferenceOntModelSelector(inferenceOms, ctx);
|
||||||
|
// inferences
|
||||||
|
|
||||||
|
//add userAccountsModel to OntModelSelectors
|
||||||
|
OntModel userAccountsModel = ontModelFromContextAttribute(
|
||||||
|
ctx, "userAccountsOntModel");
|
||||||
|
baseOms.setUserAccountsModel(userAccountsModel);
|
||||||
|
inferenceOms.setUserAccountsModel(userAccountsModel);
|
||||||
|
unionOms.setUserAccountsModel(userAccountsModel);
|
||||||
|
|
||||||
|
//add display to OntModelSelectors
|
||||||
|
OntModel displayModel = ontModelFromContextAttribute(
|
||||||
|
ctx,DISPLAY_ONT_MODEL);
|
||||||
|
baseOms.setDisplayModel(displayModel);
|
||||||
|
inferenceOms.setDisplayModel(displayModel);
|
||||||
|
unionOms.setDisplayModel(displayModel);
|
||||||
|
|
||||||
|
// The code below, which sets up the OntModelSelectors, controls whether
|
||||||
|
// each model is maintained in memory, in the DB, or both while the
|
||||||
|
// application is running.
|
||||||
|
|
||||||
|
// Populate the three OntModelSelectors (BaseOntModel = assertions,
|
||||||
|
// InferenceOntModel = inferences and JenaOntModel = union of assertions
|
||||||
|
// and inferences) with the post-SDB-conversion models.
|
||||||
|
|
||||||
|
// ABox assertions
|
||||||
|
Model aboxAssertions = makeDBModel(
|
||||||
|
bds, JenaDataSourceSetupBase.JENA_DB_MODEL, DB_ONT_MODEL_SPEC,
|
||||||
|
TripleStoreType.SDB, ctx);
|
||||||
|
Model listenableAboxAssertions = ModelFactory.createUnion(
|
||||||
|
aboxAssertions, ModelFactory.createDefaultModel());
|
||||||
|
baseOms.setABoxModel(
|
||||||
|
ModelFactory.createOntologyModel(
|
||||||
|
OntModelSpec.OWL_MEM, listenableAboxAssertions));
|
||||||
|
|
||||||
|
// ABox inferences
|
||||||
|
Model aboxInferences = makeDBModel(
|
||||||
|
bds, JenaDataSourceSetupBase.JENA_INF_MODEL, DB_ONT_MODEL_SPEC,
|
||||||
|
TripleStoreType.SDB, ctx);
|
||||||
|
Model listenableAboxInferences = ModelFactory.createUnion(
|
||||||
|
aboxInferences, ModelFactory.createDefaultModel());
|
||||||
|
inferenceOms.setABoxModel(ModelFactory.createOntologyModel(
|
||||||
|
OntModelSpec.OWL_MEM, listenableAboxInferences));
|
||||||
|
|
||||||
|
|
||||||
|
// Since the TBox models are in memory, they do not have timeout issues
|
||||||
|
// like the like the ABox models do (and so don't need the extra step
|
||||||
|
// to make them listenable.)
|
||||||
|
|
||||||
|
// TBox assertions
|
||||||
|
try {
|
||||||
|
Model tboxAssertionsDB = makeDBModel(
|
||||||
|
bds, JENA_TBOX_ASSERTIONS_MODEL, DB_ONT_MODEL_SPEC,
|
||||||
|
TripleStoreType.SDB, ctx);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TBox inferences
|
||||||
|
try {
|
||||||
|
Model tboxInferencesDB = makeDBModel(
|
||||||
|
bds, JENA_TBOX_INF_MODEL, DB_ONT_MODEL_SPEC,
|
||||||
|
TripleStoreType.SDB, ctx);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// union ABox
|
||||||
|
OntModel unionABoxModel = ModelFactory.createOntologyModel(
|
||||||
|
MEM_ONT_MODEL_SPEC,ModelFactory.createUnion(
|
||||||
|
baseOms.getABoxModel(), inferenceOms.getABoxModel()));
|
||||||
|
unionOms.setABoxModel(unionABoxModel);
|
||||||
|
|
||||||
|
// union TBox
|
||||||
|
OntModel unionTBoxModel = ModelFactory.createOntologyModel(
|
||||||
|
MEM_ONT_MODEL_SPEC,ModelFactory.createUnion(
|
||||||
|
baseOms.getTBoxModel(), inferenceOms.getTBoxModel()));
|
||||||
|
unionOms.setTBoxModel(unionTBoxModel);
|
||||||
|
|
||||||
|
|
||||||
|
// Application metadata model is cached in memory.
|
||||||
|
try {
|
||||||
|
|
||||||
|
Model applicationMetadataModelDB = makeDBModel(
|
||||||
|
bds, JENA_APPLICATION_METADATA_MODEL, DB_ONT_MODEL_SPEC,
|
||||||
|
TripleStoreType.SDB, ctx);
|
||||||
|
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 (isFirstStartup()) {
|
||||||
|
applicationMetadataModel.add(
|
||||||
|
InitialJenaModelUtils.loadInitialModel(
|
||||||
|
ctx, getDefaultNamespace(ctx)));
|
||||||
|
|
||||||
|
} else if (applicationMetadataModelDB.size() == 0) {
|
||||||
|
repairAppMetadataModel(
|
||||||
|
applicationMetadataModel, aboxAssertions,
|
||||||
|
aboxInferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create TBox + ABox union models
|
||||||
|
OntModel baseUnion = ModelFactory.createOntologyModel(
|
||||||
|
OntModelSpec.OWL_MEM,
|
||||||
|
ModelFactory.createUnion(baseOms.getABoxModel(),
|
||||||
|
baseOms.getTBoxModel()));
|
||||||
|
baseOms.setFullModel(baseUnion);
|
||||||
|
ModelContext.setBaseOntModel(baseOms.getFullModel(), ctx);
|
||||||
|
|
||||||
|
log.info("Model makers and union set up");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent arg0) {
|
||||||
|
// nothing to do.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,243 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
|
||||||
|
import org.apache.commons.dbcp.BasicDataSource;
|
||||||
|
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 com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Statement;
|
||||||
|
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
||||||
|
import com.hp.hpl.jena.sdb.SDB;
|
||||||
|
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 com.hp.hpl.jena.sdb.store.DatabaseType;
|
||||||
|
import com.hp.hpl.jena.sdb.store.LayoutType;
|
||||||
|
import com.hp.hpl.jena.sdb.util.StoreUtils;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaModelUtils;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||||
|
|
||||||
|
public class SDBSetup extends JenaDataSourceSetupBase
|
||||||
|
implements javax.servlet.ServletContextListener {
|
||||||
|
private static final Log log = LogFactory.getLog(SDBSetup.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent arg0) {
|
||||||
|
// nothing to do
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
ServletContext ctx = sce.getServletContext();
|
||||||
|
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||||
|
try {
|
||||||
|
setupSDB(ctx, ss);
|
||||||
|
log.info("SDB store ready for use");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
ss.fatal(this, "Exception in setupSDB", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupSDB(ServletContext ctx, StartupStatus ss) throws SQLException {
|
||||||
|
BasicDataSource bds = getApplicationDataSource(ctx);
|
||||||
|
if( bds == null ){
|
||||||
|
ss.fatal(this, "A DataSource must be setup before SDBSetup "+
|
||||||
|
"is run. Make sure that JenaPersistentDataSourceSetup runs before "+
|
||||||
|
"SDBSetup.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// union default graph
|
||||||
|
SDB.getContext().set(SDB.unionDefaultGraph, true) ;
|
||||||
|
|
||||||
|
StoreDesc storeDesc = makeStoreDesc(ctx);
|
||||||
|
setApplicationStoreDesc(storeDesc, ctx);
|
||||||
|
|
||||||
|
Store store = connectStore(bds, storeDesc);
|
||||||
|
setApplicationStore(store, ctx);
|
||||||
|
|
||||||
|
if (!isSetUp(store)) {
|
||||||
|
log.info("Initializing SDB store");
|
||||||
|
if (isFirstStartup()) {
|
||||||
|
setupSDB(ctx, store);
|
||||||
|
} else {
|
||||||
|
migrateToSDBFromExistingRDBStore(ctx, store);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether an SDB store has been formatted and populated for use.
|
||||||
|
* @param store
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isSetUp(Store store) throws SQLException {
|
||||||
|
if (!(StoreUtils.isFormatted(store))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// even if the store exists, it may be empty
|
||||||
|
|
||||||
|
try {
|
||||||
|
return (SDBFactory.connectNamedModel(
|
||||||
|
store,
|
||||||
|
JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL))
|
||||||
|
.size() > 0;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StoreDesc makeStoreDesc(ServletContext ctx) {
|
||||||
|
String layoutStr = ConfigurationProperties.getBean(ctx).getProperty(
|
||||||
|
"VitroConnection.DataSource.sdb.layout", "layout2/hash");
|
||||||
|
String dbtypeStr = ConfigurationProperties.getBean(ctx).getProperty(
|
||||||
|
"VitroConnection.DataSource.dbtype", "MySQL");
|
||||||
|
return new StoreDesc(
|
||||||
|
LayoutType.fetch(layoutStr),
|
||||||
|
DatabaseType.fetch(dbtypeStr) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Store connectStore(BasicDataSource bds, StoreDesc storeDesc)
|
||||||
|
throws SQLException {
|
||||||
|
SDBConnection conn = new SDBConnection(bds.getConnection());
|
||||||
|
return SDBFactory.connectStore(conn, storeDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void setupSDB(ServletContext ctx, Store store) {
|
||||||
|
setupSDB(ctx, store, ModelFactory.createDefaultModel(),
|
||||||
|
ModelFactory.createDefaultModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void setupSDB(ServletContext ctx, Store store,
|
||||||
|
Model memModel, Model inferenceModel) {
|
||||||
|
|
||||||
|
store.getTableFormatter().create();
|
||||||
|
store.getTableFormatter().truncate();
|
||||||
|
|
||||||
|
store.getTableFormatter().dropIndexes(); // improve load performance
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// This is a one-time copy of stored KB data - from a Jena RDB store
|
||||||
|
// to a Jena SDB store. In the process, we will also separate out
|
||||||
|
// the TBox from the Abox; these are in the same graph in pre-1.2
|
||||||
|
// VIVO versions and will now be stored and maintained in separate
|
||||||
|
// models. Access to the Jena RDB data is through the
|
||||||
|
// OntModelSelectors that have been set up earlier in the current
|
||||||
|
// session by JenaPersistentDataSourceSetup.java. In the code
|
||||||
|
// below, note that the current getABoxModel() methods on the
|
||||||
|
// OntModelSelectors return a graph with both ABox and TBox data.
|
||||||
|
|
||||||
|
OntModel submodels = ModelFactory
|
||||||
|
.createOntologyModel(MEM_ONT_MODEL_SPEC);
|
||||||
|
readOntologyFilesInPathSet(SUBMODELS, ctx, submodels);
|
||||||
|
|
||||||
|
Model tboxAssertions = SDBFactory.connectNamedModel(store,
|
||||||
|
JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL);
|
||||||
|
// initially putting the results in memory so we have a
|
||||||
|
// cheaper way of computing the difference when we copy the ABox
|
||||||
|
Model memTboxAssertions = ModelFactory.createDefaultModel();
|
||||||
|
getTBoxModel(memModel, submodels, memTboxAssertions);
|
||||||
|
tboxAssertions.add(memTboxAssertions);
|
||||||
|
|
||||||
|
Model tboxInferences = SDBFactory.connectNamedModel(store,
|
||||||
|
JenaDataSourceSetupBase.JENA_TBOX_INF_MODEL);
|
||||||
|
// initially putting the results in memory so we have a
|
||||||
|
// cheaper way of computing the difference when we copy the ABox
|
||||||
|
Model memTboxInferences = ModelFactory.createDefaultModel();
|
||||||
|
getTBoxModel(inferenceModel, submodels, memTboxInferences);
|
||||||
|
tboxInferences.add(memTboxInferences);
|
||||||
|
|
||||||
|
Model aboxAssertions = SDBFactory.connectNamedModel(store,
|
||||||
|
JenaDataSourceSetupBase.JENA_DB_MODEL);
|
||||||
|
copyDifference(memModel, memTboxAssertions, aboxAssertions);
|
||||||
|
|
||||||
|
Model aboxInferences = SDBFactory.connectNamedModel(store,
|
||||||
|
JenaDataSourceSetupBase.JENA_INF_MODEL);
|
||||||
|
copyDifference(inferenceModel, memTboxInferences, aboxInferences);
|
||||||
|
|
||||||
|
// Set up the application metadata model
|
||||||
|
Model applicationMetadataModel = SDBFactory.connectNamedModel(
|
||||||
|
store,
|
||||||
|
JenaDataSourceSetupBase.JENA_APPLICATION_METADATA_MODEL);
|
||||||
|
getAppMetadata(memModel, applicationMetadataModel);
|
||||||
|
log.info("During initial SDB setup, created an application "
|
||||||
|
+ "metadata model of size "
|
||||||
|
+ applicationMetadataModel.size());
|
||||||
|
|
||||||
|
// remove application metadata from ABox model
|
||||||
|
aboxAssertions.remove(applicationMetadataModel);
|
||||||
|
aboxInferences.remove(applicationMetadataModel);
|
||||||
|
|
||||||
|
// Make sure the reasoner takes into account the newly-set-up data.
|
||||||
|
SimpleReasonerSetup.setRecomputeRequired(ctx);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
log.info("Adding indexes to SDB database tables.");
|
||||||
|
store.getTableFormatter().addIndexes();
|
||||||
|
log.info("Indexes created.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void migrateToSDBFromExistingRDBStore(ServletContext ctx,
|
||||||
|
Store store) {
|
||||||
|
Model rdbAssertionsModel = makeDBModelFromConfigurationProperties(
|
||||||
|
JENA_DB_MODEL, DB_ONT_MODEL_SPEC, ctx);
|
||||||
|
Model rdbInferencesModel = makeDBModelFromConfigurationProperties(
|
||||||
|
JENA_INF_MODEL, DB_ONT_MODEL_SPEC, ctx);
|
||||||
|
setupSDB(ctx, store, rdbAssertionsModel, rdbInferencesModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy all statements from model 1 that are not in model 2 to model 3.
|
||||||
|
*/
|
||||||
|
private static void copyDifference(Model model1, Model model2, Model model3) {
|
||||||
|
|
||||||
|
StmtIterator iter = model1.listStatements();
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Statement stmt = iter.next();
|
||||||
|
if (!model2.contains(stmt)) {
|
||||||
|
model3.add(stmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getTBoxModel(Model fullModel, Model submodels,
|
||||||
|
Model tboxModel) {
|
||||||
|
|
||||||
|
JenaModelUtils modelUtils = new JenaModelUtils();
|
||||||
|
|
||||||
|
Model tempModel = ModelFactory.createUnion(fullModel, submodels);
|
||||||
|
Model tempTBoxModel = modelUtils.extractTBox(tempModel);
|
||||||
|
|
||||||
|
// copy intersection of tempTBoxModel and fullModel to tboxModel.
|
||||||
|
StmtIterator iter = tempTBoxModel.listStatements();
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Statement stmt = iter.next();
|
||||||
|
if (fullModel.contains(stmt)) {
|
||||||
|
tboxModel.add(stmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/* $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 javax.servlet.ServletContextListener;
|
||||||
|
|
||||||
|
import org.apache.commons.dbcp.BasicDataSource;
|
||||||
|
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 com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the user account model. If it does not exist in the
|
||||||
|
* database, create and populate it.
|
||||||
|
*/
|
||||||
|
public class UserModelSetup extends JenaDataSourceSetupBase
|
||||||
|
implements ServletContextListener {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(
|
||||||
|
UserModelSetup.class.getName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
ServletContext ctx = sce.getServletContext();
|
||||||
|
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||||
|
|
||||||
|
BasicDataSource bds = getApplicationDataSource(ctx);
|
||||||
|
if( bds == null ){
|
||||||
|
ss.fatal(this, "A DataSource must be setup before ModelSetup "+
|
||||||
|
"is run. Make sure that JenaPersistentDataSourceSetup runs before "+
|
||||||
|
"ModelSetup.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setupUserAccountModel(bds, ctx, ss);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent arg0) {
|
||||||
|
// Does nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUserAccountModel (BasicDataSource bds, ServletContext ctx ,StartupStatus ss){
|
||||||
|
try {
|
||||||
|
Model userAccountsDbModel = makeDBModel(bds,
|
||||||
|
JENA_USER_ACCOUNTS_MODEL, DB_ONT_MODEL_SPEC, ctx);
|
||||||
|
OntModel userAccountsModel =
|
||||||
|
ModelFactory.createOntologyModel( MEM_ONT_MODEL_SPEC);
|
||||||
|
|
||||||
|
userAccountsModel.add(userAccountsDbModel);
|
||||||
|
userAccountsModel.getBaseModel().register(
|
||||||
|
new ModelSynchronizer(userAccountsDbModel));
|
||||||
|
ctx.setAttribute("userAccountsOntModel", userAccountsModel);
|
||||||
|
|
||||||
|
} catch (Throwable t) {
|
||||||
|
log.error("Unable to load user accounts model from DB", t);
|
||||||
|
ss.fatal(this, "Unable to load user accounts model from DB", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,265 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
|
||||||
|
import org.apache.commons.dbcp.BasicDataSource;
|
||||||
|
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 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.sdb.StoreDesc;
|
||||||
|
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.OntModelSelector;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelectorImpl;
|
||||||
|
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.jena.VitroModelSource;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Primarily sets up webapp DAO factories.
|
||||||
|
*/
|
||||||
|
public class WebappDaoSDBSetup extends JenaDataSourceSetupBase
|
||||||
|
implements javax.servlet.ServletContextListener {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(WebappDaoSDBSetup.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 SDB store");
|
||||||
|
} catch (SQLException sqle) {
|
||||||
|
// SQL exceptions are fatal and should halt startup
|
||||||
|
log.error("Error using SQL database; startup aborted.", sqle);
|
||||||
|
ss.fatal(this, "Error using SQL database; startup aborted.", sqle);
|
||||||
|
} 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) throws SQLException {
|
||||||
|
|
||||||
|
BasicDataSource bds = getApplicationDataSource(ctx);
|
||||||
|
if( bds == null ){
|
||||||
|
ss.fatal(this, "A DataSource must be setup before "+ WebappDaoSDBSetup.class.getName() +
|
||||||
|
"is run. Make sure that JenaPersistentDataSourceSetup runs before "+
|
||||||
|
WebappDaoSDBSetup.class.getName() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the OntModelSelectors
|
||||||
|
OntModelSelectorImpl baseOms =
|
||||||
|
(OntModelSelectorImpl) ModelContext.getBaseOntModelSelector(ctx);
|
||||||
|
OntModelSelectorImpl inferenceOms =
|
||||||
|
(OntModelSelectorImpl) ModelContext.getInferenceOntModelSelector(ctx);
|
||||||
|
OntModelSelectorImpl unionOms =
|
||||||
|
(OntModelSelectorImpl) ModelContext.getUnionOntModelSelector(ctx);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
|
// Check for namespace mismatch
|
||||||
|
|
||||||
|
checkForNamespaceMismatch( baseOms.getApplicationMetadataModel(), ctx );
|
||||||
|
ctx.setAttribute("defaultNamespace", getDefaultNamespace(ctx));
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
|
// first startup?
|
||||||
|
|
||||||
|
if (isFirstStartup()) {
|
||||||
|
loadDataFromFilesystem(baseOms, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("Setting up DAO factories");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
|
//create assertions webapp DAO factory
|
||||||
|
|
||||||
|
StoreDesc storeDesc = getApplicationStoreDesc(ctx);
|
||||||
|
WebappDaoFactoryConfig config = new WebappDaoFactoryConfig();
|
||||||
|
config.setDefaultNamespace(getDefaultNamespace(ctx));
|
||||||
|
WebappDaoFactory baseWadf = new WebappDaoFactorySDB(
|
||||||
|
baseOms, bds, storeDesc, config,
|
||||||
|
WebappDaoFactorySDB.SDBDatasetMode.ASSERTIONS_ONLY);
|
||||||
|
ctx.setAttribute("assertionsWebappDaoFactory",baseWadf);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
|
//create inference webapp DAO factory
|
||||||
|
|
||||||
|
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(
|
||||||
|
inferenceOms, bds, storeDesc, config,
|
||||||
|
WebappDaoFactorySDB.SDBDatasetMode.INFERENCES_ONLY);
|
||||||
|
ctx.setAttribute("deductionsWebappDaoFactory", infWadf);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////
|
||||||
|
//create default union webapp DAO factory
|
||||||
|
|
||||||
|
OntModel masterUnion = ModelFactory.createOntologyModel(
|
||||||
|
DB_ONT_MODEL_SPEC, makeDBModel(
|
||||||
|
bds, WebappDaoFactorySDB.UNION_GRAPH,
|
||||||
|
DB_ONT_MODEL_SPEC, TripleStoreType.SDB, ctx));
|
||||||
|
unionOms.setFullModel(masterUnion);
|
||||||
|
ctx.setAttribute("jenaOntModel", masterUnion);
|
||||||
|
WebappDaoFactory wadf = new WebappDaoFactorySDB(
|
||||||
|
unionOms, bds, storeDesc, config);
|
||||||
|
ctx.setAttribute("webappDaoFactory",wadf);
|
||||||
|
|
||||||
|
makeModelMakerFromConnectionProperties(TripleStoreType.RDB, ctx);
|
||||||
|
VitroJenaModelMaker vjmm = getVitroJenaModelMaker();
|
||||||
|
setVitroJenaModelMaker(vjmm, ctx);
|
||||||
|
makeModelMakerFromConnectionProperties(TripleStoreType.SDB, ctx);
|
||||||
|
VitroJenaSDBModelMaker vsmm = getVitroJenaSDBModelMaker();
|
||||||
|
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("DAOs 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<Resource> 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<Resource> getPortal1s(Model model) {
|
||||||
|
List<Resource> portals = new ArrayList<Resource>();
|
||||||
|
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<Resource> 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<Statement> 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.debug("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 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,423 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.edit.elements;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
import org.junit.runners.Parameterized.Parameters;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
|
|
||||||
import com.hp.hpl.jena.datatypes.xsd.XSDDateTime;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Literal;
|
|
||||||
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.Field;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditSubmission;
|
|
||||||
|
|
||||||
|
|
||||||
@RunWith(value= Parameterized.class)
|
|
||||||
public class DateTimeWithPrecisionTest {
|
|
||||||
|
|
||||||
TimeZone orginalTimeZone;
|
|
||||||
TimeZone testZone;
|
|
||||||
|
|
||||||
public DateTimeWithPrecisionTest(TimeZone tz){
|
|
||||||
orginalTimeZone = TimeZone.getDefault();
|
|
||||||
testZone = tz;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Parameters
|
|
||||||
public static Collection<Object[]> data(){
|
|
||||||
String allZones[] = TimeZone.getAvailableIDs();
|
|
||||||
ArrayList<Object[]> data = new ArrayList<Object[]>( allZones.length );
|
|
||||||
for( String zoneId : allZones ){
|
|
||||||
Object v[] = new Object[1];
|
|
||||||
v[0] = TimeZone.getTimeZone(zoneId);
|
|
||||||
try{
|
|
||||||
DateTimeZone dtz = DateTimeZone.forID(zoneId);
|
|
||||||
if( dtz != null ){
|
|
||||||
data.add(v);
|
|
||||||
}
|
|
||||||
}catch(IllegalArgumentException ex){
|
|
||||||
//cannot convert to joda datetimezone.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void beforeTest(){
|
|
||||||
TimeZone.setDefault( testZone );
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void after(){
|
|
||||||
if( orginalTimeZone != null){
|
|
||||||
TimeZone.setDefault(orginalTimeZone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void fieldNameTemplateVariableTest() throws Exception{
|
|
||||||
String FIELDNAME = "testfield";
|
|
||||||
Field field = new Field();
|
|
||||||
field.setName(FIELDNAME);
|
|
||||||
DateTimeWithPrecision dtwp = new DateTimeWithPrecision(field);
|
|
||||||
|
|
||||||
EditSubmission editSub = null;
|
|
||||||
EditConfiguration editConfig = new EditConfiguration();
|
|
||||||
editConfig.setUrisInScope(Collections.EMPTY_MAP);
|
|
||||||
editConfig.setLiteralsInScope(Collections.EMPTY_MAP);
|
|
||||||
|
|
||||||
Map templateVars = dtwp.getMapForTemplate(editConfig, editSub);
|
|
||||||
Assert.assertNotNull(templateVars);
|
|
||||||
|
|
||||||
Assert.assertTrue( templateVars.containsKey("fieldName") );
|
|
||||||
Assert.assertEquals(templateVars.get("fieldName"), "testfield");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void precisionSecondsValidationTest() throws Exception{
|
|
||||||
String FIELDNAME = "testfield";
|
|
||||||
Field field = new Field();
|
|
||||||
field.setName(FIELDNAME);
|
|
||||||
DateTimeWithPrecision dtwp = new DateTimeWithPrecision(field);
|
|
||||||
|
|
||||||
Map<String,String[]> queryParameters = new HashMap<String, String[]>();
|
|
||||||
queryParameters.put(FIELDNAME+"-year", new String[]{"1999" });
|
|
||||||
queryParameters.put(FIELDNAME+"-month", new String[]{"12"});
|
|
||||||
queryParameters.put(FIELDNAME+"-day", new String[]{"01"});
|
|
||||||
queryParameters.put(FIELDNAME+"-hour", new String[]{"12"});
|
|
||||||
queryParameters.put(FIELDNAME+"-minute", new String[]{"00"});
|
|
||||||
queryParameters.put(FIELDNAME+"-second", new String[]{"00"});
|
|
||||||
EditConfiguration editConfig=null;
|
|
||||||
Map<String,String> validationMsgs = dtwp.getValidationMessages("testfield", editConfig, queryParameters);
|
|
||||||
Assert.assertNotNull(validationMsgs);
|
|
||||||
Assert.assertTrue(validationMsgs.size() == 0 );
|
|
||||||
|
|
||||||
String precisionURI = null;
|
|
||||||
precisionURI = dtwp.getSubmittedPrecision( queryParameters);
|
|
||||||
|
|
||||||
Assert.assertNotNull(precisionURI);
|
|
||||||
Assert.assertEquals(VitroVocabulary.Precision.SECOND.uri(), precisionURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void precisionMinutesValidationTest() throws Exception{
|
|
||||||
String FIELDNAME = "testfield";
|
|
||||||
Field field = new Field();
|
|
||||||
field.setName(FIELDNAME);
|
|
||||||
DateTimeWithPrecision dtwp = new DateTimeWithPrecision(field);
|
|
||||||
|
|
||||||
Map<String,String[]> queryParameters = new HashMap<String, String[]>();
|
|
||||||
queryParameters.put(FIELDNAME+"-year", new String[]{"1999" });
|
|
||||||
queryParameters.put(FIELDNAME+"-month", new String[]{"12"});
|
|
||||||
queryParameters.put(FIELDNAME+"-day", new String[]{"01"});
|
|
||||||
queryParameters.put(FIELDNAME+"-hour", new String[]{"12"});
|
|
||||||
queryParameters.put(FIELDNAME+"-minute", new String[]{"00"});
|
|
||||||
//no seconds
|
|
||||||
|
|
||||||
EditConfiguration editConfig=null;
|
|
||||||
Map<String,String> validationMsgs = dtwp.getValidationMessages("testfield", editConfig, queryParameters);
|
|
||||||
Assert.assertNotNull(validationMsgs);
|
|
||||||
Assert.assertTrue(validationMsgs.size() == 0 );
|
|
||||||
|
|
||||||
String precisionURI = null;
|
|
||||||
precisionURI = dtwp.getSubmittedPrecision( queryParameters);
|
|
||||||
|
|
||||||
Assert.assertNotNull(precisionURI);
|
|
||||||
Assert.assertEquals(VitroVocabulary.Precision.MINUTE.uri(), precisionURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void precisionHoursValidationTest() throws Exception{
|
|
||||||
String FIELDNAME = "testfield";
|
|
||||||
Field field = new Field();
|
|
||||||
field.setName(FIELDNAME);
|
|
||||||
DateTimeWithPrecision dtwp = new DateTimeWithPrecision(field);
|
|
||||||
|
|
||||||
Map<String,String[]> queryParameters = new HashMap<String, String[]>();
|
|
||||||
queryParameters.put(FIELDNAME+"-year", new String[]{"1999" });
|
|
||||||
queryParameters.put(FIELDNAME+"-month", new String[]{"12"});
|
|
||||||
queryParameters.put(FIELDNAME+"-day", new String[]{"01"});
|
|
||||||
queryParameters.put(FIELDNAME+"-hour", new String[]{"12"});
|
|
||||||
//no minutes
|
|
||||||
//no seconds
|
|
||||||
|
|
||||||
EditConfiguration editConfig=null;
|
|
||||||
Map<String,String> validationMsgs = dtwp.getValidationMessages("testfield", editConfig, queryParameters);
|
|
||||||
Assert.assertNotNull(validationMsgs);
|
|
||||||
Assert.assertTrue(validationMsgs.size() == 0 );
|
|
||||||
|
|
||||||
String precisionURI = null;
|
|
||||||
precisionURI = dtwp.getSubmittedPrecision( queryParameters);
|
|
||||||
|
|
||||||
Assert.assertNotNull(precisionURI);
|
|
||||||
Assert.assertEquals(VitroVocabulary.Precision.HOUR.uri(), precisionURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void precisionDaysValidationTest() throws Exception{
|
|
||||||
String FIELDNAME = "testfield";
|
|
||||||
Field field = new Field();
|
|
||||||
field.setName(FIELDNAME);
|
|
||||||
DateTimeWithPrecision dtwp = new DateTimeWithPrecision(field);
|
|
||||||
|
|
||||||
Map<String,String[]> queryParameters = new HashMap<String, String[]>();
|
|
||||||
queryParameters.put(FIELDNAME+"-year", new String[]{"1999" });
|
|
||||||
queryParameters.put(FIELDNAME+"-month", new String[]{"12"});
|
|
||||||
queryParameters.put(FIELDNAME+"-day", new String[]{"01"});
|
|
||||||
//no hours
|
|
||||||
//no minutes
|
|
||||||
//no seconds
|
|
||||||
|
|
||||||
EditConfiguration editConfig=null;
|
|
||||||
Map<String,String> validationMsgs = dtwp.getValidationMessages("testfield", editConfig, queryParameters);
|
|
||||||
Assert.assertNotNull(validationMsgs);
|
|
||||||
Assert.assertTrue(validationMsgs.size() == 0 );
|
|
||||||
|
|
||||||
String precisionURI = null;
|
|
||||||
precisionURI = dtwp.getSubmittedPrecision( queryParameters);
|
|
||||||
|
|
||||||
Assert.assertNotNull(precisionURI);
|
|
||||||
Assert.assertEquals(VitroVocabulary.Precision.DAY.uri(), precisionURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void precisionMonthsValidationTest()throws Exception{
|
|
||||||
String FIELDNAME = "testfield";
|
|
||||||
Field field = new Field();
|
|
||||||
field.setName(FIELDNAME);
|
|
||||||
DateTimeWithPrecision dtwp = new DateTimeWithPrecision(field);
|
|
||||||
|
|
||||||
Map<String,String[]> queryParameters = new HashMap<String, String[]>();
|
|
||||||
queryParameters.put(FIELDNAME+"-year", new String[]{"1999" });
|
|
||||||
queryParameters.put(FIELDNAME+"-month", new String[]{"12"});
|
|
||||||
//no days
|
|
||||||
//no hours
|
|
||||||
//no minutes
|
|
||||||
//no seconds
|
|
||||||
|
|
||||||
EditConfiguration editConfig=null;
|
|
||||||
Map<String,String> validationMsgs = dtwp.getValidationMessages("testfield", editConfig, queryParameters);
|
|
||||||
Assert.assertNotNull(validationMsgs);
|
|
||||||
Assert.assertTrue(validationMsgs.size() == 0 );
|
|
||||||
|
|
||||||
String precisionURI = null;
|
|
||||||
precisionURI = dtwp.getSubmittedPrecision( queryParameters);
|
|
||||||
|
|
||||||
Assert.assertNotNull(precisionURI);
|
|
||||||
Assert.assertEquals(VitroVocabulary.Precision.MONTH.uri(), precisionURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void precisionYearValidationTest() throws Exception{
|
|
||||||
String FIELDNAME = "testfield";
|
|
||||||
Field field = new Field();
|
|
||||||
field.setName(FIELDNAME);
|
|
||||||
DateTimeWithPrecision dtwp = new DateTimeWithPrecision(field);
|
|
||||||
|
|
||||||
Map<String,String[]> queryParameters = new HashMap<String, String[]>();
|
|
||||||
queryParameters.put(FIELDNAME+"-year", new String[]{"1999" });
|
|
||||||
//no months
|
|
||||||
//no days
|
|
||||||
//no hours
|
|
||||||
//no minutes
|
|
||||||
//no seconds
|
|
||||||
|
|
||||||
EditConfiguration editConfig=null;
|
|
||||||
Map<String,String> validationMsgs = dtwp.getValidationMessages("testfield", editConfig, queryParameters);
|
|
||||||
Assert.assertNotNull(validationMsgs);
|
|
||||||
Assert.assertTrue(validationMsgs.size() == 0 );
|
|
||||||
|
|
||||||
String precisionURI = null;
|
|
||||||
precisionURI = dtwp.getSubmittedPrecision( queryParameters);
|
|
||||||
|
|
||||||
Assert.assertNotNull(precisionURI);
|
|
||||||
Assert.assertEquals(VitroVocabulary.Precision.YEAR.uri(), precisionURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void precisionNoValueTest() throws Exception{
|
|
||||||
String FIELDNAME = "testfield";
|
|
||||||
Field field = new Field();
|
|
||||||
field.setName(FIELDNAME);
|
|
||||||
DateTimeWithPrecision dtwp = new DateTimeWithPrecision(field);
|
|
||||||
|
|
||||||
Map<String,String[]> queryParameters = new HashMap<String, String[]>();
|
|
||||||
//field is not filled out at all
|
|
||||||
//no year
|
|
||||||
//no months
|
|
||||||
//no days
|
|
||||||
//no hours
|
|
||||||
//no minutes
|
|
||||||
//no seconds
|
|
||||||
|
|
||||||
EditConfiguration editConfig=null;
|
|
||||||
Map<String,String> validationMsgs = dtwp.getValidationMessages("testfield", editConfig, queryParameters);
|
|
||||||
Assert.assertNotNull(validationMsgs);
|
|
||||||
Assert.assertTrue(validationMsgs.size() == 0 );
|
|
||||||
|
|
||||||
String precisionURI = null;
|
|
||||||
|
|
||||||
precisionURI = dtwp.getSubmittedPrecision( queryParameters );
|
|
||||||
|
|
||||||
Assert.assertNotNull(precisionURI);
|
|
||||||
Assert.assertEquals(dtwp.BLANK_SENTINEL, precisionURI);
|
|
||||||
|
|
||||||
Literal date = dtwp.getDateTime( queryParameters);
|
|
||||||
Assert.assertNull(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getDateLiteralTest(){
|
|
||||||
String FIELDNAME = "testfield";
|
|
||||||
Field field = new Field();
|
|
||||||
field.setName(FIELDNAME);
|
|
||||||
DateTimeWithPrecision dtwp = new DateTimeWithPrecision(field);
|
|
||||||
|
|
||||||
Map<String,String[]> queryParameters = new HashMap<String, String[]>();
|
|
||||||
queryParameters.put(FIELDNAME+"-year", new String[]{"1999" });
|
|
||||||
//no months
|
|
||||||
//no days
|
|
||||||
//no hours
|
|
||||||
//no minutes
|
|
||||||
//no seconds
|
|
||||||
|
|
||||||
EditConfiguration editConfig=null;
|
|
||||||
Map<String,String> validationMsgs = dtwp.getValidationMessages("testfield", editConfig, queryParameters);
|
|
||||||
Assert.assertNotNull(validationMsgs);
|
|
||||||
Assert.assertTrue(validationMsgs.size() == 0 );
|
|
||||||
|
|
||||||
Literal date = dtwp.getDateTime( queryParameters);
|
|
||||||
Assert.assertNotNull(date);
|
|
||||||
Assert.assertEquals( XSDDatatype.XSDdateTime.getURI() ,date.getDatatypeURI() );
|
|
||||||
|
|
||||||
Object obj = date.getValue();
|
|
||||||
Assert.assertNotNull(obj);
|
|
||||||
Assert.assertEquals(XSDDateTime.class, obj.getClass());
|
|
||||||
|
|
||||||
DateTime result = new DateTime( date.getLexicalForm());
|
|
||||||
DateTime expected = new DateTime(1999,1,1,0,0,0,0 );
|
|
||||||
Assert.assertEquals(expected.toInstant() , result.toInstant());
|
|
||||||
|
|
||||||
Assert.assertEquals("1999-01-01T00:00:00" , date.getLexicalForm() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void day30Test() throws Exception{
|
|
||||||
String FIELDNAME = "testfield";
|
|
||||||
Field field = new Field();
|
|
||||||
field.setName(FIELDNAME);
|
|
||||||
DateTimeWithPrecision dtwp = new DateTimeWithPrecision(field);
|
|
||||||
|
|
||||||
|
|
||||||
/* Check if it works with day number under 29 */
|
|
||||||
Map<String,String[]> queryParameters = new HashMap<String, String[]>();
|
|
||||||
queryParameters.put(FIELDNAME+"-year", new String[]{"1999" });
|
|
||||||
queryParameters.put(FIELDNAME+"-month", new String[]{"12"});
|
|
||||||
queryParameters.put(FIELDNAME+"-day", new String[]{"28"});
|
|
||||||
|
|
||||||
Map<String,String> validationMsgs = dtwp.getValidationMessages("testfield", (EditConfiguration)null, queryParameters);
|
|
||||||
Assert.assertNotNull(validationMsgs);
|
|
||||||
Assert.assertTrue(validationMsgs.size() == 0 );
|
|
||||||
|
|
||||||
String precisionURI = dtwp.getSubmittedPrecision( queryParameters);
|
|
||||||
Assert.assertNotNull(precisionURI);
|
|
||||||
Assert.assertEquals(VitroVocabulary.Precision.DAY.uri(), precisionURI);
|
|
||||||
|
|
||||||
/* Check for days greater than 28 */
|
|
||||||
queryParameters = new HashMap<String, String[]>();
|
|
||||||
queryParameters.put(FIELDNAME+"-year", new String[]{"1999" });
|
|
||||||
queryParameters.put(FIELDNAME+"-month", new String[]{"12"});
|
|
||||||
queryParameters.put(FIELDNAME+"-day", new String[]{"30"});
|
|
||||||
|
|
||||||
validationMsgs = dtwp.getValidationMessages("testfield", (EditConfiguration)null, queryParameters);
|
|
||||||
Assert.assertNotNull(validationMsgs);
|
|
||||||
Assert.assertTrue(validationMsgs.size() == 0 );
|
|
||||||
|
|
||||||
precisionURI = dtwp.getSubmittedPrecision( queryParameters);
|
|
||||||
Assert.assertNotNull(precisionURI);
|
|
||||||
Assert.assertEquals(VitroVocabulary.Precision.DAY.uri(), precisionURI);
|
|
||||||
|
|
||||||
/* Check for leap year */
|
|
||||||
queryParameters = new HashMap<String, String[]>();
|
|
||||||
queryParameters.put(FIELDNAME+"-year", new String[]{"2000" });
|
|
||||||
queryParameters.put(FIELDNAME+"-month", new String[]{"2"});
|
|
||||||
queryParameters.put(FIELDNAME+"-day", new String[]{"29"});
|
|
||||||
|
|
||||||
validationMsgs = dtwp.getValidationMessages("testfield", (EditConfiguration)null, queryParameters);
|
|
||||||
Assert.assertNotNull(validationMsgs);
|
|
||||||
Assert.assertTrue(validationMsgs.size() == 0 );
|
|
||||||
|
|
||||||
precisionURI = dtwp.getSubmittedPrecision( queryParameters);
|
|
||||||
Assert.assertNotNull(precisionURI);
|
|
||||||
Assert.assertEquals(VitroVocabulary.Precision.DAY.uri(), precisionURI);
|
|
||||||
|
|
||||||
/* check for non leap year */
|
|
||||||
queryParameters = new HashMap<String, String[]>();
|
|
||||||
queryParameters.put(FIELDNAME+"-year", new String[]{"1999" });
|
|
||||||
queryParameters.put(FIELDNAME+"-month", new String[]{"2"});
|
|
||||||
queryParameters.put(FIELDNAME+"-day", new String[]{"29"});
|
|
||||||
|
|
||||||
validationMsgs = dtwp.getValidationMessages("testfield", (EditConfiguration)null, queryParameters);
|
|
||||||
Assert.assertNotNull(validationMsgs);
|
|
||||||
Assert.assertTrue(validationMsgs.size() > 0 );
|
|
||||||
|
|
||||||
precisionURI = dtwp.getSubmittedPrecision( queryParameters);
|
|
||||||
Assert.assertNotNull(precisionURI);
|
|
||||||
Assert.assertEquals(VitroVocabulary.Precision.DAY.uri(), precisionURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void basicGetMapForTemplateTest() throws Exception{
|
|
||||||
String FIELDNAME = "testfield";
|
|
||||||
Field field = new Field();
|
|
||||||
field.setName(FIELDNAME);
|
|
||||||
DateTimeWithPrecision dtwp = new DateTimeWithPrecision(field);
|
|
||||||
|
|
||||||
EditConfiguration config = new EditConfiguration();
|
|
||||||
EditSubmission sub = null;
|
|
||||||
|
|
||||||
Map<String,String> urisInScope = new HashMap<String,String>();
|
|
||||||
urisInScope.put(dtwp.getPrecisionVariableName(),
|
|
||||||
VitroVocabulary.Precision.MINUTE.uri());
|
|
||||||
config.setUrisInScope(urisInScope);
|
|
||||||
|
|
||||||
Map<String,Literal> literalsInScope = new HashMap<String,Literal>();
|
|
||||||
literalsInScope.put(dtwp.getValueVariableName(),
|
|
||||||
ResourceFactory.createTypedLiteral("1999-02-15T10:00",XSDDatatype.XSDdateTime) );
|
|
||||||
config.setLiteralsInScope(literalsInScope);
|
|
||||||
|
|
||||||
Map<String,Object> map = dtwp.getMapForTemplate(config,sub);
|
|
||||||
Assert.assertEquals("year wrong", "1999", map.get("year"));
|
|
||||||
Assert.assertEquals("month wrong", "2", map.get("month"));
|
|
||||||
Assert.assertEquals("day wrong", "15", map.get("day"));
|
|
||||||
Assert.assertEquals("hour wrong", "10", map.get("hour"));
|
|
||||||
Assert.assertEquals("minute wrong", "0", map.get("minute"));
|
|
||||||
Assert.assertEquals("second wrong", "", map.get("second"));
|
|
||||||
|
|
||||||
Assert.assertEquals("precision wrong", VitroVocabulary.Precision.MINUTE.uri(), map.get("existingPrecision"));
|
|
||||||
|
|
||||||
Assert.assertEquals("fieldname wrong", FIELDNAME, map.get("fieldName"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -7,18 +7,22 @@
|
||||||
|
|
||||||
edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSetup
|
edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSetup
|
||||||
|
|
||||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.BasicSmokeTests
|
edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSmokeTests
|
||||||
|
|
||||||
edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup
|
edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup
|
||||||
|
|
||||||
edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup
|
edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup
|
||||||
|
|
||||||
# Comment out this listener to run Vitro without a database
|
### this listener must be run before SDBSetup, all models setups and WebappDaoSetup ###
|
||||||
# If used, this listener must be run before JenaDataSourceSetup
|
|
||||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaPersistentDataSourceSetup
|
edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaPersistentDataSourceSetup
|
||||||
|
|
||||||
# This listener is required in order to use a Jena triple store (currently the only option)
|
edu.cornell.mannlib.vitro.webapp.servlet.setup.SDBSetup
|
||||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetup
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.servlet.setup.ApplicationModelSetup
|
||||||
|
edu.cornell.mannlib.vitro.webapp.servlet.setup.UserModelSetup
|
||||||
|
edu.cornell.mannlib.vitro.webapp.servlet.setup.ModelSetup
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.servlet.setup.WebappDaoSDBSetup
|
||||||
|
|
||||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase
|
edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue