Worked on refactoring the startup listeners NIHVIVO-3700. Removed some old N3 code.

This commit is contained in:
briancaruso 2012-05-04 16:20:26 +00:00
parent 3250efd091
commit 29e4edc25d
15 changed files with 1166 additions and 2088 deletions

View file

@ -1,6 +1,6 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */ /* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.servlet.setup; package edu.cornell.mannlib.vitro.webapp.config;
import java.io.File; import java.io.File;
import java.sql.Connection; import java.sql.Connection;
@ -12,10 +12,13 @@ import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; import javax.servlet.ServletContextListener;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
public class BasicSmokeTests implements ServletContextListener { /**
* Test that gets run at servlet context startup to check for the existence and
* validity of properties in the configuration.
*/
public class ConfigurationPropertiesSmokeTests implements ServletContextListener {
private static final String PROPERTY_HOME_DIRECTORY = "vitro.home.directory"; private static final String PROPERTY_HOME_DIRECTORY = "vitro.home.directory";
private static final String PROPERTY_DB_URL = "VitroConnection.DataSource.url"; private static final String PROPERTY_DB_URL = "VitroConnection.DataSource.url";

View file

@ -73,7 +73,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaModelMaker;
import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSDBModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSDBModelMaker;
import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSpecialModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSpecialModelMaker;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetup; import edu.cornell.mannlib.vitro.webapp.servlet.setup.WebappDaoSDBSetup;
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils; import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils; import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils;
import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils.MergeResult; import edu.cornell.mannlib.vitro.webapp.utils.jena.JenaIngestUtils.MergeResult;
@ -942,7 +942,7 @@ public class JenaIngestController extends BaseEditController {
log.debug("Connecting to DB at "+jdbcUrl); log.debug("Connecting to DB at "+jdbcUrl);
StoreDesc storeDesc = new StoreDesc(LayoutType.LayoutTripleNodesHash,dbTypeObj) ; StoreDesc storeDesc = new StoreDesc(LayoutType.LayoutTripleNodesHash,dbTypeObj) ;
ServletContext ctx = vreq.getSession().getServletContext(); ServletContext ctx = vreq.getSession().getServletContext();
BasicDataSource bds = JenaDataSourceSetup.makeBasicDataSource( BasicDataSource bds = WebappDaoSDBSetup.makeBasicDataSource(
driver, jdbcUrl, username, password, ctx); driver, jdbcUrl, username, password, ctx);
try { try {
VitroJenaSDBModelMaker vsmm = new VitroJenaSDBModelMaker(storeDesc, bds); VitroJenaSDBModelMaker vsmm = new VitroJenaSDBModelMaker(storeDesc, bds);

View file

@ -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" ; }
}

View file

@ -4,8 +4,8 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -15,9 +15,6 @@ import com.hp.hpl.jena.rdf.model.Literal;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.Precision; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.Precision;
import edu.cornell.mannlib.vitro.webapp.edit.elements.DateTimeWithPrecision;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfiguration;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.EditSubmission;
/* /*
* Assumption for date time interval validation: Only one start field/end field/and precision. * Assumption for date time interval validation: Only one start field/end field/and precision.
@ -133,7 +130,7 @@ public class DateTimeIntervalValidationVTwo implements N3ValidatorVTwo {
//Currently checks first precision str and then returns response //Currently checks first precision str and then returns response
if(precisionStr.size() > 0) { if(precisionStr.size() > 0) {
String precisionString = precisionStr.get(0); String precisionString = precisionStr.get(0);
VitroVocabulary.Precision precision = DateTimeWithPrecision.toPrecision( precisionString ); VitroVocabulary.Precision precision = DateTimeWithPrecisionVTwo.toPrecision( precisionString );
if( precision == null ) if( precision == null )
log.debug("cannot convert " + precisionStr + " to a precision"); log.debug("cannot convert " + precisionStr + " to a precision");
else else

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -18,14 +18,21 @@ import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.graph.Graph; import com.hp.hpl.jena.graph.Graph;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.sdb.Store;
import com.hp.hpl.jena.sdb.StoreDesc; import com.hp.hpl.jena.sdb.StoreDesc;
import com.hp.hpl.jena.sdb.store.DatabaseType; import com.hp.hpl.jena.sdb.store.DatabaseType;
import com.hp.hpl.jena.sdb.store.LayoutType; import com.hp.hpl.jena.sdb.store.LayoutType;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDaoCon; import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDaoCon;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDBGraphGenerator; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDBGraphGenerator;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RegeneratingGraph; import edu.cornell.mannlib.vitro.webapp.dao.jena.RegeneratingGraph;
@ -62,8 +69,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
protected static String USER_ABOX_PATH = BASE+"user/abox"; protected static String USER_ABOX_PATH = BASE+"user/abox";
protected static String USER_TBOX_PATH = BASE+"user/tbox"; protected static String USER_TBOX_PATH = BASE+"user/tbox";
protected static String USER_APPMETA_PATH = BASE+"user/applicationMetadata"; protected static String USER_APPMETA_PATH = BASE+"user/applicationMetadata";
protected static String SYSTEMPATH = BASE+"system/"; protected static String SYSTEMPATH = BASE+"system/";
protected static String AUTHPATH = BASE+"auth/";
public static String APPPATH = BASE+"app/"; public static String APPPATH = BASE+"app/";
//these files are loaded everytime the system starts up //these files are loaded everytime the system starts up
public static String APPPATH_LOAD = APPPATH + "menuload/"; public static String APPPATH_LOAD = APPPATH + "menuload/";
@ -418,7 +424,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
} else if (TripleStoreType.SDB.equals(type)) { } else if (TripleStoreType.SDB.equals(type)) {
StoreDesc storeDesc = new StoreDesc( StoreDesc storeDesc = new StoreDesc(
LayoutType.LayoutTripleNodesHash, DatabaseType.fetch(dbtypeStr)); LayoutType.LayoutTripleNodesHash, DatabaseType.fetch(dbtypeStr));
BasicDataSource bds = JenaDataSourceSetup.makeBasicDataSource( BasicDataSource bds = WebappDaoSDBSetup.makeBasicDataSource(
getDbDriverClassName(ctx), jdbcUrl, username, password, ctx); getDbDriverClassName(ctx), jdbcUrl, username, password, ctx);
bds.setMaxActive(4); // for now, the SDB model makers should not use more bds.setMaxActive(4); // for now, the SDB model makers should not use more
// than a small handful of connections // than a small handful of connections
@ -524,4 +530,68 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon {
"VitroConnection.DataSource.validationQuery", "SELECT 1"); "VitroConnection.DataSource.validationQuery", "SELECT 1");
} }
protected OntModel ontModelFromContextAttribute(ServletContext ctx,
String attribute) {
OntModel ontModel;
Object attributeValue = ctx.getAttribute(attribute);
if (attributeValue != null && attributeValue instanceof OntModel) {
ontModel = (OntModel) attributeValue;
} else {
ontModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
ctx.setAttribute(attribute, ontModel);
}
return ontModel;
}
protected static void repairAppMetadataModel(Model applicationMetadataModel,
Model aboxAssertions,
Model aboxInferences) {
log.info("Moving application metadata from ABox to dedicated model");
getAppMetadata(aboxAssertions, applicationMetadataModel);
getAppMetadata(aboxInferences, applicationMetadataModel);
aboxAssertions.remove(applicationMetadataModel);
aboxInferences.remove(applicationMetadataModel);
return;
}
protected static void getAppMetadata(Model source, Model target) {
String amdQuery = "DESCRIBE ?x WHERE { " +
"{?x a <" + VitroVocabulary.PORTAL +"> } UNION " +
"{?x a <" + VitroVocabulary.PROPERTYGROUP +"> } UNION " +
"{?x a <" + VitroVocabulary.CLASSGROUP +"> } } ";
try {
Query q = QueryFactory.create(amdQuery, Syntax.syntaxARQ);
QueryExecution qe = QueryExecutionFactory.create(q, source);
qe.execDescribe(target);
} catch (Exception e) {
log.error("unable to create the application metadata model",e);
}
return;
}
private static final String STOREDESC_ATTR = "storeDesc";
private static final String STORE_ATTR = "kbStore";
public static void setApplicationStoreDesc(StoreDesc storeDesc,
ServletContext ctx) {
ctx.setAttribute(STOREDESC_ATTR, storeDesc);
}
public static StoreDesc getApplicationStoreDesc(ServletContext ctx) {
return (StoreDesc) ctx.getAttribute(STOREDESC_ATTR);
}
public static void setApplicationStore(Store store,
ServletContext ctx) {
ctx.setAttribute(STORE_ATTR, store);
}
public static Store getApplicationStore(ServletContext ctx) {
return (Store) ctx.getAttribute(STORE_ATTR);
}
} }

View file

@ -2,11 +2,6 @@
package edu.cornell.mannlib.vitro.webapp.servlet.setup; package edu.cornell.mannlib.vitro.webapp.servlet.setup;
import static edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary.DISPLAY_ONT_MODEL;
import java.io.File;
import java.io.FileOutputStream;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; import javax.servlet.ServletContextListener;
@ -14,21 +9,18 @@ import javax.servlet.ServletContextListener;
import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;
import com.hp.hpl.jena.ontology.OntDocumentManager; import com.hp.hpl.jena.ontology.OntDocumentManager;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
* Create connection to DB and DataSource, put them in the context.
*/
public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
implements ServletContextListener { implements ServletContextListener {
@ -44,217 +36,13 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase
OntDocumentManager.getInstance().setProcessImports(false); OntDocumentManager.getInstance().setProcessImports(false);
BasicDataSource bds = makeDataSourceFromConfigurationProperties(ctx); BasicDataSource bds = makeDataSourceFromConfigurationProperties(ctx);
setApplicationDataSource(bds, ctx); setApplicationDataSource(bds, ctx);
// user accounts Model
try {
Model userAccountsDbModel = makeDBModel(bds,
JENA_USER_ACCOUNTS_MODEL, DB_ONT_MODEL_SPEC, ctx);
if (userAccountsDbModel.size() == 0) {
firstStartup = true;
readOntologyFilesInPathSet(AUTHPATH, ctx,
userAccountsDbModel);
}
OntModel userAccountsModel = ModelFactory.createOntologyModel(
MEM_ONT_MODEL_SPEC);
userAccountsModel.add(userAccountsDbModel);
userAccountsModel.getBaseModel().register(
new ModelSynchronizer(userAccountsDbModel));
ctx.setAttribute("userAccountsOntModel", userAccountsModel);
if (userAccountsModel.isEmpty()) {
initializeUserAccounts(ctx, userAccountsModel);
}
} catch (Throwable t) {
log.error("Unable to load user accounts model from DB", t);
ss.fatal(this, "Unable to load user accounts model from DB", t);
}
// display, editing and navigation Model
try {
Model displayDbModel = makeDBModel(bds,
JENA_DISPLAY_METADATA_MODEL, DB_ONT_MODEL_SPEC, ctx);
if (displayDbModel.size() == 0) {
readOntologyFilesInPathSet(APPPATH, ctx,displayDbModel);
}
OntModel displayModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC);
displayModel.add(displayDbModel);
displayModel.getBaseModel().register(new ModelSynchronizer(displayDbModel));
ctx.setAttribute(DISPLAY_ONT_MODEL, displayModel);
//at each startup load all RDF files from directory to sub-models of display model
initializeDisplayLoadedAtStartup(ctx, displayModel);
} catch (Throwable t) {
log.error("Unable to load user application configuration model", t);
ss.fatal(this, "Unable to load user application configuration model", t);
}
//display tbox - currently reading in every time
try {
Model displayTboxModel = makeDBModel(bds,
JENA_DISPLAY_TBOX_MODEL, DB_ONT_MODEL_SPEC, ctx);
//Reading in single file every time
//TODO: Check if original needs to be cleared/removed every time?
readOntologyFileFromPath(APPPATH_LOAD + "displayTBOX.n3", displayTboxModel, ctx);
OntModel appTBOXModel = ModelFactory.createOntologyModel(
MEM_ONT_MODEL_SPEC);
appTBOXModel.add(displayTboxModel);
appTBOXModel.getBaseModel().register(new ModelSynchronizer(displayTboxModel));
ctx.setAttribute("displayOntModelTBOX", appTBOXModel);
log.debug("Loaded file " + APPPATH_LOAD + "displayTBOX.n3 into display tbox model");
} catch (Throwable t) {
log.error("Unable to load user application configuration model TBOX", t);
ss.fatal(this, "Unable to load user application configuration model TBOX", t);
}
//Display Display model, currently empty, create if doesn't exist but no files to load
try {
Model displayDisplayModel = makeDBModel(bds,
JENA_DISPLAY_DISPLAY_MODEL, DB_ONT_MODEL_SPEC, ctx);
//Reading in single file every time
//TODO: Check if original needs to be cleared/removed every time?
readOntologyFileFromPath(APPPATH_LOAD + "displayDisplay.n3", displayDisplayModel, ctx);
OntModel appDisplayDisplayModel = ModelFactory.createOntologyModel(
MEM_ONT_MODEL_SPEC);
appDisplayDisplayModel.add(displayDisplayModel);
appDisplayDisplayModel.getBaseModel().register(new ModelSynchronizer(displayDisplayModel));
ctx.setAttribute("displayOntModelDisplayModel", appDisplayDisplayModel);
log.debug("Loaded file " + APPPATH_LOAD + "displayDisplay.n3 into display display model");
} catch (Throwable t) {
log.error("Unable to load user application configuration model Display Model", t);
ss.fatal(this, "Unable to load user application configuration model Display Model", t);
}
} }
@Override
@Override
public void contextDestroyed(ServletContextEvent sce) { public void contextDestroyed(ServletContextEvent sce) {
// Nothing to do. // Nothing to do.
} }
private void initializeUserAccounts(ServletContext ctx,
Model userAccountsModel) {
readOntologyFilesInPathSet(AUTHPATH, ctx, userAccountsModel);
}
/**
* Load the RDF found in the directory DISPLAY_MODEL_LOAD_AT_STARTUP_DIR
* a sub-models of displayModel. The RDF from thes files will not be saved
* in the database and it will be reloaded each time the system starts up.
*/
private void initializeDisplayLoadedAtStartup(ServletContext ctx, OntModel displayModel){
log.info("loading display model from files in " + ctx.getRealPath(DISPLAY_MODEL_LOAD_AT_STARTUP_DIR) );
Model displayLoadAtStartup = readInDisplayModelLoadAtStartup(ctx);
if( log.isDebugEnabled() ){
log.debug("loaded display model from files in " + ctx.getRealPath(DISPLAY_MODEL_LOAD_AT_STARTUP_DIR) );
displayLoadAtStartup.write(System.out, "N3-PP");
}
checkForOldListViews(ctx,displayModel,displayLoadAtStartup);
displayModel.addSubModel( displayLoadAtStartup );
}
/**
* All of the list views should now reside in files in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR.
* This will check for custom list view annotation statements in the displayModel, check
* if they exist in the files in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR, and write any that don't
* exist there to a file in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR. After that the statements
* will be removed from the displayDBModel.
*
* returns true if there were old list view statements in the DB, returns false
* if there were none. displayLoadAlways should be reloaded from the file system
* if this returns true as this method may have changed the files.
*
* displayLoadAtStartup and displayModel may be modified.
*/
private void checkForOldListViews( ServletContext ctx, OntModel displayModel, Model displayLoadAtStartup){
// run construct for old custom list view statements from displayModel
Model oldListViewModel = getOldListViewStatements( displayModel );
if( log.isDebugEnabled() ){
log.debug("Printing the old list view statements from the display model to System.out.");
oldListViewModel.write(System.out,"N3-PP");
}
// find statements in old stmts that are not in loadedAtStartup and
// save them in a new file in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR
// so that in the future they will be in loadedAtStartup
Model stmtsInOldAndFiles = displayLoadAtStartup.intersection( displayModel );
Model unhandledOldListViewStmts = oldListViewModel.difference( stmtsInOldAndFiles );
boolean saved = false;
boolean neededSave = false;
if( unhandledOldListViewStmts != null && !unhandledOldListViewStmts.isEmpty() ){
log.debug("need to deal with old list view statements from the display model");
neededSave = true;
try{
//create a file for the old statements in the loadAtStartup directory
String newFileName = ctx.getRealPath(
DISPLAY_MODEL_LOAD_AT_STARTUP_DIR + File.separator
+ new DateTime().toString(ISODateTimeFormat.basicDateTime()) + ".n3" );
File file = new File( newFileName );
file.createNewFile();
log.info("Relocating " + unhandledOldListViewStmts.size() + " custom list view statements from DB and saving to "
+ file.getAbsolutePath()+ File.separator + file.getName()
+ ". These will be loaded from this file when the system starts up.");
FileOutputStream fileOut = new FileOutputStream(file);
unhandledOldListViewStmts.write(fileOut, "N3-PP");
fileOut.close();
saved = true;
}catch(Throwable th){
log.warn("Could not save old list view statements. Leaving them in the DB",th);
}
//need to reload displayLoadAlways because DISPLAY_MODEL_LOAD_AT_STARTUP_DIR may have changed
displayLoadAtStartup.removeAll().add(readInDisplayModelLoadAtStartup(ctx));
}
if( oldListViewModel != null && ! oldListViewModel.isEmpty() ){
//At this point, there are old list view statements in the DB but they
//should are all redundant with ones in DISPLAY_MODEL_LOAD_AT_STARTUP_DIR
if( (neededSave && saved) || (!neededSave) ){
//if there was nothing to save, just remove the old stuff
//if there was stuff to save, only remove if it was saved.
log.debug("removing old statements from displayModel");
displayModel.remove(oldListViewModel);
}
}
}
private Model getOldListViewStatements(OntModel displayModel) {
//run a construct on displayModel to get all list view statements
Query query = QueryFactory.create ( listViewQuery );
QueryExecution qexec = QueryExecutionFactory.create(query, displayModel) ;
Model oldModel = null;
try {
oldModel = qexec.execConstruct();
} catch( Throwable th ){
log.error("could not check for old custom list views, query exception",th);
}finally {
qexec.close() ;
}
if( oldModel != null)
return oldModel;
else
return ModelFactory.createDefaultModel();
}
private static final String listViewQuery = "" +
"PREFIX d: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#>\n" +
"CONSTRUCT { \n" +
" ?a d:listViewConfigFile ?b . \n" +
"} WHERE {\n" +
" ?a d:listViewConfigFile ?b . \n" +
"} ";
protected Model readInDisplayModelLoadAtStartup( ServletContext ctx ){
return getModelFromDir( new File( ctx.getRealPath( DISPLAY_MODEL_LOAD_AT_STARTUP_DIR )));
}
} }

View file

@ -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.
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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 ");
}
}

View file

@ -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"));
}
}

View file

@ -7,18 +7,22 @@
edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSetup edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.BasicSmokeTests edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSmokeTests
edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup
edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory$Setup
# Comment out this listener to run Vitro without a database ### this listener must be run before SDBSetup, all models setups and WebappDaoSetup ###
# If used, this listener must be run before JenaDataSourceSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaPersistentDataSourceSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaPersistentDataSourceSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.SDBSetup
# This listener is required in order to use a Jena triple store (currently the only option) edu.cornell.mannlib.vitro.webapp.servlet.setup.ApplicationModelSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.UserModelSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.ModelSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.WebappDaoSDBSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase