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$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
||||
package edu.cornell.mannlib.vitro.webapp.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
|
@ -12,10 +12,13 @@ import javax.servlet.ServletContext;
|
|||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||
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_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.VitroJenaSpecialModelMaker;
|
||||
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.jena.JenaIngestUtils;
|
||||
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);
|
||||
StoreDesc storeDesc = new StoreDesc(LayoutType.LayoutTripleNodesHash,dbTypeObj) ;
|
||||
ServletContext ctx = vreq.getSession().getServletContext();
|
||||
BasicDataSource bds = JenaDataSourceSetup.makeBasicDataSource(
|
||||
BasicDataSource bds = WebappDaoSDBSetup.makeBasicDataSource(
|
||||
driver, jdbcUrl, username, password, ctx);
|
||||
try {
|
||||
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.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
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.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.
|
||||
|
@ -133,7 +130,7 @@ public class DateTimeIntervalValidationVTwo implements N3ValidatorVTwo {
|
|||
//Currently checks first precision str and then returns response
|
||||
if(precisionStr.size() > 0) {
|
||||
String precisionString = precisionStr.get(0);
|
||||
VitroVocabulary.Precision precision = DateTimeWithPrecision.toPrecision( precisionString );
|
||||
VitroVocabulary.Precision precision = DateTimeWithPrecisionVTwo.toPrecision( precisionString );
|
||||
if( precision == null )
|
||||
log.debug("cannot convert " + precisionStr + " to a precision");
|
||||
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.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.sdb.Store;
|
||||
import com.hp.hpl.jena.sdb.StoreDesc;
|
||||
import com.hp.hpl.jena.sdb.store.DatabaseType;
|
||||
import com.hp.hpl.jena.sdb.store.LayoutType;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||
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.RDBGraphGenerator;
|
||||
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_APPMETA_PATH = BASE+"user/applicationMetadata";
|
||||
protected static String SYSTEMPATH = BASE+"system/";
|
||||
protected static String AUTHPATH = BASE+"auth/";
|
||||
public static String APPPATH = BASE+"app/";
|
||||
//these files are loaded everytime the system starts up
|
||||
public static String APPPATH_LOAD = APPPATH + "menuload/";
|
||||
|
@ -418,7 +424,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
|
|||
} else if (TripleStoreType.SDB.equals(type)) {
|
||||
StoreDesc storeDesc = new StoreDesc(
|
||||
LayoutType.LayoutTripleNodesHash, DatabaseType.fetch(dbtypeStr));
|
||||
BasicDataSource bds = JenaDataSourceSetup.makeBasicDataSource(
|
||||
BasicDataSource bds = WebappDaoSDBSetup.makeBasicDataSource(
|
||||
getDbDriverClassName(ctx), jdbcUrl, username, password, ctx);
|
||||
bds.setMaxActive(4); // for now, the SDB model makers should not use more
|
||||
// than a small handful of connections
|
||||
|
@ -524,4 +530,68 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
|
|||
"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;
|
||||
|
||||
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;
|
||||
|
@ -14,21 +9,18 @@ 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;
|
||||
|
||||
/**
|
||||
* Create connection to DB and DataSource, put them in the context.
|
||||
*/
|
||||
public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
|
||||
implements ServletContextListener {
|
||||
|
||||
|
@ -45,216 +37,12 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
|
|||
|
||||
BasicDataSource bds = makeDataSourceFromConfigurationProperties(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
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
// 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.servlet.setup.BasicSmokeTests
|
||||
edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSmokeTests
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup
|
||||
|
||||
# Comment out this listener to run Vitro without a database
|
||||
# If used, this listener must be run before JenaDataSourceSetup
|
||||
### this listener must be run before SDBSetup, all models setups and WebappDaoSetup ###
|
||||
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.JenaDataSourceSetup
|
||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.SDBSetup
|
||||
|
||||
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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue