various dev work on language filtering and querying from a generic endpoint

This commit is contained in:
brianjlowe 2012-04-11 16:27:54 +00:00
commit 376c7be7c3
110 changed files with 2372 additions and 3963 deletions

View file

@ -116,6 +116,16 @@ deploy - Deploy the application directly into the Tomcat webapps directory.
</condition> </condition>
</fail> </fail>
<fail message="The vitro.home.directory &quot;${vitro.home.directory}&quot; is not writable.">
<condition>
<not>
<isfileselected file="${vitro.home.directory}" >
<writable/>
</isfileselected>
</not>
</condition>
</fail>
<property name="solr.home.dir" location="${vitro.home.directory}/solr" /> <property name="solr.home.dir" location="${vitro.home.directory}/solr" />
</target> </target>

View file

@ -133,6 +133,9 @@ webapp/web/WEB-INF/tlds/taglibs-string.tld
webapp/web/themes/enhanced/css/blueprint/grid.css webapp/web/themes/enhanced/css/blueprint/grid.css
webapp/web/themes/enhanced/css/blueprint/ie.css webapp/web/themes/enhanced/css/blueprint/ie.css
# See /doc/3rd-party-licenses.txt for LICENSE file
webapp/web/css/jquery_plugins/jquery.realperson.css
# PROBLEM: Can't find any info on licensing. # PROBLEM: Can't find any info on licensing.
webapp/web/themes/enhanced/css/blueprint/liquid.css webapp/web/themes/enhanced/css/blueprint/liquid.css

View file

@ -441,14 +441,14 @@ public class OperationController extends BaseEditController {
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
log.error(this.getClass().getName()+" encountered exception performing two-stage update"); log.error(this.getClass().getName()+" encountered exception performing two-stage update");
Throwable innerE = e.getTargetException(); Throwable innerE = e.getTargetException();
log.error(innerE); log.error(innerE, innerE);
if (innerE.getMessage()!=null) { if (innerE.getMessage()!=null) {
log.error(innerE.getMessage()); //log.error(innerE.getMessage());
epo.setAttribute("globalErrorMsg",innerE.getMessage()); epo.setAttribute("globalErrorMsg",innerE.getMessage());
} }
return FAILURE; return FAILURE;
} catch (IllegalAccessException iae) { } catch (IllegalAccessException iae) {
log.error(iae); log.error(iae, iae);
epo.setAttribute("globalErrorMessage", "Illegal access - see error logs."); epo.setAttribute("globalErrorMessage", "Illegal access - see error logs.");
return FAILURE; return FAILURE;
} }
@ -459,15 +459,15 @@ public class OperationController extends BaseEditController {
log.error(this.getClass().getName()+" encountered exception performing edit action"); log.error(this.getClass().getName()+" encountered exception performing edit action");
Throwable innerE = e.getTargetException(); Throwable innerE = e.getTargetException();
//innerE.printStackTrace(); //innerE.printStackTrace();
log.error(innerE); log.error(innerE, innerE);
if (innerE.getMessage()!=null) { if (innerE.getMessage()!=null) {
//System.out.println(innerE.getMessage()); //System.out.println(innerE.getMessage());
log.error(innerE.getMessage()); //log.error(innerE.getMessage());
epo.setAttribute("globalErrorMsg",innerE.getMessage()); epo.setAttribute("globalErrorMsg",innerE.getMessage());
} }
return FAILURE; return FAILURE;
} catch (IllegalAccessException iae) { } catch (IllegalAccessException iae) {
log.error(iae); log.error(iae, iae);
epo.setAttribute("globalErrorMessage", "Illegal access - see error logs."); epo.setAttribute("globalErrorMessage", "Illegal access - see error logs.");
return FAILURE; return FAILURE;
} }

View file

@ -84,6 +84,8 @@ public class SimplePermission extends Permission {
"UseMiscellaneousEditorPages"); "UseMiscellaneousEditorPages");
public static final SimplePermission USE_MISCELLANEOUS_PAGES = new SimplePermission( public static final SimplePermission USE_MISCELLANEOUS_PAGES = new SimplePermission(
"UseMiscellaneousPages"); "UseMiscellaneousPages");
public static final SimplePermission USE_SPARQL_QUERY_PAGE = new SimplePermission(
"UseSparqlQueryPage");
public static List<SimplePermission> getAllInstances() { public static List<SimplePermission> getAllInstances() {
return new ArrayList<SimplePermission>(allInstances.values()); return new ArrayList<SimplePermission>(allInstances.values());

View file

@ -7,10 +7,6 @@ public interface ObjectPropertyStatement {
public String toString(); public String toString();
public boolean isSubjectOriented();
public void setSubjectOriented(boolean subjectOriented);
public String getSubjectURI(); public String getSubjectURI();
public void setSubjectURI(String subjectURI); public void setSubjectURI(String subjectURI);

View file

@ -18,9 +18,7 @@ public class ObjectPropertyStatementImpl implements ObjectPropertyStatement
private String propertyURI = null; private String propertyURI = null;
private ObjectProperty property = null; private ObjectProperty property = null;
private String qualifier = null;
private boolean subjectOriented = true; //is the range the item of interest? private boolean subjectOriented = true; //is the range the item of interest?
private String description = null; //generated desc based on subjectOriented during sql query.
public ObjectPropertyStatementImpl() { } public ObjectPropertyStatementImpl() { }
@ -37,23 +35,7 @@ public class ObjectPropertyStatementImpl implements ObjectPropertyStatement
String prop = (getProperty()!=null)?getProperty().getDomainPublic():"by propURI"+getPropertyURI(); String prop = (getProperty()!=null)?getProperty().getDomainPublic():"by propURI"+getPropertyURI();
String ran = (getObject()!= null)?getObject().getName():"objectURI:"+getObjectURI(); String ran = (getObject()!= null)?getObject().getName():"objectURI:"+getObjectURI();
String dom = (getSubject()!= null)?getSubject().getName():"subjectURI:"+getSubjectURI(); String dom = (getSubject()!= null)?getSubject().getName():"subjectURI:"+getSubjectURI();
String orent = (isSubjectOriented() )?"subject oriented":"object oriented"; return "Object Property Statements: "+dom+" "+prop+" to "+ran+" ";
return "Object Property Statements: "+dom+" "+prop+" to "+ran+" "+orent;
}
/* (non-Javadoc)
* @see edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement#isSubjectOriented()
*/
public boolean isSubjectOriented() {
return subjectOriented;
}
/* (non-Javadoc)
* @see edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement#setSubjectOriented(boolean)
*/
public void setSubjectOriented(boolean subjectOriented) {
this.subjectOriented = subjectOriented;
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -100,6 +82,11 @@ public class ObjectPropertyStatementImpl implements ObjectPropertyStatement
*/ */
public void setSubject(Individual subject) { public void setSubject(Individual subject) {
this.subject = subject; this.subject = subject;
if (subject == null || subject.isAnonymous()) {
setSubjectURI(null);
} else {
setSubjectURI(subject.getURI());
}
} }
@ -136,6 +123,11 @@ public class ObjectPropertyStatementImpl implements ObjectPropertyStatement
*/ */
public void setObject(Individual object) { public void setObject(Individual object) {
this.object = object; this.object = object;
if (object == null || object.isAnonymous()) {
setObjectURI(null);
} else {
setObjectURI(object.getURI());
}
} }

View file

@ -133,8 +133,14 @@ public class VClass extends BaseResourceBean implements Comparable<VClass>
* Sorts alphabetically by name * Sorts alphabetically by name
*/ */
public int compareTo (VClass o1) { public int compareTo (VClass o1) {
Collator collator = Collator.getInstance(); if (this.getName() == null) {
return collator.compare(this.getName(),o1.getName()); return 1;
} else if (o1.getName() == null) {
return -1;
} else {
Collator collator = Collator.getInstance();
return collator.compare(this.getName(),o1.getName());
}
} }
/** /**

View file

@ -128,8 +128,6 @@ public class MailUsersServlet extends VitroHttpServlet {
msgBuf.append("</html>" + lineSeparator ); msgBuf.append("</html>" + lineSeparator );
String msgText = msgBuf.toString(); String msgText = msgBuf.toString();
// debugging
//PrintWriter outFile = new PrintWriter (new FileWriter(request.getSession().getServletContext().getRealPath("/WEB-INF/LatestMessage.html"),true)); //autoflush
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();

View file

@ -101,7 +101,7 @@ public class SparqlQueryServlet extends BaseEditController {
throws ServletException, IOException throws ServletException, IOException
{ {
if (!isAuthorizedToDisplayPage(request, response, if (!isAuthorizedToDisplayPage(request, response,
SimplePermission.USE_ADVANCED_DATA_TOOLS_PAGES.ACTIONS)) { SimplePermission.USE_SPARQL_QUERY_PAGE.ACTIONS)) {
return; return;
} }

View file

@ -19,6 +19,7 @@ import com.hp.hpl.jena.query.Dataset;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDao; import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDao;
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource.ModelName; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource.ModelName;
public class VitroRequest extends HttpServletRequestWrapper { public class VitroRequest extends HttpServletRequestWrapper {
@ -78,6 +79,10 @@ public class VitroRequest extends HttpServletRequestWrapper {
setAttribute("jenaOntModel", ontModel); setAttribute("jenaOntModel", ontModel);
} }
public void setOntModelSelector(OntModelSelector oms) {
setAttribute("ontModelSelector", oms);
}
/** gets assertions + inferences WebappDaoFactory with no filtering **/ /** gets assertions + inferences WebappDaoFactory with no filtering **/
public WebappDaoFactory getFullWebappDaoFactory() { public WebappDaoFactory getFullWebappDaoFactory() {
Object webappDaoFactoryAttr = _req.getAttribute("fullWebappDaoFactory"); Object webappDaoFactoryAttr = _req.getAttribute("fullWebappDaoFactory");
@ -97,12 +102,26 @@ public class VitroRequest extends HttpServletRequestWrapper {
public WebappDaoFactory getAssertionsWebappDaoFactory() { public WebappDaoFactory getAssertionsWebappDaoFactory() {
Object webappDaoFactoryAttr = _req.getSession().getAttribute("assertionsWebappDaoFactory"); Object webappDaoFactoryAttr = _req.getSession().getAttribute("assertionsWebappDaoFactory");
if (webappDaoFactoryAttr instanceof WebappDaoFactory) { if (webappDaoFactoryAttr instanceof WebappDaoFactory) {
log.info("Returning assertionsWebappDaoFactory from session");
return (WebappDaoFactory) webappDaoFactoryAttr; return (WebappDaoFactory) webappDaoFactoryAttr;
} else { } else {
return (WebappDaoFactory) _req.getSession().getServletContext().getAttribute("assertionsWebappDaoFactory"); webappDaoFactoryAttr = getAttribute("assertionsWebappDaoFactory");
if (webappDaoFactoryAttr instanceof WebappDaoFactory) {
log.info("returning assertionsWebappDaoFactory from request attribute");
return (WebappDaoFactory) webappDaoFactoryAttr;
} else {
log.info("Returning assertionsWebappDaoFactory from context");
return (WebappDaoFactory) _req.getSession().getServletContext().getAttribute("assertionsWebappDaoFactory");
}
} }
} }
/** gets assertions-only WebappDaoFactory with no filtering */
public void setAssertionsWebappDaoFactory(WebappDaoFactory wadf) {
setAttribute("assertionsWebappDaoFactory", wadf);
}
/** gets inferences-only WebappDaoFactory with no filtering */ /** gets inferences-only WebappDaoFactory with no filtering */
public WebappDaoFactory getDeductionsWebappDaoFactory() { public WebappDaoFactory getDeductionsWebappDaoFactory() {
Object webappDaoFactoryAttr = _req.getSession().getAttribute("deductionsWebappDaoFactory"); Object webappDaoFactoryAttr = _req.getSession().getAttribute("deductionsWebappDaoFactory");
@ -137,6 +156,16 @@ public class VitroRequest extends HttpServletRequestWrapper {
return jenaOntModel; return jenaOntModel;
} }
public OntModelSelector getOntModelSelector() {
Object o = this.getAttribute("ontModelSelector");
if (o instanceof OntModelSelector) {
return (OntModelSelector) o;
} else {
return null;
}
}
public OntModel getAssertionsOntModel() { public OntModel getAssertionsOntModel() {
OntModel jenaOntModel = (OntModel)_req.getSession().getAttribute( JenaBaseDao.ASSERTIONS_ONT_MODEL_ATTRIBUTE_NAME ); OntModel jenaOntModel = (OntModel)_req.getSession().getAttribute( JenaBaseDao.ASSERTIONS_ONT_MODEL_ATTRIBUTE_NAME );
if ( jenaOntModel == null ) { if ( jenaOntModel == null ) {

View file

@ -35,9 +35,6 @@ public abstract class UserAccountsPage extends AbstractPageHandler {
private static final String PERSON_CLASS_URI = "http://xmlns.com/foaf/0.1/Person"; private static final String PERSON_CLASS_URI = "http://xmlns.com/foaf/0.1/Person";
private static final String DEFAULT_IMAGE_URL = UrlBuilder
.getUrl("/images/placeholders/person.thumbnail.jpg");
/** /**
* After the account is created, or the password is reset, the user has this * After the account is created, or the password is reset, the user has this
* many days to repond to the email. * many days to repond to the email.
@ -109,7 +106,6 @@ public abstract class UserAccountsPage extends AbstractPageHandler {
UrlBuilder.getUrl("/accounts/firstTimeExternal")); UrlBuilder.getUrl("/accounts/firstTimeExternal"));
map.put("accountsAjax", UrlBuilder.getUrl("/accountsAjax")); map.put("accountsAjax", UrlBuilder.getUrl("/accountsAjax"));
map.put("proxyAjax", UrlBuilder.getUrl("/proxiesAjax")); map.put("proxyAjax", UrlBuilder.getUrl("/proxiesAjax"));
map.put("defaultImageUrl", DEFAULT_IMAGE_URL);
return map; return map;
} }

View file

@ -237,6 +237,7 @@ public class UserAccountsEditPage extends UserAccountsPage {
if (!isRootUser()) { if (!isRootUser()) {
body.put("roles", buildListOfSelectableRoles()); body.put("roles", buildListOfSelectableRoles());
body.put("externalAuthPermitted", Boolean.TRUE);
} }
body.put("profileTypes", buildProfileTypesList()); body.put("profileTypes", buildProfileTypesList());

View file

@ -24,7 +24,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.utils.ImageUtil; import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
/** /**
* TODO * TODO
@ -134,8 +134,8 @@ public class ManageProxiesListPage extends AbstractPageHandler {
private ProxyItemInfo wrapProxyItem(ProxyItemInfo item) { private ProxyItemInfo wrapProxyItem(ProxyItemInfo item) {
String imagePath = item.getImageUrl(); String imagePath = item.getImageUrl();
if (imagePath.isEmpty()) { if (imagePath.isEmpty()) {
imagePath = ImageUtil imagePath = PlaceholderUtil.getPlaceholderImagePathForType(vreq,
.getPlaceholderImagePathForType(VitroVocabulary.USERACCOUNT); VitroVocabulary.USERACCOUNT);
} }
UserAccount ua = userAccountsDao.getUserAccountByUri(item.getUri()); UserAccount ua = userAccountsDao.getUserAccountByUri(item.getUri());
@ -151,8 +151,8 @@ public class ManageProxiesListPage extends AbstractPageHandler {
private ProxyItemInfo wrapProfileItem(ProxyItemInfo item) { private ProxyItemInfo wrapProfileItem(ProxyItemInfo item) {
String imagePath = item.getImageUrl(); String imagePath = item.getImageUrl();
if (imagePath.isEmpty()) { if (imagePath.isEmpty()) {
imagePath = ImageUtil.getPlaceholderImagePathForIndividual(vreq, imagePath = PlaceholderUtil.getPlaceholderImagePathForIndividual(
item.getUri()); vreq, item.getUri());
} }
return new ProfileItemWrapper(item.getUri(), item.getLabel(), return new ProfileItemWrapper(item.getUri(), item.getLabel(),

View file

@ -24,9 +24,9 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; 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.ModelContext;
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
import edu.cornell.mannlib.vitro.webapp.utils.ImageUtil;
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner; import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils; import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
/** /**
* Get the basic auto-complete info for the proxy selection. * Get the basic auto-complete info for the proxy selection.
@ -64,8 +64,9 @@ public class BasicProxiesGetter extends AbstractAjaxResponder {
OntModelSelector oms = ModelContext.getUnionOntModelSelector(ctx); OntModelSelector oms = ModelContext.getUnionOntModelSelector(ctx);
userAccountsModel = oms.getUserAccountsModel(); userAccountsModel = oms.getUserAccountsModel();
placeholderImageUrl = UrlBuilder.getUrl(ImageUtil placeholderImageUrl = UrlBuilder.getUrl(PlaceholderUtil
.getPlaceholderImagePathForType(VitroVocabulary.USERACCOUNT)); .getPlaceholderImagePathForType(vreq,
VitroVocabulary.USERACCOUNT));
} }
@Override @Override

View file

@ -19,7 +19,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.ajax.AbstractAjaxResponder; import edu.cornell.mannlib.vitro.webapp.controller.ajax.AbstractAjaxResponder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.utils.ImageUtil; import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
/** /**
* Get more information (class label and image URL) about a selected proxy. * Get more information (class label and image URL) about a selected proxy.
@ -79,7 +79,7 @@ public class MoreProfileInfo extends AbstractAjaxResponder {
private String getFullImageUrl(Individual ind) { private String getFullImageUrl(Individual ind) {
String path = ind.getThumbUrl(); String path = ind.getThumbUrl();
if ((path == null) || path.isEmpty()) { if ((path == null) || path.isEmpty()) {
path = ImageUtil.getPlaceholderImagePathForIndividual(vreq, path = PlaceholderUtil.getPlaceholderImagePathForIndividual(vreq,
ind.getURI()); ind.getURI());
} }
return UrlBuilder.getUrl(path); return UrlBuilder.getUrl(path);

View file

@ -26,6 +26,8 @@ import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
/** /**
* Handle the "My Account" form display and submission. * Handle the "My Account" form display and submission.
@ -268,7 +270,9 @@ public class UserAccountsMyAccountPage extends UserAccountsPage {
String userUri = proxyUser.getUri(); String userUri = proxyUser.getUri();
String label = assembleUserAccountLabel(proxyUser); String label = assembleUserAccountLabel(proxyUser);
String classLabel = ""; String classLabel = "";
String imageUrl = ""; String imageUrl = UrlBuilder.getUrl(PlaceholderUtil
.getPlaceholderImagePathForType(vreq,
VitroVocabulary.USERACCOUNT));
// Does this user have a profile? Can we get better info? // Does this user have a profile? Can we get better info?
Individual proxyProfilePage = getProfilePage(proxyUser); Individual proxyProfilePage = getProfilePage(proxyUser);

View file

@ -16,7 +16,6 @@ import edu.cornell.mannlib.vedit.controller.BaseEditController;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes; import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
public class Classes2ClassesOperationController extends BaseEditController { public class Classes2ClassesOperationController extends BaseEditController {
@ -58,7 +57,6 @@ public class Classes2ClassesOperationController extends BaseEditController {
return; return;
} }
Classes2ClassesDao dao = request.getFullWebappDaoFactory().getClasses2ClassesDao();
VClassDao vcDao = request.getFullWebappDaoFactory().getVClassDao(); VClassDao vcDao = request.getFullWebappDaoFactory().getVClassDao();
String modeStr = request.getParameter("opMode"); String modeStr = request.getParameter("opMode");
@ -81,7 +79,7 @@ public class Classes2ClassesOperationController extends BaseEditController {
Classes2Classes c2c = new Classes2Classes(); Classes2Classes c2c = new Classes2Classes();
c2c.setSubclassURI(subclassURIstrs[i]); c2c.setSubclassURI(subclassURIstrs[i]);
c2c.setSuperclassURI(superclassURIstr); c2c.setSuperclassURI(superclassURIstr);
dao.deleteClasses2Classes(c2c); vcDao.deleteClasses2Classes(c2c);
} }
} }
} }
@ -98,7 +96,7 @@ public class Classes2ClassesOperationController extends BaseEditController {
Classes2Classes c2c = new Classes2Classes(); Classes2Classes c2c = new Classes2Classes();
c2c.setSuperclassURI(superclassURIstrs[i]); c2c.setSuperclassURI(superclassURIstrs[i]);
c2c.setSubclassURI(subclassURIstr); c2c.setSubclassURI(subclassURIstr);
dao.deleteClasses2Classes(c2c); vcDao.deleteClasses2Classes(c2c);
} }
} }
} }
@ -112,7 +110,7 @@ public class Classes2ClassesOperationController extends BaseEditController {
Classes2Classes c2c = new Classes2Classes(); Classes2Classes c2c = new Classes2Classes();
c2c.setSuperclassURI(request.getParameter("SuperclassURI")); c2c.setSuperclassURI(request.getParameter("SuperclassURI"));
c2c.setSubclassURI(request.getParameter("SubclassURI")); c2c.setSubclassURI(request.getParameter("SubclassURI"));
dao.insertNewClasses2Classes(c2c); vcDao.insertNewClasses2Classes(c2c);
} }
} }
} catch (Exception e) { } catch (Exception e) {

View file

@ -19,7 +19,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes; import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
public class Classes2ClassesRetryController extends BaseEditController { public class Classes2ClassesRetryController extends BaseEditController {
@ -44,9 +43,8 @@ public class Classes2ClassesRetryController extends BaseEditController {
action = epo.getAction(); action = epo.getAction();
} }
Classes2ClassesDao c2cDao = request.getFullWebappDaoFactory().getClasses2ClassesDao();
VClassDao vcDao = request.getFullWebappDaoFactory().getVClassDao(); VClassDao vcDao = request.getFullWebappDaoFactory().getVClassDao();
epo.setDataAccessObject(c2cDao); epo.setDataAccessObject(vcDao);
Classes2Classes objectForEditing = new Classes2Classes(); Classes2Classes objectForEditing = new Classes2Classes();
String superclassURIstr = request.getParameter("SuperclassURI"); String superclassURIstr = request.getParameter("SuperclassURI");

View file

@ -48,6 +48,7 @@ public class EntityEditController extends BaseEditController {
VitroRequest vreq = (new VitroRequest(request)); VitroRequest vreq = (new VitroRequest(request));
ApplicationBean application = vreq.getAppBean(); ApplicationBean application = vreq.getAppBean();
//Individual ent = vreq.getWebappDaoFactory().getIndividualDao().getIndividualByURI(entURI);
Individual ent = vreq.getAssertionsWebappDaoFactory().getIndividualDao().getIndividualByURI(entURI); Individual ent = vreq.getAssertionsWebappDaoFactory().getIndividualDao().getIndividualByURI(entURI);
if (ent == null) { if (ent == null) {
try { try {

View file

@ -78,7 +78,11 @@ public class EntityRetryController extends BaseEditController {
action = epo.getAction(); action = epo.getAction();
} }
WebappDaoFactory wadf = (vreq.getAssertionsWebappDaoFactory()!=null) ? vreq.getAssertionsWebappDaoFactory() : vreq.getFullWebappDaoFactory(); WebappDaoFactory wadf = vreq.getAssertionsWebappDaoFactory();
if (wadf == null) {
log.info("Using vreq.getFullWebappDaoFactory()");
vreq.getFullWebappDaoFactory();
}
LoginStatusBean loginBean = LoginStatusBean.getBean(request); LoginStatusBean loginBean = LoginStatusBean.getBean(request);
WebappDaoFactory myWebappDaoFactory = wadf.getUserAwareDaoFactory(loginBean.getUserURI()); WebappDaoFactory myWebappDaoFactory = wadf.getUserAwareDaoFactory(loginBean.getUserURI());

View file

@ -197,7 +197,7 @@ public class VclassRetryController extends BaseEditController {
Classes2Classes c2c = new Classes2Classes(); Classes2Classes c2c = new Classes2Classes();
c2c.setSubclassURI(((VClass)newObj).getURI()); c2c.setSubclassURI(((VClass)newObj).getURI());
c2c.setSuperclassURI(superclassURI); c2c.setSuperclassURI(superclassURI);
daoFactory.getClasses2ClassesDao().insertNewClasses2Classes(c2c); daoFactory.getVClassDao().insertNewClasses2Classes(c2c);
} }
public void doUpdated(Object oldObj, Object newObj, EditProcessObject epo) { public void doUpdated(Object oldObj, Object newObj, EditProcessObject epo) {
// nothing to do // nothing to do

View file

@ -198,9 +198,11 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet {
urls.put("ingest", UrlBuilder.getUrl("/ingest")); urls.put("ingest", UrlBuilder.getUrl("/ingest"));
urls.put("rdfData", UrlBuilder.getUrl("/uploadRDFForm")); urls.put("rdfData", UrlBuilder.getUrl("/uploadRDFForm"));
urls.put("rdfExport", UrlBuilder.getUrl("/export")); urls.put("rdfExport", UrlBuilder.getUrl("/export"));
urls.put("sparqlQuery", UrlBuilder.getUrl("/admin/sparqlquery"));
urls.put("sparqlQueryBuilder", UrlBuilder.getUrl("/admin/sparqlquerybuilder")); urls.put("sparqlQueryBuilder", UrlBuilder.getUrl("/admin/sparqlquerybuilder"));
} }
if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.USE_SPARQL_QUERY_PAGE.ACTIONS)) {
urls.put("sparqlQuery", UrlBuilder.getUrl("/admin/sparqlquery"));
}
return urls; return urls;
} }

View file

@ -2,6 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.controller.freemarker; package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -25,6 +26,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
@ -38,7 +40,6 @@ public class ContactMailController extends FreemarkerHttpServlet {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final static String SPAM_MESSAGE = "Your message was flagged as spam."; private final static String SPAM_MESSAGE = "Your message was flagged as spam.";
private final static String EMAIL_BACKUP_FILE_PATH = "/WEB-INF/LatestMessage.html";
private final static String WEB_USERNAME_PARAM = "webusername"; private final static String WEB_USERNAME_PARAM = "webusername";
private final static String WEB_USEREMAIL_PARAM = "webuseremail"; private final static String WEB_USEREMAIL_PARAM = "webuseremail";
@ -48,6 +49,11 @@ public class ContactMailController extends FreemarkerHttpServlet {
private final static String TEMPLATE_EMAIL = "contactForm-email.ftl"; private final static String TEMPLATE_EMAIL = "contactForm-email.ftl";
private final static String TEMPLATE_BACKUP = "contactForm-backup.ftl"; private final static String TEMPLATE_BACKUP = "contactForm-backup.ftl";
private final static String TEMPLATE_ERROR = "contactForm-error.ftl"; private final static String TEMPLATE_ERROR = "contactForm-error.ftl";
private final static String TEMPLATE_FORM = "contactForm-form.ftl";
private static final String PROPERTY_VITRO_HOME_DIR = "vitro.home.directory";
private static final String EMAIL_JOURNAL_FILE_DIR = "emailJournal";
private static final String EMAIL_JOURNAL_FILE_NAME = "contactFormEmails.html";
@Override @Override
protected String getTitle(String siteName, VitroRequest vreq) { protected String getTitle(String siteName, VitroRequest vreq) {
@ -70,9 +76,13 @@ public class ContactMailController extends FreemarkerHttpServlet {
String webuseremail = nonNullAndTrim(vreq, WEB_USEREMAIL_PARAM); String webuseremail = nonNullAndTrim(vreq, WEB_USEREMAIL_PARAM);
String comments = nonNullAndTrim(vreq, COMMENTS_PARAM); String comments = nonNullAndTrim(vreq, COMMENTS_PARAM);
String formType = nonNullAndTrim(vreq, "DeliveryType"); String formType = nonNullAndTrim(vreq, "DeliveryType");
String captchaInput = nonNullAndTrim(vreq, "defaultReal");
String captchaDisplay = nonNullAndTrim(vreq, "defaultRealHash");
if (validateInput(webusername, webuseremail, comments) != null) { String errorMsg = validateInput(webusername, webuseremail, comments, captchaInput, captchaDisplay);
return errorParametersNotValid();
if ( errorMsg != null) {
return errorParametersNotValid(errorMsg, webusername, webuseremail, comments);
} }
String spamReason = checkForSpam(comments, formType); String spamReason = checkForSpam(comments, formType);
@ -107,14 +117,14 @@ public class ContactMailController extends FreemarkerHttpServlet {
deliveryfrom, originalReferer, vreq.getRemoteAddr(), config, vreq); deliveryfrom, originalReferer, vreq.getRemoteAddr(), config, vreq);
try { try {
// Write the email to a backup file // Write the message to the journal file
FileWriter fw = new FileWriter(getServletContext().getRealPath(EMAIL_BACKUP_FILE_PATH),true); FileWriter fw = new FileWriter(locateTheJournalFile(vreq),true);
PrintWriter outFile = new PrintWriter(fw); PrintWriter outFile = new PrintWriter(fw);
writeBackupCopy(outFile, msgText, config, vreq); writeBackupCopy(outFile, msgText, config, vreq);
Session s = FreemarkerEmailFactory.getEmailSession(vreq);
try { try {
// Send the message
Session s = FreemarkerEmailFactory.getEmailSession(vreq);
sendMessage(s, webuseremail, webusername, recipients, deliveryfrom, msgText); sendMessage(s, webuseremail, webusername, recipients, deliveryfrom, msgText);
} catch (AddressException e) { } catch (AddressException e) {
statusMsg = "Please supply a valid email address."; statusMsg = "Please supply a valid email address.";
@ -147,6 +157,40 @@ public class ContactMailController extends FreemarkerHttpServlet {
} }
} }
/**
* The journal file belongs in a sub-directory of the Vitro home directory.
* If the sub-directory doesn't exist, create it.
*/
private File locateTheJournalFile(VitroRequest vreq) {
String homeDirPath = ConfigurationProperties.getBean(vreq).getProperty(
PROPERTY_VITRO_HOME_DIR);
if (homeDirPath == null) {
throw new IllegalArgumentException(
"Configuration properties must contain a value for '"
+ PROPERTY_VITRO_HOME_DIR + "'");
}
File homeDir = new File(homeDirPath);
if (!homeDir.exists()) {
throw new IllegalStateException("Vitro home directory '"
+ homeDir.getAbsolutePath() + "' does not exist.");
}
File journalDir = new File(homeDir, EMAIL_JOURNAL_FILE_DIR);
if (!journalDir.exists()) {
boolean created = journalDir.mkdir();
if (!created) {
throw new IllegalStateException(
"Unable to create email journal directory at '"
+ journalDir + "'");
}
}
File journalFile = new File(journalDir, EMAIL_JOURNAL_FILE_NAME);
return journalFile;
}
private String getOriginalRefererFromSession(VitroRequest vreq) { private String getOriginalRefererFromSession(VitroRequest vreq) {
String originalReferer = (String) vreq.getSession().getAttribute("contactFormReferer"); String originalReferer = (String) vreq.getSession().getAttribute("contactFormReferer");
if (originalReferer != null) { if (originalReferer != null) {
@ -263,20 +307,28 @@ public class ContactMailController extends FreemarkerHttpServlet {
} }
private String validateInput(String webusername, String webuseremail, private String validateInput(String webusername, String webuseremail,
String comments) { String comments, String captchaInput, String captchaDisplay) {
if( webusername.isEmpty() ){ if( webusername.isEmpty() ){
return "A proper webusername field was not found in the form submitted."; return "Please enter a value in the Full name field.";
} }
if( webuseremail.isEmpty() ){ if( webuseremail.isEmpty() ){
return "A proper webuser email field was not found in the form submitted."; return "Please enter a valid email address.";
} }
if (comments.isEmpty()) { if (comments.isEmpty()) {
return "The proper comments field was not found in the form submitted."; return "Please enter your comments or questions in the space provided.";
} }
if (captchaInput.isEmpty()) {
return "Please enter the contents of the gray box in the security field provided.";
}
if ( !captchaHash(captchaInput).equals(captchaDisplay) ) {
return "The value you entered in the security field did not match the letters displayed in the gray box.";
}
return null; return null;
} }
@ -308,6 +360,15 @@ public class ContactMailController extends FreemarkerHttpServlet {
} }
private String captchaHash(String value) {
int hash = 5381;
value = value.toUpperCase();
for(int i = 0; i < value.length(); i++) {
hash = ((hash << 5) + hash) + value.charAt(i);
}
return String.valueOf(hash);
}
private ResponseValues errorNoSmtpServer() { private ResponseValues errorNoSmtpServer() {
Map<String, Object> body = new HashMap<String, Object>(); Map<String, Object> body = new HashMap<String, Object>();
body.put("errorMessage", body.put("errorMessage",
@ -324,11 +385,14 @@ public class ContactMailController extends FreemarkerHttpServlet {
return new TemplateResponseValues(TEMPLATE_ERROR, body); return new TemplateResponseValues(TEMPLATE_ERROR, body);
} }
private ResponseValues errorParametersNotValid() { private ResponseValues errorParametersNotValid(String errorMsg, String webusername, String webuseremail, String comments) {
// rjy7 We should reload the form, not go to the error page!
Map<String, Object> body = new HashMap<String, Object>(); Map<String, Object> body = new HashMap<String, Object>();
body.put("errorMessage", "Invalid submission"); body.put("errorMessage", errorMsg);
return new TemplateResponseValues(TEMPLATE_ERROR, body); body.put("formAction", "submitFeedback");
body.put("webusername", webusername);
body.put("webuseremail", webuseremail);
body.put("comments", comments);
return new TemplateResponseValues(TEMPLATE_FORM, body);
} }
private ResponseValues errorSpam() { private ResponseValues errorSpam() {

View file

@ -19,6 +19,10 @@ import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean; import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfigurationConstants;
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualLocalNameMethod;
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualPlaceholderImageUrlMethod;
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualProfileUrlMethod;
import freemarker.cache.ClassTemplateLoader; import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.FileTemplateLoader; import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader; import freemarker.cache.MultiTemplateLoader;
@ -108,6 +112,9 @@ public class FreemarkerConfiguration extends Configuration {
sharedVariables.putAll(getMethods()); sharedVariables.putAll(getMethods());
sharedVariables.put("siteTagline", appBean.getShortHand()); sharedVariables.put("siteTagline", appBean.getShortHand());
//Put in edit configuration constants - useful for freemarker templates/editing
sharedVariables.put("editConfigurationConstants", EditConfigurationConstants.exportConstants());
for ( Map.Entry<String, Object> variable : sharedVariables.entrySet() ) { for ( Map.Entry<String, Object> variable : sharedVariables.entrySet() ) {
try { try {
setSharedVariable(variable.getKey(), variable.getValue()); setSharedVariable(variable.getKey(), variable.getValue());
@ -156,8 +163,9 @@ public class FreemarkerConfiguration extends Configuration {
public static Map<String, Object> getMethods() { public static Map<String, Object> getMethods() {
Map<String, Object> map = new HashMap<String, Object>(); Map<String, Object> map = new HashMap<String, Object>();
map.put("profileUrl", new edu.cornell.mannlib.vitro.webapp.web.methods.IndividualProfileUrlMethod()); map.put("profileUrl", new IndividualProfileUrlMethod());
map.put("localName", new edu.cornell.mannlib.vitro.webapp.web.methods.IndividualLocalNameMethod()); map.put("localName", new IndividualLocalNameMethod());
map.put("placeholderImageUrl", new IndividualPlaceholderImageUrlMethod());
return map; return map;
} }

View file

@ -338,42 +338,38 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
return appBean.getThemeDir().replaceAll("/$", ""); return appBean.getThemeDir().replaceAll("/$", "");
} }
/** /**
* Define the request-specific URLs that are accessible to the templates. * Define the request-specific URLs that are accessible to the templates.
* @param VitroRequest vreq * Merge it with the context-specific URLs from the configuration, because
*/ * this map will mask that one.
private void setRequestUrls(VitroRequest vreq) { */
private Map<String, Object> buildRequestUrls(VitroRequest vreq) {
Map<String, Object> requestUrls = new HashMap<String, Object>();
FreemarkerConfiguration config = (FreemarkerConfiguration)vreq.getAttribute("freemarkerConfig"); FreemarkerConfiguration config = (FreemarkerConfiguration)vreq.getAttribute("freemarkerConfig");
TemplateModel urlModel = config.getSharedVariable("urls"); TemplateModel urlModel = config.getSharedVariable("urls");
try { try {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Map<String, Object> urls = (Map<String, Object>) DeepUnwrap.permissiveUnwrap(urlModel); Map<String, Object> configUrls = (Map<String, Object>) DeepUnwrap.permissiveUnwrap(urlModel);
requestUrls.putAll(configUrls);
// This is request-specific because email can be configured // This is request-specific because email can be configured
// and de-configured in the application interface. // and de-configured in the application interface.
if (FreemarkerEmailFactory.isConfigured(vreq)) { if (FreemarkerEmailFactory.isConfigured(vreq)) {
urls.put("contact", UrlBuilder.getUrl(Route.CONTACT)); requestUrls.put("contact", UrlBuilder.getUrl(Route.CONTACT));
} else {
urls.remove("contact"); // clear value from a previous request
} }
urls.put("currentPage", getCurrentPageUrl(vreq)); requestUrls.put("currentPage", getCurrentPageUrl(vreq));
urls.put("referringPage", getReferringPageUrl(vreq)); requestUrls.put("referringPage", getReferringPageUrl(vreq));
if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.EDIT_OWN_ACCOUNT.ACTIONS)) { if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.EDIT_OWN_ACCOUNT.ACTIONS)) {
urls.put("myAccount", UrlBuilder.getUrl("/accounts/myAccount")); requestUrls.put("myAccount", UrlBuilder.getUrl("/accounts/myAccount"));
} else {
urls.remove("myAccount"); // clear value from a previous request
} }
config.setSharedVariable("urls", urls);
} catch (TemplateModelException e) { } catch (TemplateModelException e) {
log.error(e, e); log.error(e, e);
} }
return requestUrls;
} }
private String getCurrentPageUrl(HttpServletRequest request) { private String getCurrentPageUrl(HttpServletRequest request) {
@ -424,7 +420,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
// This may be overridden by the body data model received from the subcontroller. // This may be overridden by the body data model received from the subcontroller.
map.put("title", getTitle(vreq.getAppBean().getApplicationName(), vreq)); map.put("title", getTitle(vreq.getAppBean().getApplicationName(), vreq));
setRequestUrls(vreq); map.put("urls", buildRequestUrls(vreq));
map.put("menu", getDisplayModelMenu(vreq)); map.put("menu", getDisplayModelMenu(vreq));

View file

@ -36,6 +36,7 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup;
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo;
import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest; import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest;
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
/** /**
* Handle adding, replacing or deleting the main image on an Individual. * Handle adding, replacing or deleting the main image on an Individual.
@ -63,12 +64,6 @@ public class ImageUploadController extends FreemarkerHttpServlet {
/** The form field of the uploaded file; use as a key to the FileItem map. */ /** The form field of the uploaded file; use as a key to the FileItem map. */
public static final String PARAMETER_UPLOADED_FILE = "datafile"; public static final String PARAMETER_UPLOADED_FILE = "datafile";
/**
* The image to use as a placeholder when the individual has no image.
* Determined by the template.
*/
public static final String PARAMETER_PLACEHOLDER_URL = "placeholder";
/** Here is the main image file. Hold on to it. */ /** Here is the main image file. Hold on to it. */
public static final String ACTION_UPLOAD = "upload"; public static final String ACTION_UPLOAD = "upload";
@ -141,7 +136,8 @@ public class ImageUploadController extends FreemarkerHttpServlet {
String imageUri = entity.getMainImageUri(); String imageUri = entity.getMainImageUri();
RequestedAction ra; RequestedAction ra;
if (ACTION_DELETE.equals(action) || ACTION_DELETE_EDIT.equals(action)) { if (ACTION_DELETE.equals(action)
|| ACTION_DELETE_EDIT.equals(action)) {
ra = new DropObjectPropStmt(entity.getURI(), ra = new DropObjectPropStmt(entity.getURI(),
VitroVocabulary.IND_MAIN_IMAGE, imageUri); VitroVocabulary.IND_MAIN_IMAGE, imageUri);
} else if (imageUri != null) { } else if (imageUri != null) {
@ -405,12 +401,13 @@ public class ImageUploadController extends FreemarkerHttpServlet {
private TemplateResponseValues showAddImagePage(VitroRequest vreq, private TemplateResponseValues showAddImagePage(VitroRequest vreq,
Individual entity) { Individual entity) {
String placeholderUrl = vreq.getParameter(PARAMETER_PLACEHOLDER_URL);
String formAction = (entity == null) ? "" : formAction(entity.getURI(), String formAction = (entity == null) ? "" : formAction(entity.getURI(),
ACTION_UPLOAD, placeholderUrl); ACTION_UPLOAD);
String cancelUrl = (entity == null) ? "" : exitPageUrl(vreq, String cancelUrl = (entity == null) ? "" : exitPageUrl(vreq,
entity.getURI()); entity.getURI());
String placeholderUrl = (entity == null) ? "" : UrlBuilder
.getUrl(PlaceholderUtil.getPlaceholderImagePathForIndividual(
vreq, entity.getURI()));
TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_NEW); TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_NEW);
@ -437,12 +434,11 @@ public class ImageUploadController extends FreemarkerHttpServlet {
*/ */
private TemplateResponseValues showReplaceImagePage(VitroRequest vreq, private TemplateResponseValues showReplaceImagePage(VitroRequest vreq,
Individual entity, ImageInfo imageInfo) { Individual entity, ImageInfo imageInfo) {
String placeholderUrl = vreq.getParameter(PARAMETER_PLACEHOLDER_URL);
TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_REPLACE); TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_REPLACE);
rv.put(BODY_THUMBNAIL_URL, UrlBuilder.getUrl(imageInfo.getThumbnail() rv.put(BODY_THUMBNAIL_URL, UrlBuilder.getUrl(imageInfo.getThumbnail()
.getBytestreamAliasUrl())); .getBytestreamAliasUrl()));
rv.put(BODY_DELETE_URL, formAction(entity.getURI(), ACTION_DELETE_EDIT, placeholderUrl)); rv.put(BODY_DELETE_URL, formAction(entity.getURI(), ACTION_DELETE_EDIT));
rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_UPLOAD, placeholderUrl)); rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_UPLOAD));
rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI())); rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI()));
rv.put(BODY_TITLE, "Replace image" + forName(entity)); rv.put(BODY_TITLE, "Replace image" + forName(entity));
rv.put(BODY_MAX_FILE_SIZE, MAXIMUM_FILE_SIZE / (1024 * 1024)); rv.put(BODY_MAX_FILE_SIZE, MAXIMUM_FILE_SIZE / (1024 * 1024));
@ -468,12 +464,11 @@ public class ImageUploadController extends FreemarkerHttpServlet {
*/ */
private TemplateResponseValues showCropImagePage(VitroRequest vreq, private TemplateResponseValues showCropImagePage(VitroRequest vreq,
Individual entity, String imageUrl, Dimensions dimensions) { Individual entity, String imageUrl, Dimensions dimensions) {
String placeholderUrl = vreq.getParameter(PARAMETER_PLACEHOLDER_URL);
TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_CROP); TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_CROP);
rv.put(BODY_MAIN_IMAGE_URL, UrlBuilder.getUrl(imageUrl)); rv.put(BODY_MAIN_IMAGE_URL, UrlBuilder.getUrl(imageUrl));
rv.put(BODY_MAIN_IMAGE_HEIGHT, dimensions.height); rv.put(BODY_MAIN_IMAGE_HEIGHT, dimensions.height);
rv.put(BODY_MAIN_IMAGE_WIDTH, dimensions.width); rv.put(BODY_MAIN_IMAGE_WIDTH, dimensions.width);
rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_SAVE, placeholderUrl)); rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_SAVE));
rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI())); rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI()));
rv.put(BODY_TITLE, "Crop Photo" + forName(entity)); rv.put(BODY_TITLE, "Crop Photo" + forName(entity));
return rv; return rv;
@ -518,11 +513,9 @@ public class ImageUploadController extends FreemarkerHttpServlet {
* back to this controller, along with the desired action and the Entity * back to this controller, along with the desired action and the Entity
* URI. * URI.
*/ */
private String formAction(String entityUri, String action, private String formAction(String entityUri, String action) {
String placeholderUrl) { ParamMap params = new ParamMap(PARAMETER_ENTITY_URI, entityUri,
ParamMap params = new ParamMap( PARAMETER_ACTION, action);
PARAMETER_ENTITY_URI, entityUri, PARAMETER_ACTION, action,
PARAMETER_PLACEHOLDER_URL, placeholderUrl);
return UrlBuilder.getPath(URL_HERE, params); return UrlBuilder.getPath(URL_HERE, params);
} }

View file

@ -1,13 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.dao;
import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
public interface Classes2ClassesDao {
public abstract void deleteClasses2Classes(Classes2Classes c2c);
public abstract void insertNewClasses2Classes(Classes2Classes c2c);
}

View file

@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.dao;
import java.util.List; import java.util.List;
import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
@ -67,6 +68,10 @@ public interface VClassDao {
void addVClassesToGroup(VClassGroup group); void addVClassesToGroup(VClassGroup group);
void insertNewClasses2Classes(Classes2Classes c2c);
void deleteClasses2Classes(Classes2Classes c2c);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedClasses);/* (non-Javadoc) void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedClasses);/* (non-Javadoc)
* @see edu.cornell.mannlib.vitro.webapp.dao.db.VClassDao#addVClassesToGroups(java.util.List) * @see edu.cornell.mannlib.vitro.webapp.dao.db.VClassDao#addVClassesToGroups(java.util.List)

View file

@ -3,7 +3,6 @@
package edu.cornell.mannlib.vitro.webapp.dao; package edu.cornell.mannlib.vitro.webapp.dao;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
public interface WebappDaoFactory { public interface WebappDaoFactory {
@ -13,12 +12,6 @@ public interface WebappDaoFactory {
*/ */
public void close(); public void close();
/**
* Retrieves a map containing arbitrary key-value pairs describing this
* WebappDaoFactory
*/
public Map<String,String> getProperties();
/** /**
* Checks a URI String for two things: well-formedness and uniqueness in the * Checks a URI String for two things: well-formedness and uniqueness in the
* model. Ill-formed strings or those matching URIs already in use will * model. Ill-formed strings or those matching URIs already in use will
@ -39,7 +32,7 @@ public interface WebappDaoFactory {
public Set<String> getNonuserNamespaces(); public Set<String> getNonuserNamespaces();
public String[] getPreferredLanguages(); public List<String> getPreferredLanguages();
/** /**
* BJL23 2008-05-20: Putting this here for lack of a more logical place. * BJL23 2008-05-20: Putting this here for lack of a more logical place.
@ -66,11 +59,6 @@ public interface WebappDaoFactory {
/* =============== DAOs for ontology (TBox) manipulation =============== */ /* =============== DAOs for ontology (TBox) manipulation =============== */
/**
* returns a Data Access Object for working with class subsumption axioms
*/
public Classes2ClassesDao getClasses2ClassesDao();
/** /**
* returns a Data Access Object for working with DataProperties * returns a Data Access Object for working with DataProperties
*/ */

View file

@ -2,30 +2,29 @@
package edu.cornell.mannlib.vitro.webapp.dao; package edu.cornell.mannlib.vitro.webapp.dao;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
public class WebappDaoFactoryConfig { public class WebappDaoFactoryConfig {
private String[] preferredLanguages; private List<String> preferredLanguages;
private String defaultNamespace; private String defaultNamespace;
private Set<String> nonUserNamespaces; private Set<String> nonUserNamespaces;
public WebappDaoFactoryConfig() { public WebappDaoFactoryConfig() {
preferredLanguages = new String[3]; preferredLanguages = Arrays.asList("en-US", "en", "EN");
preferredLanguages[0] = "en-US";
preferredLanguages[1] = "en";
preferredLanguages[2] = "EN";
defaultNamespace = "http://vitro.mannlib.cornell.edu/ns/default#"; defaultNamespace = "http://vitro.mannlib.cornell.edu/ns/default#";
nonUserNamespaces = new HashSet<String>(); nonUserNamespaces = new HashSet<String>();
nonUserNamespaces.add(VitroVocabulary.vitroURI); nonUserNamespaces.add(VitroVocabulary.vitroURI);
} }
public String[] getPreferredLanguages() { public List<String> getPreferredLanguages() {
return this.preferredLanguages; return this.preferredLanguages;
} }
public void setPreferredLanguages(String[] pl) { public void setPreferredLanguages(List<String> pl) {
this.preferredLanguages = pl; this.preferredLanguages = pl;
} }

View file

@ -56,10 +56,6 @@ public class ObjectPropertyStatementFiltering implements ObjectPropertyStatement
return innerStmt.getSubjectURI(); return innerStmt.getSubjectURI();
} }
public boolean isSubjectOriented() {
return innerStmt.isSubjectOriented();
}
public void setObject(Individual object) { public void setObject(Individual object) {
innerStmt.setObject(object); innerStmt.setObject(object);
} }
@ -80,10 +76,6 @@ public class ObjectPropertyStatementFiltering implements ObjectPropertyStatement
innerStmt.setSubject(subject); innerStmt.setSubject(subject);
} }
public void setSubjectOriented(boolean subjectOriented) {
innerStmt.setSubjectOriented(subjectOriented);
}
public void setSubjectURI(String subjectURI) { public void setSubjectURI(String subjectURI) {
innerStmt.setSubjectURI(subjectURI); innerStmt.setSubjectURI(subjectURI);
} }

View file

@ -11,6 +11,7 @@ import java.util.List;
import net.sf.jga.algorithms.Filter; import net.sf.jga.algorithms.Filter;
import net.sf.jga.fn.UnaryFunctor; import net.sf.jga.fn.UnaryFunctor;
import net.sf.jga.fn.property.GetProperty; import net.sf.jga.fn.property.GetProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
@ -240,6 +241,14 @@ public class VClassDaoFiltering extends BaseFiltering implements VClassDao{
return innerVClassDao.getBottomConcept(); return innerVClassDao.getBottomConcept();
} }
public void insertNewClasses2Classes(Classes2Classes c2c) {
innerVClassDao.insertNewClasses2Classes(c2c);
}
public void deleteClasses2Classes(Classes2Classes c2c) {
innerVClassDao.deleteClasses2Classes(c2c);
}
public boolean isSubClassOf(VClass vc1, VClass vc2) { public boolean isSubClassOf(VClass vc1, VClass vc2) {
return innerVClassDao.isSubClassOf(vc1, vc2); return innerVClassDao.isSubClassOf(vc1, vc2);
} }

View file

@ -7,7 +7,6 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao; import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao;
import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
@ -76,10 +75,6 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory {
/* ******************* filtering *********************** */ /* ******************* filtering *********************** */
public Map<String,String> getProperties() {
return innerWebappDaoFactory.getProperties();
}
public String checkURI(String uriStr) { public String checkURI(String uriStr) {
return innerWebappDaoFactory.checkURI(uriStr); return innerWebappDaoFactory.checkURI(uriStr);
} }
@ -101,7 +96,7 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory {
return innerWebappDaoFactory.getNonuserNamespaces(); return innerWebappDaoFactory.getNonuserNamespaces();
} }
public String[] getPreferredLanguages() { public List<String> getPreferredLanguages() {
return innerWebappDaoFactory.getPreferredLanguages(); return innerWebappDaoFactory.getPreferredLanguages();
} }
@ -168,10 +163,6 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory {
/* ******************* non-filtering DAOs *************************** */ /* ******************* non-filtering DAOs *************************** */
public Classes2ClassesDao getClasses2ClassesDao() {
return innerWebappDaoFactory.getClasses2ClassesDao();
}
public DatatypeDao getDatatypeDao() { public DatatypeDao getDatatypeDao() {
return innerWebappDaoFactory.getDatatypeDao(); return innerWebappDaoFactory.getDatatypeDao();
} }

View file

@ -1,69 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.dao.jena;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
/**
*
*/
public class Classes2ClassesDaoJena extends JenaBaseDao implements Classes2ClassesDao {
public Classes2ClassesDaoJena(WebappDaoFactoryJena wadf) {
super(wadf);
}
public void deleteClasses2Classes( Classes2Classes c2c ) {
deleteClasses2Classes(c2c, getOntModelSelector().getTBoxModel());
}
public void deleteClasses2Classes( Classes2Classes c2c, OntModel ontModel )
{
ontModel.enterCriticalSection(Lock.WRITE);
ontModel.getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true));
try {
OntResource subclass = getOntClass(ontModel,c2c.getSubclassURI());
OntResource superclass = getOntClass(ontModel,c2c.getSuperclassURI());
if ((subclass != null) && (superclass != null)) {
ontModel.removeAll(subclass, RDFS.subClassOf, superclass);
}
if (subclass.isAnon()) {
smartRemove(subclass, getOntModel());
}
if (superclass.isAnon()) {
smartRemove(superclass, getOntModel());
}
} finally {
ontModel.getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false));
ontModel.leaveCriticalSection();
}
}
public void insertNewClasses2Classes( Classes2Classes c2c ) {
insertNewClasses2Classes(c2c, getOntModelSelector().getTBoxModel());
}
public void insertNewClasses2Classes( Classes2Classes c2c, OntModel ontModel )
{
ontModel.enterCriticalSection(Lock.WRITE);
ontModel.getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true));
try {
Resource subclass = ontModel.getResource(c2c.getSubclassURI());
Resource superclass = ontModel.getResource(c2c.getSuperclassURI());
if ((subclass != null) && (superclass != null)) {
ontModel.add(subclass, RDFS.subClassOf, superclass);
}
} finally {
ontModel.getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false));
ontModel.leaveCriticalSection();
}
}
}

View file

@ -43,17 +43,17 @@ public class EmptyReifier implements Reifier {
@Override @Override
public ExtendedIterator<Triple> find(TripleMatch arg0) { public ExtendedIterator<Triple> find(TripleMatch arg0) {
return WrappedIterator.create(Collections.EMPTY_LIST.iterator()); return g.find(arg0);
} }
@Override @Override
public ExtendedIterator<Triple> findEither(TripleMatch arg0, boolean arg1) { public ExtendedIterator<Triple> findEither(TripleMatch arg0, boolean arg1) {
return WrappedIterator.create(Collections.EMPTY_LIST.iterator()); return find(arg0);
} }
@Override @Override
public ExtendedIterator<Triple> findExposed(TripleMatch arg0) { public ExtendedIterator<Triple> findExposed(TripleMatch arg0) {
return WrappedIterator.create(Collections.EMPTY_LIST.iterator()); return find(arg0);
} }
@Override @Override
@ -68,14 +68,14 @@ public class EmptyReifier implements Reifier {
@Override @Override
public boolean handledAdd(Triple arg0) { public boolean handledAdd(Triple arg0) {
// TODO Auto-generated method stub g.add(arg0);
return false; return true;
} }
@Override @Override
public boolean handledRemove(Triple arg0) { public boolean handledRemove(Triple arg0) {
// TODO Auto-generated method stub g.delete(arg0);
return false; return true;
} }
@Override @Override
@ -98,20 +98,17 @@ public class EmptyReifier implements Reifier {
@Override @Override
public void remove(Triple arg0) { public void remove(Triple arg0) {
// TODO Auto-generated method stub g.delete(arg0);
} }
@Override @Override
public void remove(Node arg0, Triple arg1) { public void remove(Node arg0, Triple arg1) {
// TODO Auto-generated method stub g.delete(arg1);
} }
@Override @Override
public int size() { public int size() {
// TODO Auto-generated method stub return g.size();
return 0;
} }
} }

View file

@ -187,9 +187,10 @@ public class IndividualDaoSDB extends IndividualDaoJena {
continue; continue;
} }
if (uri != null && !uri.equals(currRes.getURI())) { if (uri != null && !uri.equals(currRes.getURI())) {
Individual ent = makeIndividual(uri, label); try {
if (ent != null) { ents.add(makeIndividual(uri, label));
ents.add(ent); } catch (IndividualNotFoundException e) {
// don't add
} }
uri = currRes.getURI(); uri = currRes.getURI();
label = null; label = null;
@ -201,9 +202,10 @@ public class IndividualDaoSDB extends IndividualDaoJena {
label = labelLit.getLexicalForm(); label = labelLit.getLexicalForm();
} }
if (!rs.hasNext()) { if (!rs.hasNext()) {
Individual ent = makeIndividual(uri, label); try {
if (ent != null) { ents.add(makeIndividual(uri, label));
ents.add(ent); } catch (IndividualNotFoundException e) {
// don't add
} }
} }
} }
@ -237,8 +239,12 @@ public class IndividualDaoSDB extends IndividualDaoJena {
if (currRes.isAnon()) { if (currRes.isAnon()) {
continue; continue;
} }
filteredIndividualList.add( try {
makeIndividual(currRes.getURI(), null)); filteredIndividualList.add(
makeIndividual(currRes.getURI(), null));
} catch (IndividualNotFoundException e) {
// don't add
}
} }
} finally { } finally {
dataset.getLock().leaveCriticalSection(); dataset.getLock().leaveCriticalSection();
@ -247,7 +253,7 @@ public class IndividualDaoSDB extends IndividualDaoJena {
return filteredIndividualList; return filteredIndividualList;
} }
private Individual makeIndividual(String uri, String label) { private Individual makeIndividual(String uri, String label) throws IndividualNotFoundException {
Individual ent = new IndividualSDB(uri, Individual ent = new IndividualSDB(uri,
this.dwf, datasetMode, getWebappDaoFactory(), this.dwf, datasetMode, getWebappDaoFactory(),
SKIP_INITIALIZATION); SKIP_INITIALIZATION);

View file

@ -109,7 +109,7 @@ public class IndividualSDB extends IndividualImpl implements Individual {
DatasetWrapperFactory datasetWrapperFactory, DatasetWrapperFactory datasetWrapperFactory,
SDBDatasetMode datasetMode, SDBDatasetMode datasetMode,
WebappDaoFactoryJena wadf, WebappDaoFactoryJena wadf,
boolean skipInitialization) { boolean skipInitialization) throws IndividualNotFoundException {
this.individualURI = individualURI; this.individualURI = individualURI;
this.datasetMode = datasetMode; this.datasetMode = datasetMode;
this.dwf = datasetWrapperFactory; this.dwf = datasetWrapperFactory;
@ -176,7 +176,7 @@ public class IndividualSDB extends IndividualImpl implements Individual {
public IndividualSDB(String individualURI, public IndividualSDB(String individualURI,
DatasetWrapperFactory datasetWrapperFactory, DatasetWrapperFactory datasetWrapperFactory,
SDBDatasetMode datasetMode, SDBDatasetMode datasetMode,
WebappDaoFactoryJena wadf) { WebappDaoFactoryJena wadf) throws IndividualNotFoundException {
this(individualURI, this(individualURI,
datasetWrapperFactory, datasetWrapperFactory,
datasetMode, datasetMode,
@ -184,7 +184,7 @@ public class IndividualSDB extends IndividualImpl implements Individual {
!SKIP_INITIALIZATION); !SKIP_INITIALIZATION);
} }
public class IndividualNotFoundException extends RuntimeException {} public class IndividualNotFoundException extends Exception {}
private void setUpURIParts(OntResource ind) { private void setUpURIParts(OntResource ind) {
if (ind != null) { if (ind != null) {
@ -464,8 +464,24 @@ public class IndividualSDB extends IndividualImpl implements Individual {
if (!s.getSubject().canAs(OntResource.class) || !s.getObject().canAs(OntResource.class)) { if (!s.getSubject().canAs(OntResource.class) || !s.getObject().canAs(OntResource.class)) {
continue; continue;
} }
Individual subj = new IndividualSDB(((OntResource) s.getSubject().as(OntResource.class)).getURI(), this.dwf, datasetMode, webappDaoFactory); Individual subj = null;
Individual obj = new IndividualSDB(((OntResource) s.getObject().as(OntResource.class)).getURI(), this.dwf, datasetMode, webappDaoFactory); try {
subj = new IndividualSDB(
((OntResource) s.getSubject().as(OntResource.class))
.getURI(),
this.dwf, datasetMode, webappDaoFactory);
} catch (IndividualNotFoundException e) {
// leave null subject
}
Individual obj = null;
try {
obj = new IndividualSDB(
((OntResource) s.getObject().as(OntResource.class))
.getURI(),
this.dwf, datasetMode, webappDaoFactory);
} catch (IndividualNotFoundException e) {
// leave null object
}
ObjectProperty op = webappDaoFactory.getObjectPropertyDao().getObjectPropertyByURI(s.getPredicate().getURI()); ObjectProperty op = webappDaoFactory.getObjectPropertyDao().getObjectPropertyByURI(s.getPredicate().getURI());
// We don't want to filter out statements simply because we // We don't want to filter out statements simply because we
// can't find a type for the property, so we'll just make a // can't find a type for the property, so we'll just make a
@ -517,15 +533,19 @@ public class IndividualSDB extends IndividualImpl implements Individual {
while (values.hasNext()) { while (values.hasNext()) {
result = values.next(); result = values.next();
RDFNode value = result.get("object"); RDFNode value = result.get("object");
if (value.canAs(OntResource.class)) { try {
relatedIndividuals.add( if (value.canAs(OntResource.class)) {
new IndividualSDB( relatedIndividuals.add(
((OntResource) value.as(OntResource.class)) new IndividualSDB(
.getURI(), ((OntResource) value.as(OntResource.class))
this.dwf, .getURI(),
datasetMode, this.dwf,
webappDaoFactory) ); datasetMode,
} webappDaoFactory) );
}
} catch (IndividualNotFoundException e) {
// don't add to the list
}
} }
} finally { } finally {
dataset.getLock().leaveCriticalSection(); dataset.getLock().leaveCriticalSection();
@ -555,9 +575,13 @@ public class IndividualSDB extends IndividualImpl implements Individual {
QuerySolution result = results.next(); QuerySolution result = results.next();
RDFNode value = result.get("object"); RDFNode value = result.get("object");
if (value != null && value.canAs(OntResource.class)) { if (value != null && value.canAs(OntResource.class)) {
return new IndividualSDB( try {
((OntResource) value.as(OntResource.class)).getURI(), return new IndividualSDB(
dwf, datasetMode, webappDaoFactory); ((OntResource) value.as(OntResource.class)).getURI(),
dwf, datasetMode, webappDaoFactory);
} catch (IndividualNotFoundException e) {
return null;
}
} }
} }
return null; return null;

View file

@ -80,7 +80,7 @@ public class JenaBaseDao extends JenaBaseDaoCon {
protected String DEFAULT_NAMESPACE; protected String DEFAULT_NAMESPACE;
protected Set<String> NONUSER_NAMESPACES; protected Set<String> NONUSER_NAMESPACES;
protected String[] PREFERRED_LANGUAGES; protected List<String> PREFERRED_LANGUAGES;
/* ******************* constructor ************************* */ /* ******************* constructor ************************* */
@ -501,7 +501,7 @@ public class JenaBaseDao extends JenaBaseDaoCon {
} }
} }
} catch (Exception e) { } catch (Exception e) {
log.error("Error in updatePropertyDateValue"); log.error("Error in updatePropertyDateValue", e);
} }
} }
@ -552,8 +552,7 @@ public class JenaBaseDao extends JenaBaseDaoCon {
} }
} }
} catch (Exception e) { } catch (Exception e) {
log.error("Error in updatePropertyDateTimeValue"); log.error("Error in updatePropertyDateTimeValue", e);
log.error(e, e);
} }
} }
@ -767,7 +766,7 @@ public class JenaBaseDao extends JenaBaseDaoCon {
if (label.isLiteral()) { if (label.isLiteral()) {
Literal labelLit = ((Literal)label); Literal labelLit = ((Literal)label);
String labelLanguage = labelLit.getLanguage(); String labelLanguage = labelLit.getLanguage();
if ( (labelLanguage==null) && (lang==null) ) { if ( (labelLanguage == null) && (lang == null || lang.isEmpty()) ) {
return labelLit; return labelLit;
} }
if ( (lang != null) && (lang.equals(labelLanguage)) ) { if ( (lang != null) && (lang.equals(labelLanguage)) ) {
@ -857,6 +856,10 @@ public class JenaBaseDao extends JenaBaseDaoCon {
Literal label = null; Literal label = null;
List<RDFNode> labels = r.listPropertyValues(p).toList(); List<RDFNode> labels = r.listPropertyValues(p).toList();
if (labels.size() == 0) {
return null;
}
// Sort by lexical value to guarantee consistent results // Sort by lexical value to guarantee consistent results
Collections.sort(labels, new Comparator<RDFNode>() { Collections.sort(labels, new Comparator<RDFNode>() {
public int compare(RDFNode left, RDFNode right) { public int compare(RDFNode left, RDFNode right) {
@ -871,8 +874,7 @@ public class JenaBaseDao extends JenaBaseDaoCon {
} }
}); });
for (int i=0; i<PREFERRED_LANGUAGES.length; i++) { for (String lang : PREFERRED_LANGUAGES) {
String lang = PREFERRED_LANGUAGES[i];
label = getLabel(lang,labels); label = getLabel(lang,labels);
if (label != null) { if (label != null) {
break; break;
@ -880,12 +882,21 @@ public class JenaBaseDao extends JenaBaseDaoCon {
} }
if ( label == null && alsoTryNoLang ) { if ( label == null && alsoTryNoLang ) {
label = getLabel("", labels); label = getLabel("", labels);
// accept any label as a last resort
if (label == null) {
for (RDFNode labelNode : labels) {
if (labelNode instanceof Literal) {
label = ((Literal) labelNode);
break;
}
}
}
} }
return label; return label;
} }
protected String getDefaultLanguage() { protected String getDefaultLanguage() {
return PREFERRED_LANGUAGES[0]; return PREFERRED_LANGUAGES.get(0);
} }
/** /**

View file

@ -404,6 +404,17 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
/** /**
* Finds all mostSpecificTypes of an individual that are members of a classgroup. * Finds all mostSpecificTypes of an individual that are members of a classgroup.
* Returns a list of type labels. * Returns a list of type labels.
*
* Note that the Map returned is a LinkedHashMap, which means that an iterator
* will return the entries in the order in which the keys were inserted in the map.
* Since the SPARQL query included an "ORDER BY ?label" clause, and since an
* iterator through that ResultSet was used to add entries to the map, an iterator
* on the map will return entries that are sorted by label (value, not key).
*
* While this sorting order is not specified as a requirement (maybe it should be?),
* it is certainly useful that the types are returned in some order that is
* replicable, so an individual with multiple mostSpecificTypes, will always see
* the same list in the same order. (See https://issues.library.cornell.edu/browse/NIHVIVO-568)
* **/ * **/
public Map<String, String> getMostSpecificTypesInClassgroupsForIndividual(String subjectUri) { public Map<String, String> getMostSpecificTypesInClassgroupsForIndividual(String subjectUri) {

View file

@ -132,7 +132,7 @@ public class OntologyDaoJena extends JenaBaseDao implements OntologyDao {
try { try {
com.hp.hpl.jena.ontology.Ontology o = ontModel.createOntology(adjustOntologyURI(ontology.getURI())); com.hp.hpl.jena.ontology.Ontology o = ontModel.createOntology(adjustOntologyURI(ontology.getURI()));
if (ontology.getName() != null && ontology.getName().length()>0) { if (ontology.getName() != null && ontology.getName().length()>0) {
o.setLabel(ontology.getName(), PREFERRED_LANGUAGES[0]); o.setLabel(ontology.getName(), getDefaultLanguage());
} }
if (ontology.getPrefix() != null && ontology.getPrefix().length()>0) { if (ontology.getPrefix() != null && ontology.getPrefix().length()>0) {
addPropertyStringValue(o,ONTOLOGY_PREFIX_ANNOT,ontology.getPrefix(),ontModel); addPropertyStringValue(o,ONTOLOGY_PREFIX_ANNOT,ontology.getPrefix(),ontModel);

View file

@ -3,7 +3,6 @@
package edu.cornell.mannlib.vitro.webapp.dao.jena; package edu.cornell.mannlib.vitro.webapp.dao.jena;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
@ -35,6 +34,7 @@ import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.sparql.resultset.ResultSetMem; import com.hp.hpl.jena.sparql.resultset.ResultSetMem;
import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDFS; import com.hp.hpl.jena.vocabulary.RDFS;
@ -596,6 +596,31 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
} }
} }
private List<OntClass> listSuperClasses(OntClass ontClass) {
return relatedClasses(ontClass, RDFS.subClassOf);
}
private List<OntClass> listEquivalentClasses(OntClass ontClass) {
return relatedClasses(ontClass, OWL.equivalentClass);
}
private List<OntClass> relatedClasses(OntClass ontClass,
com.hp.hpl.jena.rdf.model.Property property) {
List<OntClass> classes = new ArrayList<OntClass>();
StmtIterator closeIt = ontClass.listProperties(property);
try {
while (closeIt.hasNext()) {
Statement stmt = closeIt.nextStatement();
if (stmt.getObject().canAs(OntClass.class)) {
classes.add(stmt.getObject().as(OntClass.class));
}
}
} finally {
closeIt.close();
}
return classes;
}
public List<PropertyInstance> getAllPropInstByVClasses(List<VClass> vclasses) { public List<PropertyInstance> getAllPropInstByVClasses(List<VClass> vclasses) {
List<PropertyInstance> propInsts = new ArrayList<PropertyInstance>(); List<PropertyInstance> propInsts = new ArrayList<PropertyInstance>();
@ -628,8 +653,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
OntClass ontClass = getOntClass(ontModel,VClassURI); OntClass ontClass = getOntClass(ontModel,VClassURI);
if (ontClass != null) { if (ontClass != null) {
List<OntClass> relatedClasses = new ArrayList<OntClass>(); List<OntClass> relatedClasses = new ArrayList<OntClass>();
relatedClasses.addAll(ontClass.listEquivalentClasses().toList()); relatedClasses.addAll(listEquivalentClasses(ontClass));
relatedClasses.addAll(ontClass.listSuperClasses().toList()); relatedClasses.addAll(listSuperClasses(ontClass));
for (OntClass relatedClass : relatedClasses) { for (OntClass relatedClass : relatedClasses) {
// find properties in restrictions // find properties in restrictions
if (relatedClass.isRestriction()) { if (relatedClass.isRestriction()) {

View file

@ -14,14 +14,14 @@ import com.hp.hpl.jena.shared.Lock;
*/ */
public class SimpleOntModelSelector implements OntModelSelector { public class SimpleOntModelSelector implements OntModelSelector {
private OntModel fullModel; protected OntModel fullModel;
private OntModel aboxModel; protected OntModel aboxModel;
private OntModel applicationMetadataModel; protected OntModel applicationMetadataModel;
private OntModel tboxModel; protected OntModel tboxModel;
private OntModel userAccountsModel; protected OntModel userAccountsModel;
private OntModelSpec DEFAULT_ONT_MODEL_SPEC = OntModelSpec.OWL_MEM; protected OntModelSpec DEFAULT_ONT_MODEL_SPEC = OntModelSpec.OWL_MEM;
private OntModel displayModel; protected OntModel displayModel;
/** /**
* Construct an OntModelSelector with a bunch of empty models * Construct an OntModelSelector with a bunch of empty models

View file

@ -0,0 +1,15 @@
package edu.cornell.mannlib.vitro.webapp.dao.jena;
import com.hp.hpl.jena.ontology.OntModel;
public class SingleContentOntModelSelector extends SimpleOntModelSelector {
public SingleContentOntModelSelector(OntModel contentModel,
OntModel displayModel,
OntModel userAccountsModel) {
super(contentModel);
super.displayModel = displayModel;
super.userAccountsModel = userAccountsModel;
}
}

View file

@ -82,11 +82,25 @@ public class SparqlGraph implements GraphWithPerform {
@Override @Override
public void performAdd(Triple t) { public void performAdd(Triple t) {
String updateString = "INSERT DATA { " //log.info("adding " + t);
String updateString = "INSERT DATA { GRAPH <junk:junk> { "
+ sparqlNode(t.getSubject(), "") + " " + sparqlNode(t.getSubject(), "") + " "
+ sparqlNode(t.getPredicate(), "") + " " + sparqlNode(t.getPredicate(), "") + " "
+ sparqlNode(t.getObject(), "") + + sparqlNode(t.getObject(), "") +
"}"; " } }";
if (false) {
try {
throw new RuntimeException("Breakpoint");
} catch (RuntimeException e) {
log.error(e, e);
//throw(e);
}
}
//log.info(updateString);
try { try {
RepositoryConnection conn = getConnection(); RepositoryConnection conn = getConnection();
@ -108,11 +122,15 @@ public class SparqlGraph implements GraphWithPerform {
@Override @Override
public void performDelete(Triple t) { public void performDelete(Triple t) {
String updateString = "DELETE DATA { " log.info ("************** DELETE!!!!! ********************");
String updateString = "DELETE DATA { GRAPH <junk:junk> { "
+ sparqlNode(t.getSubject(), "") + " " + sparqlNode(t.getSubject(), "") + " "
+ sparqlNode(t.getPredicate(), "") + " " + sparqlNode(t.getPredicate(), "") + " "
+ sparqlNode(t.getObject(), "") + + sparqlNode(t.getObject(), "") +
"}"; " } }";
log.info(updateString);
try { try {
RepositoryConnection conn = getConnection(); RepositoryConnection conn = getConnection();
@ -158,6 +176,7 @@ public class SparqlGraph implements GraphWithPerform {
@Override @Override
public void delete(Triple arg0) throws DeleteDeniedException { public void delete(Triple arg0) throws DeleteDeniedException {
log.info("********************** DELETE!!!!!! ************************");
performDelete(arg0); performDelete(arg0);
} }
@ -212,7 +231,7 @@ public class SparqlGraph implements GraphWithPerform {
.append(sparqlNode(object, "?o")) .append(sparqlNode(object, "?o"))
.append("\n}"); .append("\n}");
log.info(findQuery.toString()); //log.info(findQuery.toString());
ResultSet rs = execSelect(findQuery.toString()); ResultSet rs = execSelect(findQuery.toString());
//rs = execSelect(findQuery.toString()); //rs = execSelect(findQuery.toString());
//rs = execSelect(findQuery.toString()); //rs = execSelect(findQuery.toString());
@ -226,6 +245,7 @@ public class SparqlGraph implements GraphWithPerform {
//log.info(t); //log.info(t);
triplist.add(t); triplist.add(t);
} }
//log.info(triplist.size() + " results");
return WrappedIterator.create(triplist.iterator()); return WrappedIterator.create(triplist.iterator());
} }
@ -236,7 +256,7 @@ public class SparqlGraph implements GraphWithPerform {
@Override @Override
public BulkUpdateHandler getBulkUpdateHandler() { public BulkUpdateHandler getBulkUpdateHandler() {
if (this.bulkUpdateHandler == null) { if (this.bulkUpdateHandler == null) {
this.bulkUpdateHandler = new SimpleBulkUpdateHandler(this); this.bulkUpdateHandler = new SparqlGraphBulkUpdater(this);
} }
return this.bulkUpdateHandler; return this.bulkUpdateHandler;
} }
@ -383,7 +403,7 @@ public class SparqlGraph implements GraphWithPerform {
try { try {
return new ResultSetMem(qe.execSelect()); return new ResultSetMem(qe.execSelect());
} finally { } finally {
log.info((System.currentTimeMillis() - startTime) + " to execute via Jena"); //log.info((System.currentTimeMillis() - startTime) + " to execute via Jena");
qe.close(); qe.close();
} }
} }

View file

@ -0,0 +1,148 @@
package edu.cornell.mannlib.vitro.webapp.dao.jena;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.graph.TripleMatch;
import com.hp.hpl.jena.graph.impl.GraphWithPerform;
import com.hp.hpl.jena.shared.AddDeniedException;
import com.hp.hpl.jena.sparql.util.NodeFactory;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.util.iterator.WrappedIterator;
public class SparqlGraphMultilingual extends SparqlGraph implements GraphWithPerform {
private static final Log log = LogFactory.getLog(SparqlGraphMultilingual.class);
protected List<String> langs;
public SparqlGraphMultilingual(String endpointURI, List<String> languages) {
super(endpointURI);
this.langs = languages;
}
@Override
public void add(Triple arg0) throws AddDeniedException {
performAdd(arg0);
}
@Override
public void performAdd(Triple t) {
if (true) {
super.performAdd(t);
return;
}
if (langs == null || langs.size() == 0) {
log.info("No language configured - adding original triple " + t);
super.performAdd(t);
} else if (t.getObject().isLiteral()
&& t.getObject().getLiteral().getDatatypeURI() == null) {
log.info("adding language tag");
super.performAdd(Triple.create(t.getSubject(),
t.getPredicate(), NodeFactory.createLiteralNode(
t.getObject().getLiteralLexicalForm(), langs.get(0), null)));
} else {
log.info("adding original triple " + t);
super.performAdd(t);
}
}
@Override
public ExtendedIterator<Triple> find(TripleMatch arg0) {
//log.info("find(TripleMatch) " + arg0);
Triple t = arg0.asTriple();
return find(t.getSubject(), t.getPredicate(), t.getObject());
}
@Override
public ExtendedIterator<Triple> find(Node subject, Node predicate, Node object) {
long startTime = System.currentTimeMillis();
ExtendedIterator<Triple> rawResults = super.find(subject, predicate, object);
long rawTime = System.currentTimeMillis() - startTime;
List<Triple> tripList = new ArrayList<Triple>();
while (rawResults.hasNext()) {
tripList.add(rawResults.next());
}
if (tripList.size() == 0) {
return WrappedIterator.create(tripList.iterator());
}
if (subject.isConcrete() && predicate.isConcrete() && !object.isConcrete()) {
Collections.sort(tripList, new TripleSortByLang());
LinkedList<Triple> tripl = new LinkedList<Triple>();
if (!tripList.get(0).getObject().isLiteral()) {
tripl.addAll(tripList);
} else if (StringUtils.isEmpty(tripList.get(0).getObject().getLiteralLanguage())) {
tripl.addAll(tripList); // is this right?
} else {
String lang = tripList.get(0).getObject().getLiteralLanguage();
for (Triple t : tripList) {
if (lang.equals(t.getObject().getLiteralLanguage())) {
tripl.add(t);
} else {
break;
}
}
}
long filterTime = System.currentTimeMillis() - rawTime - startTime;
if (filterTime > 1) {
log.info("raw time " + rawTime + " ; filter time " + filterTime);
}
return WrappedIterator.create(tripl.iterator());
} else {
long filterTime = System.currentTimeMillis() - rawTime - startTime;
if (rawTime > 9) {
log.info("raw time " + rawTime + " ; filter time " + filterTime);
log.info("^ " + subject + " : " + predicate + " : " + object);
}
return WrappedIterator.create(tripList.iterator());
}
}
private class TripleSortByLang implements Comparator<Triple> {
public int compare(Triple t1, Triple t2) {
if (t1 == null || t2 == null) {
return 0;
} else if (!t1.getObject().isLiteral() || !t2.getObject().isLiteral()) {
return 0;
}
String t1lang = t1.getObject().getLiteral().language();
String t2lang = t2.getObject().getLiteral().language();
if ( t1lang == null && t2lang == null) {
return 0;
} else if (t1lang == null) {
return 1;
} else if (t2lang == null) {
return -1;
} else {
int t1langPref = langs.indexOf(t1.getObject().getLiteral().language());
if (t1langPref == -1) {
t1langPref = Integer.MAX_VALUE;
}
int t2langPref = langs.indexOf(t2.getObject().getLiteral().language());
if (t2langPref == -1) {
t2langPref = Integer.MAX_VALUE;
}
return t1langPref - t2langPref;
}
}
}
}

View file

@ -30,7 +30,6 @@ import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.util.iterator.ClosableIterator;
import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao; import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao;
import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
@ -233,7 +232,7 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
return config.getDefaultNamespace(); return config.getDefaultNamespace();
} }
public String[] getPreferredLanguages() { public List<String> getPreferredLanguages() {
return config.getPreferredLanguages(); return config.getPreferredLanguages();
} }
@ -312,13 +311,6 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
return userAccountsDao = new UserAccountsDaoJena(this); return userAccountsDao = new UserAccountsDaoJena(this);
} }
Classes2ClassesDao classes2ClassesDao = null;
public Classes2ClassesDao getClasses2ClassesDao() {
if(classes2ClassesDao == null )
classes2ClassesDao = new Classes2ClassesDaoJena(this);
return classes2ClassesDao;
}
DataPropertyStatementDao dataPropertyStatementDao = null; DataPropertyStatementDao dataPropertyStatementDao = null;
public DataPropertyStatementDao getDataPropertyStatementDao() { public DataPropertyStatementDao getDataPropertyStatementDao() {
if( dataPropertyStatementDao == null ) if( dataPropertyStatementDao == null )

View file

@ -163,7 +163,9 @@ public class PelletListener implements ModelChangedListener {
this.deletedDataProperties = ModelFactory.createDefaultModel(); this.deletedDataProperties = ModelFactory.createDefaultModel();
this.mainModel.enterCriticalSection(Lock.READ); this.mainModel.enterCriticalSection(Lock.READ);
try { try {
addedStatements(mainModel); for (ObjectPropertyStatementPattern pat : this.inferenceDrivingPatternAllowSet) {
addedStatements(mainModel.listStatements((Resource) null, pat.getPredicate(), (RDFNode) null));
}
if (!skipReasoningUponInitialization) { if (!skipReasoningUponInitialization) {
this.foreground = foreground; this.foreground = foreground;
notifyEvent(null,new EditEvent(null,false)); notifyEvent(null,new EditEvent(null,false));

View file

@ -7,6 +7,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
@ -23,6 +24,7 @@ import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vitro.webapp.dao.InsertException; import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
import edu.cornell.mannlib.vitro.webapp.dao.jena.DependentResourceDeleteJena; import edu.cornell.mannlib.vitro.webapp.dao.jena.DependentResourceDeleteJena;
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.edit.n3editing.configuration.EditConfigurationConstants;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.controller.ProcessRdfFormController.Utilities; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.controller.ProcessRdfFormController.Utilities;
/** /**
@ -41,8 +43,7 @@ public class ProcessRdfForm {
private EditN3GeneratorVTwo populator; private EditN3GeneratorVTwo populator;
private Map<String,String> urisForNewResources = null; private Map<String,String> urisForNewResources = null;
/**
/**
* Construct the ProcessRdfForm object. * Construct the ProcessRdfForm object.
*/ */
public ProcessRdfForm( EditConfigurationVTwo config, NewURIMaker newURIMaker){ public ProcessRdfForm( EditConfigurationVTwo config, NewURIMaker newURIMaker){
@ -172,6 +173,12 @@ public class ProcessRdfForm {
//need to substitute into the return to URL becase it may need new resource URIs //need to substitute into the return to URL becase it may need new resource URIs
List<String> URLToReturnTo = Arrays.asList(submission.getEntityToReturnTo()); List<String> URLToReturnTo = Arrays.asList(submission.getEntityToReturnTo());
/* *********** Check if new resource needs to be forcibly created ******** */
urisForNewResources = URIsForNewRsources(editConfig, newURIMaker);
substituteInForcedNewURIs(urisForNewResources, submission.getUrisFromForm(), requiredAsserts, optionalAsserts, URLToReturnTo);
logSubstitue( "Added form URIs that required new URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
/* ********** Form submission URIs ********* */ /* ********** Form submission URIs ********* */
substituteInMultiURIs(submission.getUrisFromForm(), requiredAsserts, optionalAsserts, URLToReturnTo); substituteInMultiURIs(submission.getUrisFromForm(), requiredAsserts, optionalAsserts, URLToReturnTo);
logSubstitue( "Added form URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts); logSubstitue( "Added form URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
@ -182,10 +189,13 @@ public class ProcessRdfForm {
logSubstitue( "Added form Literals", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts); logSubstitue( "Added form Literals", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
//Retractions does NOT get values from form. //Retractions does NOT get values from form.
/* *********** Add subject, object and predicate ******** */ /* *********** Add subject, object and predicate ******** */
substituteInSubPredObjURIs(editConfig, requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts, URLToReturnTo); substituteInSubPredObjURIs(editConfig, requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts, URLToReturnTo);
logSubstitue( "Added sub, pred and obj URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts); logSubstitue( "Added sub, pred and obj URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
/* ********* Existing URIs and Literals ********** */ /* ********* Existing URIs and Literals ********** */
substituteInMultiURIs(editConfig.getUrisInScope(), substituteInMultiURIs(editConfig.getUrisInScope(),
requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts, URLToReturnTo); requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts, URLToReturnTo);
@ -197,7 +207,8 @@ public class ProcessRdfForm {
//Both Assertions and Retractions get existing values. //Both Assertions and Retractions get existing values.
/* ************ Edits may need new resources *********** */ /* ************ Edits may need new resources *********** */
urisForNewResources = URIsForNewRsources(editConfig, newURIMaker); //moved this up?
//urisForNewResources = URIsForNewRsources(editConfig, newURIMaker);
substituteInURIs( urisForNewResources, requiredAsserts, optionalAsserts, URLToReturnTo); substituteInURIs( urisForNewResources, requiredAsserts, optionalAsserts, URLToReturnTo);
logSubstitue( "Added URIs for new Resources", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts); logSubstitue( "Added URIs for new Resources", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
// Only Assertions get new resources. // Only Assertions get new resources.
@ -205,7 +216,9 @@ public class ProcessRdfForm {
submission.setEntityToReturnTo(URLToReturnTo.get(0)); submission.setEntityToReturnTo(URLToReturnTo.get(0));
} }
//TODO: maybe move this to utils or contorller?
//TODO: maybe move this to utils or contorller?
public static AdditionsAndRetractions addDependentDeletes( AdditionsAndRetractions changes, Model queryModel){ public static AdditionsAndRetractions addDependentDeletes( AdditionsAndRetractions changes, Model queryModel){
//Add retractions for dependent resource delete if that is configured and //Add retractions for dependent resource delete if that is configured and
//if there are any dependent resources. //if there are any dependent resources.
@ -455,5 +468,35 @@ public class ProcessRdfForm {
} }
} }
/*
* In some situations, an object may have an existing URI but be left blank
* when the desired behavior is that a new object be created to replace the existing URI
* E.g. autocomplete forms that allow editing of autocomplete fields
*/
@SuppressWarnings("unchecked")
private void substituteInForcedNewURIs(
Map<String, String> urisForNewResources, Map<String, List<String>> urisFromForm,
List<String> requiredAsserts, List<String> optionalAsserts,
List<String> uRLToReturnTo) {
Map<String, List<String>> newUris = new HashMap<String, List<String>>();
//Check if any values from the submission have the "force new uri" value
//TODO: Check how to handle multiple new resource values
Iterator<String> keyIterator = urisFromForm.keySet().iterator();
while(keyIterator.hasNext()) {
String key = keyIterator.next().toString();
if(urisFromForm.get(key).contains(EditConfigurationConstants.NEW_URI_SENTINEL)) {
String newUri = urisForNewResources.get(key);
List<String> newUrisForKey = new ArrayList<String>();
newUrisForKey.add(newUri);
newUris.put(key, newUrisForKey);
}
}
if(newUris.size() > 0) {
substituteInMultiURIs(newUris, requiredAsserts, optionalAsserts, uRLToReturnTo);
}
}
private static Log log = LogFactory.getLog(ProcessRdfForm.class); private static Log log = LogFactory.getLog(ProcessRdfForm.class);
} }

View file

@ -0,0 +1,38 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.ProcessRdfForm;
public class EditConfigurationConstants {
/** Constants used by edit configuration */
//forces creation of new uri if present
public static final String NEW_URI_SENTINEL = ">NEW URI REQUIRED<";
public static final String BLANK_SENTINEL = ">SUBMITTED VALUE WAS BLANK<";
//For freemarker configuration
public static Map<String, String> exportConstants() {
Map<String, String> constants = new HashMap<String, String>();
java.lang.reflect.Field[] fields = EditConfigurationConstants.class.getDeclaredFields();
for(java.lang.reflect.Field f: fields) {
if(Modifier.isStatic(f.getModifiers()) &&
Modifier.isPublic(f.getModifiers())) {
try {
constants.put(f.getName(), f.get(null).toString());
} catch(Exception ex) {
log.error("An exception occurred in trying to retrieve this field ", ex);
}
}
}
return constants;
}
private static Log log = LogFactory.getLog(EditConfigurationConstants.class);
}

View file

@ -5,6 +5,9 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
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.OntModel;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
@ -12,6 +15,8 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
public class StandardModelSelector implements ModelSelector { public class StandardModelSelector implements ModelSelector {
private static final Log log = LogFactory.getLog(StandardModelSelector.class);
public OntModel getModel(HttpServletRequest request, ServletContext context) { public OntModel getModel(HttpServletRequest request, ServletContext context) {
VitroRequest vreq = new VitroRequest( request ); VitroRequest vreq = new VitroRequest( request );
@ -23,11 +28,17 @@ public class StandardModelSelector implements ModelSelector {
sessionOntModel = oms.getABoxModel(); sessionOntModel = oms.getABoxModel();
} }
} }
if(sessionOntModel != null && sessionOntModel instanceof OntModel ) if(sessionOntModel != null && sessionOntModel instanceof OntModel ) {
log.info("++++++++++ using OntModelSelector from session");
return (OntModel)sessionOntModel; return (OntModel)sessionOntModel;
else } else if (vreq.getOntModelSelector() != null) {
log.info("++++++++++ using OntModelSelector from request");
return vreq.getOntModelSelector().getABoxModel();
} else {
log.info("++++++++++ using OntModelSelector from context");
return ((OntModelSelector) context return ((OntModelSelector) context
.getAttribute("unionOntModelSelector")).getABoxModel(); .getAttribute("unionOntModelSelector")).getABoxModel();
}
} }
public static final ModelSelector selector = new StandardModelSelector(); public static final ModelSelector selector = new StandardModelSelector();

View file

@ -66,7 +66,7 @@ public abstract class BaseEditConfigurationGenerator implements EditConfiguratio
//setup the model selectors for query, write and display models on editConfig //setup the model selectors for query, write and display models on editConfig
setupModelSelectorsFromVitroRequest(vreq, editConfig); setupModelSelectorsFromVitroRequest(vreq, editConfig);
OntModel queryModel = (OntModel)vreq.getAttribute("jenaOntModel"); OntModel queryModel = vreq.getJenaOntModel(); // (OntModel)vreq.getAttribute("jenaOntModel");
if( editConfig.getSubjectUri() == null) if( editConfig.getSubjectUri() == null)
editConfig.setSubjectUri( EditConfigurationUtils.getSubjectUri(vreq)); editConfig.setSubjectUri( EditConfigurationUtils.getSubjectUri(vreq));

View file

@ -50,6 +50,8 @@ public class ProcessRdfFormController extends FreemarkerHttpServlet{
private Log log = LogFactory.getLog(ProcessRdfFormController.class); private Log log = LogFactory.getLog(ProcessRdfFormController.class);
@Override @Override
protected Actions requiredActions(VitroRequest vreq) { protected Actions requiredActions(VitroRequest vreq) {
return SimplePermission.DO_FRONT_END_EDITING.ACTIONS; return SimplePermission.DO_FRONT_END_EDITING.ACTIONS;

View file

@ -1,64 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.io.File;
import java.io.IOException;
import com.hp.hpl.jena.rdf.model.Resource;
/**
* Adjust any individual that has a thumbnail with no main image.
*/
public class AllThumbsAdjuster extends FsuScanner {
private ImageDirectoryWithBackup imageDirectoryWithBackup;
public AllThumbsAdjuster(FSUController controller) {
super(controller);
this.imageDirectoryWithBackup = controller
.getImageDirectoryWithBackup();
}
/**
* For every individual with thumbnails but no main images, create a main
* image from the first thumbnail.
*/
public void adjust() {
updateLog.section("Creating main images for thumbnails "
+ "that have none.");
for (Resource resource : ModelWrapper.listResourcesWithProperty(model,
thumbProperty)) {
if (ResourceWrapper.getProperty(resource, imageProperty) == null) {
createMainImageFromThumbnail(resource);
}
}
}
/**
* This individual has a thumbnail but no main image. Create one.
* <ul>
* <li>Figure a name for the main image.</li>
* <li>Copy the thumbnail image file into the main image file.</li>
* <li>Set that file as an image (old-style) on the individual.</li>
* </ul>
*/
private void createMainImageFromThumbnail(Resource resource) {
String thumbFilename = getValues(resource, thumbProperty).get(0);
String mainFilename = addFilenamePrefix("_main_image_", thumbFilename);
updateLog.log(resource, "creating a main file at '" + mainFilename
+ "' to match the thumbnail at '" + thumbFilename + "'");
try {
File thumbFile = imageDirectoryWithBackup
.getExistingFile(thumbFilename);
File mainFile = imageDirectoryWithBackup.getNewfile(mainFilename);
mainFile = checkNameConflicts(mainFile);
FileUtil.copyFile(thumbFile, mainFile);
ResourceWrapper.addProperty(resource, imageProperty, mainFilename);
} catch (IOException e) {
updateLog.error(resource, "failed to create main file '"
+ mainFilename + "'", e);
}
}
}

View file

@ -1,71 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.io.File;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
/**
* Removes any image properties (main or thumbnail) that point to files that
* don't actually exist.
*/
public class DeadEndPropertyRemover extends FsuScanner {
private ImageDirectoryWithBackup imageDirectoryWithBackup;
public DeadEndPropertyRemover(FSUController controller) {
super(controller);
this.imageDirectoryWithBackup = controller
.getImageDirectoryWithBackup();
}
/**
* Remove dead end properties for both main images and thumbnails.
*/
public void remove() {
updateLog.section("Removing image properties whose "
+ "referenced files do not exist.");
removeDeadEndProperties(imageProperty, "main image");
removeDeadEndProperties(thumbProperty, "thumbnail");
}
/**
* Check all of the individuals that possess this property.
*/
private void removeDeadEndProperties(Property prop, String label) {
for (Resource resource : ModelWrapper.listResourcesWithProperty(model,
prop)) {
removeDeadEndPropertiesFromResource(resource, prop, label);
}
}
/**
* Check these statments on this resource. If any of them does not point to
* an existing file, remove the statement.
*/
private void removeDeadEndPropertiesFromResource(Resource resource,
Property prop, String label) {
for (Statement stmt : getStatements(resource, prop)) {
RDFNode node = stmt.getObject();
if (node.isLiteral()) {
String filename = ((Literal) node).getString();
File file = imageDirectoryWithBackup.getExistingFile(filename);
if (!file.exists()) {
updateLog.warn(
resource,
"removing link to " + label + " '" + filename
+ "': file does not exist at '"
+ file.getAbsolutePath() + "'.");
ModelWrapper.removeStatement(model, stmt);
}
}
}
}
}

View file

@ -1,38 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.io.File;
import com.hp.hpl.jena.rdf.model.Model;
import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper;
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
/**
* An object that can initialize one of the {@link FsuScanner}s.
*/
public interface FSUController {
/** The Jena model. */
Model getModel();
/** The update log. */
FSULog getUpdateLog();
/** The place to find or to create image files. */
ImageDirectoryWithBackup getImageDirectoryWithBackup();
/** A helper with access to the DAO layer and the file storage system. */
UploadedFileHelper getUploadedFileHelper();
/** The file storage system. */
FileStorage getFileStorage();
/** Where to store the files that were translated. */
File getTranslatedDirectory();
/** Where to store the files that weren't in use anyway. */
File getUnreferencedDirectory();
}

View file

@ -1,181 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
/**
* Writes the log file for the {@link FileStorageUpdater}. Be sure to call
* {@link #close()} when finished.
*/
public class FSULog {
private final SimpleDateFormat timeStamper = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
private final File logFile;
private final PrintWriter writer;
private boolean open;
FSULog(File logDirectory, String prefix) throws IOException {
this.logFile = generateTimestampedFilename(logDirectory, prefix);
this.writer = new PrintWriter(this.logFile);
open = true;
}
/**
* Create a filename for the log file that contains a timestamp, so if we
* run the process more than once, we will see multiple files.
*/
private File generateTimestampedFilename(File upgradeDirectory,
String prefix) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-sss");
String filename = prefix + "." + sdf.format(new Date()) + ".txt";
return new File(upgradeDirectory, filename);
}
/**
* Where are we writing the output?
*/
String getFilename() {
return this.logFile.getAbsolutePath();
}
/**
* Write this message.
*/
void log(String message) {
writer.println(timeStamper.format(new Date()) + " INFO " + message);
}
/**
* Write this message about this resource.
*/
void log(Resource resource, String message) {
log(showResource(resource) + message);
}
/**
* Write this warning message.
*/
public void warn(String message) {
writer.println(timeStamper.format(new Date()) + " WARN " + message);
}
/**
* Write this warning message about this resource.
*/
public void warn(Resource resource, String message) {
warn(showResource(resource) + message);
}
/**
* Write this error message.
*/
void error(String message) {
writer.println(timeStamper.format(new Date()) + " ERROR " + message);
}
/**
* Write this exception as an error message..
*/
void error(Exception e) {
error(e.toString());
e.printStackTrace(writer);
}
/**
* Write an error message with this exception.
*/
public void error(String message, Exception e) {
error(message);
e.printStackTrace(writer);
}
/**
* Write an error message about this resource and with this exception.
*/
public void error(Resource resource, String message) {
error(showResource(resource) + message);
}
/**
* Write an error message about this resource and with this exception.
*/
public void error(Resource resource, String message, Exception e) {
error(showResource(resource) + message, e);
}
/**
* Write a section heading.
*/
public void section(String message) {
log(">>>>>>>>>> ");
log(">>>>>>>>>> " + message);
log(">>>>>>>>>> ");
}
/**
* Close the writer, if not already closed.
*/
public void close() {
if (open) {
writer.close();
open = false;
}
}
/**
* Format the resource label and URI for output in a message.
*/
private String showResource(Resource resource) {
return "On resource '" + getLabel(resource) + "' (" + getUri(resource)
+ "), ";
}
/**
* Find the URI for this resource, if there is one.
*/
private String getUri(Resource resource) {
if (resource != null) {
String uri = resource.getURI();
if (uri != null) {
return uri;
}
}
return "no URI";
}
/**
* Find the label for this resource, if there is one.
*/
private String getLabel(Resource resource) {
if (resource != null) {
Model model = resource.getModel();
if (model != null) {
Property prop = model.createProperty(VitroVocabulary.LABEL);
Statement stmt = resource.getProperty(prop);
if (stmt != null) {
RDFNode node = stmt.getObject();
if (node.isLiteral()) {
return ((Literal) node).getString();
}
}
}
}
return "no label";
}
}

View file

@ -1,352 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
/**
* Check all of the FileByteStream objects. If there are any that don't have
* alias URLs, fix them.
*/
public class FileStorageAliasAdder {
private static final Log log = LogFactory
.getLog(FileStorageAliasAdder.class);
private static final String FILE_PATH = "/file/";
/**
* Query: get all bytestream resources that do not have alias URLs.
*/
private static final String QUERY_BYTESTREAMS_WITHOUT_ALIASES = ""
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX public: <http://vitro.mannlib.cornell.edu/ns/vitro/public#>\n"
+ "SELECT ?bs\n" + "WHERE {\n"
+ " ?bs rdf:type public:FileByteStream\n"
+ " OPTIONAL { ?bs public:directDownloadUrl ?alias }\n"
+ " FILTER ( !BOUND(?alias) )\n" + "}\n";
/**
* Query: get the filenames for all bytestream resources that do not have
* alias URLs.
*/
private static final String QUERY_FILENAMES_FOR_BYTESTREAMS = ""
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX public: <http://vitro.mannlib.cornell.edu/ns/vitro/public#>\n"
+ "SELECT ?bs ?fn\n" + "WHERE {\n"
+ " ?bs rdf:type public:FileByteStream . \n"
+ " ?f public:downloadLocation ?bs . \n"
+ " ?f public:filename ?fn . \n"
+ " OPTIONAL { ?bs public:directDownloadUrl ?alias . }\n"
+ " FILTER ( !BOUND(?alias) )\n" + "}\n";
private final Model model;
private final File upgradeDirectory;
private final String vivoDefaultNamespace;
private FSULog updateLog;
private Set<String> bytestreamUrisWithoutAliases;
private Map<String, String> bytestreamUrisAndFilenames;
public FileStorageAliasAdder(Model model, File uploadDirectory,
String vivoDefaultNamespace) {
this.model = model;
this.upgradeDirectory = new File(uploadDirectory, "upgrade");
this.vivoDefaultNamespace = vivoDefaultNamespace;
}
/**
* Go through all of the FileByteStream objects in the model, creating Alias
* URLs for any objects that don't have them.
*
* If there is nothing to do, don't even create a log file, just exit.
*
* If there is something to do, go through the whole process.
*
* At the end, there should be nothing to do.
*/
public void update() {
// If there is nothing to do, we're done: don't even create a log file.
if (!isThereAnythingToDo()) {
log.debug("Found no FileByteStreams without alias URLs.");
return;
}
setup();
try {
findAndAddMissingAliasUrls();
if (isThereAnythingToDo()) {
throw new IllegalStateException("FileStorageAliasAdder "
+ "was unsuccessful -- model still contains "
+ "FileByteStreams without alias URLs.");
}
updateLog.section("Finished adding alias URLs to FileByteStreams.");
} finally {
updateLog.close();
}
log.info("Finished adding alias URLs to FileByteStreams.");
}
/**
* Query the model. If there are any FileByteStream objects with no Alias
* URL, we have work to do.
*/
private boolean isThereAnythingToDo() {
String queryString = QUERY_BYTESTREAMS_WITHOUT_ALIASES;
log.debug("query: " + queryString);
QueryExecution qexec = null;
try {
qexec = createQueryExecutor(queryString);
ResultSet results = qexec.execSelect();
boolean foundSome = results.hasNext();
log.debug("any work to do? " + foundSome);
return foundSome;
} catch (Exception e) {
log.error(e, e);
return false;
} finally {
if (qexec != null) {
qexec.close();
}
}
}
/**
* Create the upgrade directory. Create the log file. If we fail, drop dead.
*/
private void setup() {
try {
this.upgradeDirectory.mkdirs();
updateLog = new FSULog(this.upgradeDirectory,
"FileStorageAliasAdder-log");
log.info("Updating pre-1.1 file references. Log file is "
+ updateLog.getFilename());
} catch (IOException e) {
if (updateLog != null) {
updateLog.close();
}
throw new IllegalStateException("can't create log file: '"
+ updateLog.getFilename() + "'", e);
}
}
/**
* Add an alias URL to any FileByteStream object that doesn't have one.
*/
private void findAndAddMissingAliasUrls() {
findBytestreamsWithoutAliasUrls();
findFilenamesForBytestreams();
addAliasUrlsToModel();
}
/**
* Find every bytestream that doesn't have an alias URL.
*/
private void findBytestreamsWithoutAliasUrls() {
BytestreamUriUnpacker unpacker = new BytestreamUriUnpacker();
runQuery(QUERY_BYTESTREAMS_WITHOUT_ALIASES, unpacker);
this.bytestreamUrisWithoutAliases = unpacker.getUris();
log.debug("Found " + unpacker.getUris().size()
+ " bytestreams without alias URLs");
}
/**
* Find the filename for every bytestream that doesn't have an alias URL.
*/
private void findFilenamesForBytestreams() {
FilenameUnpacker unpacker = new FilenameUnpacker();
runQuery(QUERY_FILENAMES_FOR_BYTESTREAMS, unpacker);
this.bytestreamUrisAndFilenames = unpacker.getFilenameMap();
log.debug("Found " + unpacker.getFilenameMap().size()
+ " bytestreams with filenames but no alias URLs");
}
/** Add an alias URL to each resource in the list. */
private void addAliasUrlsToModel() {
if (this.bytestreamUrisWithoutAliases.isEmpty()) {
updateLog.warn("Found no bytestreams without aliases. "
+ "Why am I here?");
return;
}
Property aliasProperty = model
.createProperty(VitroVocabulary.FS_ALIAS_URL);
for (String bytestreamUri : this.bytestreamUrisWithoutAliases) {
String aliasUrl = figureAliasUrl(bytestreamUri);
Resource resource = model.getResource(bytestreamUri);
ModelWrapper.add(model, resource, aliasProperty, aliasUrl);
updateLog.log(resource, "added alias URL: '" + aliasUrl + "'");
}
}
/**
* Convert the bytestream URI and the filename into an alias URL.
*
* If they aren't in our default namespace, or they don't have a filename,
* then their URI is the best we can do for an alias URL.
*/
private String figureAliasUrl(String bytestreamUri) {
if (!bytestreamUri.startsWith(vivoDefaultNamespace)) {
updateLog.warn("bytestream uri does not start "
+ "with the default namespace: '" + bytestreamUri + "'");
return bytestreamUri;
}
String filename = this.bytestreamUrisAndFilenames.get(bytestreamUri);
if (filename == null) {
updateLog.warn("bytestream has no surrogate or no filename: '"
+ bytestreamUri + "'");
return "filename_not_found";
}
try {
String remainder = bytestreamUri.substring(vivoDefaultNamespace
.length());
String encodedFilename = URLEncoder.encode(filename, "UTF-8");
String separator = remainder.endsWith("/") ? "" : "/";
return FILE_PATH + remainder + separator + encodedFilename;
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e); // No UTF-8? Can't happen.
}
}
private void runQuery(String queryString, QueryResultUnpacker unpacker) {
log.debug("query: " + queryString);
QueryExecution qexec = null;
try {
qexec = createQueryExecutor(queryString);
Iterator<QuerySolution> results = qexec.execSelect();
while (results.hasNext()) {
QuerySolution result = results.next();
if (log.isDebugEnabled()) {
log.debug("Query result variables: "
+ listVariables(result));
}
unpacker.unpack(result);
}
} catch (Exception e) {
log.error(e, e);
} finally {
if (qexec != null) {
qexec.close();
}
}
}
private QueryExecution createQueryExecutor(String queryString) {
Query query = QueryFactory.create(queryString);
return QueryExecutionFactory.create(query, model);
}
/** For debug logging. */
private List<String> listVariables(QuerySolution result) {
List<String> list = new ArrayList<String>();
for (Iterator<String> names = result.varNames(); names.hasNext();) {
String name = names.next();
RDFNode value = result.get(name);
list.add(name + "=" + value);
}
return list;
}
// ----------------------------------------------------------------------
// Helper classes
// ----------------------------------------------------------------------
private interface QueryResultUnpacker {
public abstract void unpack(QuerySolution result);
}
private class BytestreamUriUnpacker implements QueryResultUnpacker {
private final Set<String> uris = new HashSet<String>();
@Override
public void unpack(QuerySolution result) {
Resource bytestream = result.getResource("bs");
if (bytestream == null) {
updateLog.error("Query result contains no "
+ "bytestream resource: " + result);
return;
}
uris.add(bytestream.getURI());
}
public Set<String> getUris() {
return uris;
}
}
private class FilenameUnpacker implements QueryResultUnpacker {
private final Map<String, String> filenameMap = new HashMap<String, String>();
@Override
public void unpack(QuerySolution result) {
Resource bytestream = result.getResource("bs");
if (bytestream == null) {
updateLog.error("Query result contains no "
+ "bytestream resource: " + result);
return;
}
String bytestreamUri = bytestream.getURI();
Literal filenameLiteral = result.getLiteral("fn");
if (filenameLiteral == null) {
updateLog.error("Query result for '" + bytestreamUri
+ "' contains no filename.");
return;
}
String filename = filenameLiteral.getString();
filenameMap.put(bytestreamUri, filename);
}
public Map<String, String> getFilenameMap() {
return filenameMap;
}
}
}

View file

@ -1,268 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.rdf.model.Model;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper;
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
/**
* <p>
* Clean up any files that are stored in the old directory structure and
* referenced by old-style image properties.
* </p>
* <p>
* Besides converting the files to the new framework, this process will produce
* these artifacts:
* <ul>
* <li>A log file in the uploaded files directory, with a timestamped name, such
* as <code>upgrade/upgradeLog2010-06-20T14-55-00.txt</code>, for example. If
* for any reason, the upgrade process must run again, the log will not be
* overwritten.</li>
* <li>A directory of "deleted" files - these were extra thumbnail files or
* extra main image files -- see the details below.</li>
* <li>A directory of "unreferenced" files - these were in the image directory,
* but not connected to any entity.</li>
* </ul>
* </p>
* <p>
* We consider some special cases:
* <ul>
* <li>An individual may refer to an image file that does not actually exist. If
* so, that reference will be deleted.</li>
* <li>There may be more than one reference to the same image file. If so, all
* but the first such reference will be deleted.</li>
* <li>
* In the old style, it was possible to have a main image without a thumbnail.
* If we find that, we will generate a scaled down copy of the main image, store
* that as a thumbnail image file, and then proceed.</li>
* <li>
* In the old style, it was possible to have a thumbnail without a main image.
* If we find that, we will make a copy of the thumbnail image file, declare
* that copy to be the main image, and then proceed.</li>
* <li>
* We may find individuals with more than one main image, or more than one
* thumbnail. If so, we will discard all but the first one (move them to the
* "deleted" directory).</li>
* </ul>
* </p>
* <p>
* Aside from these special cases, we will:
* <ul>
* <li>Translate the main image.
* <ul>
* <li>Store the image in the new file system.</li>
* <li>Delete the image from the old images directory.</li>
* <li>Create a ByteStream individual for the main image.</li>
* <li>Create a Surrogate individual for the main image.</li>
* <li>Tie these together and attach to the entity that owns the image.</li>
* </ul>
* </li>
* <li>Translate the thumbnail.
* <ul>
* <li>Store the thumbnail in the new file system.</li>
* <li>Create a ByteStream individual for the thumbnail.</li>
* <li>Create a Surrogate individual for the thumbnail.</li>
* <li>Tie these together and attach to the Surrogate for the main image.</li>
* </ul>
* </li>
* </ul>
* </p>
* <p>
* After processing all of these cases, there may be some images remaining in
* the "images" directory. These will be moved to the "unreferenced" directory,
* while preserving any internal tree structure.
* </p>
*/
public class FileStorageUpdater implements FSUController {
private static final Log log = LogFactory.getLog(FileStorageUpdater.class);
/** How wide should a generated thumbnail image be (in pixels)? */
public static final int THUMBNAIL_WIDTH = 200;
/** How high should a generated thumbnail image be (in pixels)? */
public static final int THUMBNAIL_HEIGHT = 200;
/** How is the main image referenced in the old scheme? */
public static final String IMAGEFILE = VitroVocabulary.vitroURI
+ "imageFile";
/** How is the thumbnail referenced in the old scheme? */
public static final String IMAGETHUMB = VitroVocabulary.vitroURI
+ "imageThumb";
private final Model model;
private final FileStorage fileStorage;
private final UploadedFileHelper uploadedFileHelper;
private final ImageDirectoryWithBackup imageDirectoryWithBackup;
private final File upgradeDirectory;
private FSULog updateLog;
public FileStorageUpdater(WebappDaoFactory wadf, Model model,
FileStorage fileStorage, File uploadDirectory,
File webappImageDirectory, ServletContext ctx) {
this.model = model;
this.fileStorage = fileStorage;
this.uploadedFileHelper = new UploadedFileHelper(fileStorage, wadf, ctx);
this.upgradeDirectory = new File(uploadDirectory, "upgrade");
this.imageDirectoryWithBackup = new ImageDirectoryWithBackup(new File(
uploadDirectory, "images"), webappImageDirectory);
}
/**
* <p>
* Go through all of the individuals who have image files or thumbnail
* files, adjusting them to the new way.
* </p>
* <p>
* If there is nothing to do, don't even create a log file, just exit.
* </p>
* <p>
* If there is something to do, go through the whole process.
* </p>
* <p>
* At the end, there should be nothing to do. If that's true, clean out the
* old images directory.
* </p>
*/
public void update() {
// If there is nothing to do, we're done: don't even create a log file.
if (!isThereAnythingToDo()) {
log.debug("Found no pre-1.1 file references.");
return;
}
// Create the upgrade directory and the log file.
setup();
try {
// Remove any image properties that don't point to literals.
new NonLiteralPropertyRemover(this).remove();
// Remove any image properties that point to files that don't exist.
new DeadEndPropertyRemover(this).remove();
// No resource may have multiple main images or multiple thumbnails.
new MultiplePropertyRemover(this).remove();
// Create a main image for any thumbnail that doesn't have one.
new AllThumbsAdjuster(this).adjust();
// Create a thumbnail for any main image that doesn't have one.
new NoThumbsAdjuster(this).adjust();
// Copy all images into the new file storage system, translating
// into the new schema. Get a list of all the images we translated.
ImageSchemaTranslater translater = new ImageSchemaTranslater(this);
Collection<String> translatedFiles = translater.translate();
if (isThereAnythingToDo()) {
throw new IllegalStateException(
"FileStorageUpdate was unsuccessful -- "
+ "model still contains pre-1.1 file references.");
}
// Clean out the old image directory, separating into files which
// were translated, and files for which we found no reference.
new ImageDirectoryCleaner(this).clean(translatedFiles);
updateLog.section("File Storage update is complete.");
} finally {
updateLog.close();
}
log.info("Finished updating pre-1.1 file references.");
}
/**
* Query the model. If there are any resources with old-style image
* properties, we have work to do.
*/
private boolean isThereAnythingToDo() {
if (!ModelWrapper.listResourcesWithProperty(model,
model.createProperty(IMAGEFILE)).isEmpty()) {
return true;
}
if (!ModelWrapper.listResourcesWithProperty(model,
model.createProperty(IMAGETHUMB)).isEmpty()) {
return true;
}
return false;
}
/**
* Create the upgrade directory. Create the log file. If we fail, drop dead.
*/
private void setup() {
try {
this.upgradeDirectory.mkdirs();
updateLog = new FSULog(this.upgradeDirectory,
"FileStorageUpdater-log");
log.info("Updating pre-1.1 file references. Log file is "
+ updateLog.getFilename());
} catch (IOException e) {
if (updateLog != null) {
updateLog.close();
}
throw new IllegalStateException("can't create log file: '"
+ updateLog.getFilename() + "'", e);
}
}
// ----------------------------------------------------------------------
// Methods to set up the individual scanners.
// ----------------------------------------------------------------------
@Override
public Model getModel() {
return this.model;
}
@Override
public FSULog getUpdateLog() {
return this.updateLog;
}
@Override
public UploadedFileHelper getUploadedFileHelper() {
return this.uploadedFileHelper;
}
@Override
public FileStorage getFileStorage() {
return this.fileStorage;
}
@Override
public ImageDirectoryWithBackup getImageDirectoryWithBackup() {
return this.imageDirectoryWithBackup;
}
@Override
public File getTranslatedDirectory() {
return new File(this.upgradeDirectory, "translatedImages");
}
@Override
public File getUnreferencedDirectory() {
return new File(this.upgradeDirectory, "unreferencedImages");
}
}

View file

@ -1,107 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* A collection of static routines for moving, copying and deleting files.
*/
public class FileUtil {
/**
* Copy a file from one location to another, and remove it from the original
* location.
*/
public static void moveFile(File from, File to) throws IOException {
copyFile(from, to);
deleteFile(from);
}
/**
* Copy a file from one location to another.
*/
public static void copyFile(File from, File to) throws IOException {
if (!from.exists()) {
throw new FileNotFoundException("File '" + from.getAbsolutePath()
+ "' does not exist.");
}
InputStream in = null;
try {
in = new FileInputStream(from);
writeFile(in, to);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* Create a file with the contents of this data stream.
*
* @param stream
* the data stream. You must close it afterward.
*/
public static void writeFile(InputStream stream, File to)
throws IOException {
if (to.exists()) {
throw new IOException("File '" + to.getAbsolutePath()
+ "' already exists.");
}
File parent = to.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
if (!parent.exists()) {
throw new IOException("Can't create parent directory for '"
+ to.getAbsolutePath() + "'");
}
}
OutputStream out = null;
try {
out = new FileOutputStream(to);
byte[] buffer = new byte[8192];
int howMany;
while (-1 != (howMany = stream.read(buffer))) {
out.write(buffer, 0, howMany);
}
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* Delete this file, and make sure that it's gone.
*/
public static void deleteFile(File file) throws IOException {
file.delete();
if (file.exists()) {
throw new IOException("Failed to delete file '"
+ file.getAbsolutePath() + "'");
}
}
/** No need to instantiate it -- all methods are static. */
private FileUtil() {
// Nothing to instantiate.
}
}

View file

@ -1,126 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock;
/**
* Base class for the tools that scan the model. Holds some useful fields and
* some utility methods.
*/
public abstract class FsuScanner {
protected final Model model;
protected final FSULog updateLog;
protected final Property imageProperty;
protected final Property thumbProperty;
public FsuScanner(FSUController controller) {
this.model = controller.getModel();
this.updateLog = controller.getUpdateLog();
this.imageProperty = model.createProperty(FileStorageUpdater.IMAGEFILE);
this.thumbProperty = model
.createProperty(FileStorageUpdater.IMAGETHUMB);
}
/**
* Read all of the specified properties on a resource, and return a
* {@link List} of the {@link String} values.
*/
protected List<String> getValues(Resource resource, Property property) {
List<String> list = new ArrayList<String>();
StmtIterator stmts = resource.listProperties(property);
try {
while (stmts.hasNext()) {
Statement stmt = stmts.next();
RDFNode object = stmt.getObject();
if (object.isLiteral()) {
list.add(((Literal) object).getString());
} else {
updateLog.error(resource,
"property value was not a literal: "
+ "property is '" + property.getURI()
+ "', value is '" + object + "'");
}
}
} finally {
stmts.close();
}
return list;
}
/**
* Read all of the specified properties on a resource, and return a
* {@link List} of the {@link Statement}s.
*/
protected List<Statement> getStatements(Resource resource, Property property) {
List<Statement> list = new ArrayList<Statement>();
resource.getModel().enterCriticalSection(Lock.READ);
StmtIterator stmts = resource.listProperties(property);
try {
while (stmts.hasNext()) {
list.add(stmts.next());
}
} finally {
stmts.close();
resource.getModel().leaveCriticalSection();
}
return list;
}
/**
* Find the filename within a path so we can add this prefix to it, while
* retaining the path.
*/
protected String addFilenamePrefix(String prefix, String path) {
int slashHere = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
if (slashHere == -1) {
return prefix + path;
} else {
String dirs = path.substring(0, slashHere + 1);
String filename = path.substring(slashHere + 1);
return dirs + prefix + filename;
}
}
/**
* We are about to create a file - if a file of this name already exists,
* increment the name until we have no collision.
*
* @return the original file, or the file with the incremented name.
*/
protected File checkNameConflicts(final File file) {
if (!file.exists()) {
// No conflict.
return file;
}
File parent = file.getParentFile();
String filename = file.getName();
for (int i = 0; i < 100; i++) {
File newFile = new File(parent, i + filename);
if (!newFile.exists()) {
updateLog.log("File '" + file + "' already exists, using '"
+ newFile + "' to avoid conflict.");
return newFile;
}
}
updateLog.error("File '" + file
+ "' already exists. Unable to avoid conflict.");
return file;
}
}

View file

@ -1,134 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
/**
* Clean out the old image directory. Copy the files into the upgrade directory,
* separating into the ones that we translated, and the ones that weren't
* referenced.
*/
public class ImageDirectoryCleaner extends FsuScanner {
private final ImageDirectoryWithBackup imageDirectoryWithBackup;
protected final File translatedDirectory;
protected final File unreferencedDirectory;
public ImageDirectoryCleaner(FSUController controller) {
super(controller);
this.imageDirectoryWithBackup = controller
.getImageDirectoryWithBackup();
this.translatedDirectory = controller.getTranslatedDirectory();
this.unreferencedDirectory = controller.getUnreferencedDirectory();
}
/**
* Remove all of the files from the old image directory.
*/
public void clean(Collection<String> translatedFiles) {
updateLog.section("Cleaning the old image directory of "
+ "files that were translated.");
removeTranslatedFiles(translatedFiles);
updateLog.section("Cleaning the old image directory of "
+ "files that were not referenced.");
removeRemainingFiles(imageDirectoryWithBackup
.getPrimaryImageDirectory());
}
/**
* Move all of the files that we translated into the new system.
*/
private void removeTranslatedFiles(Collection<String> translatedFiles) {
for (String path : translatedFiles) {
File oldFile = new File(
imageDirectoryWithBackup.getPrimaryImageDirectory(), path);
if (oldFile.exists()) {
updateLog.log("moving image file '" + path
+ "' to the 'translated' directory.");
File deletedFile = new File(translatedDirectory, path);
try {
FileUtil.moveFile(oldFile, deletedFile);
} catch (IOException e) {
updateLog.error("Failed to move translated file '"
+ oldFile.getAbsolutePath() + "'");
}
} else {
updateLog.log("Not moving image file '" + path
+ "' to the 'translated' directory -- "
+ "found it in the backup directory.");
}
}
}
/**
* Go through the images directory, and discard any that remain. They must
* not have been referenced by any existing individuals.
*/
private void removeRemainingFiles(File directory) {
updateLog.log("Cleaning image directory '" + directory + "'");
try {
File targetDirectory = makeCorrespondingDirectory(directory);
File[] children = directory.listFiles();
if (children != null) {
for (File child : children) {
if (child.isDirectory()) {
removeRemainingFiles(child);
} else {
moveUnreferencedFile(targetDirectory, child);
}
}
}
} catch (IOException e) {
updateLog.error(
"Failed to clean images directory '"
+ directory.getAbsolutePath() + "'", e);
}
}
/**
* Move this file from its current location to its new home in the
* "unreferenced" directory. Log it.
*/
private void moveUnreferencedFile(File targetDirectory, File file) {
updateLog.log("Moving image file '" + file.getPath()
+ "' to the 'unreferenced' directory");
try {
File newFile = new File(targetDirectory, file.getName());
FileUtil.moveFile(file, newFile);
} catch (IOException e) {
updateLog.error(
"Can't move unreferenced file '" + file.getAbsolutePath()
+ "'", e);
}
}
/**
* Figure out the path from the "images" directory to this one, and create a
* corresponding directory in the "unreferenced" area.
*/
private File makeCorrespondingDirectory(File directory) throws IOException {
String imagesPath = imageDirectoryWithBackup.getPrimaryImageDirectory()
.getAbsolutePath();
String thisPath = directory.getAbsolutePath();
if (!thisPath.startsWith(imagesPath)) {
throw new IOException("Can't make a corresponding directory for '"
+ thisPath + "'");
}
String suffix = thisPath.substring(imagesPath.length());
File corresponding = new File(unreferencedDirectory, suffix);
corresponding.mkdirs();
if (!corresponding.exists()) {
throw new IOException("Failed to create corresponding directory '"
+ corresponding.getAbsolutePath() + "'");
}
return corresponding;
}
}

View file

@ -1,77 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.io.File;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A way to look for files in TOMCAT_WEBAPP/vivo/images, if they are not found
* in upload.directory/images.
*/
public class ImageDirectoryWithBackup {
private static final Log log = LogFactory
.getLog(ImageDirectoryWithBackup.class);
/** The primary image directory, where we do most of the manipulation. */
private final File uploadImageDirectory;
/**
* If we are looking for a file and don't find it in the primary directory,
* look for it here.
*/
private final File webappImageDirectory;
/**
* Be careful! webappImageDirectory may be null.
*/
public ImageDirectoryWithBackup(File uploadImageDirectory,
File webappImageDirectory) {
this.uploadImageDirectory = uploadImageDirectory;
this.webappImageDirectory = webappImageDirectory;
}
/**
* When looking to read a file, start by looking in the
* {@link #uploadImageDirectory}.
*
* If the file isn't found there, look in the {@link #webappImageDirectory}
* as a fallback.
*
* If not there either, return the pointer to the nonexistent file in the
* {@link #uploadImageDirectory}.
*/
File getExistingFile(String relativePath) {
File file1 = new File(uploadImageDirectory, relativePath);
if (file1.exists()) {
log.trace("Found file: " + file1.getAbsolutePath());
return file1;
}
if (webappImageDirectory != null) {
File file2 = new File(webappImageDirectory, relativePath);
if (file2.exists()) {
log.trace("Found file: " + file2.getAbsolutePath());
return file2;
}
}
log.trace("Didn't find file: " + file1.getAbsolutePath());
return file1;
}
/**
* New files will always be created in the primary directory.
*/
File getNewfile(String relativePath) {
return new File(uploadImageDirectory, relativePath);
}
/**
* You can get a direct reference to the primary image directory, but it
* should only be used for directory-base operations, like final cleanup.
*/
public File getPrimaryImageDirectory() {
return uploadImageDirectory;
}
}

View file

@ -1,170 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.commons.io.FilenameUtils;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper;
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
/**
* Make copies of the main image and thumbnail in the new file storage system,
* and in the model. Remove the old properties, but don't remove the old files
* yet, in case someone else is referring to them also.
*/
public class ImageSchemaTranslater extends FsuScanner {
private final ImageDirectoryWithBackup imageDirectoryWithBackup;
protected final FileStorage fileStorage;
protected final UploadedFileHelper uploadedFileHelper;
public ImageSchemaTranslater(FSUController controller) {
super(controller);
this.imageDirectoryWithBackup = controller
.getImageDirectoryWithBackup();
this.fileStorage = controller.getFileStorage();
this.uploadedFileHelper = controller.getUploadedFileHelper();
}
/**
* By the time we get here, any individual with a main image also has a
* thumbnail, and vice versa, and exactly one of each. For each one,
* translate the main image and the thumbnail into the new system.
*/
public Collection<String> translate() {
updateLog.section("Copying images into the new file storage, "
+ "and adding them to the new model.");
SortedSet<String> translated = new TreeSet<String>();
ResIterator haveImage = model.listResourcesWithProperty(imageProperty);
try {
while (haveImage.hasNext()) {
Resource resource = haveImage.next();
translateImages(resource, translated);
}
} finally {
haveImage.close();
}
return translated;
}
/**
* This individual should have exactly one main image and exactly one
* thumbnail.
* <ul>
* <li>Translate the first main image into the new system.</li>
* <li>Translate the first thumbnail into the new system.</li>
* <li>Remove all old-style main image properties.</li>
* <li>Remove all old-style thumbnail properties.</li>
* </ul>
*/
private void translateImages(Resource resource,
Collection<String> translated) {
List<String> mainImages = getValues(resource, imageProperty);
if (mainImages.size() != 1) {
updateLog.error(resource, "has " + mainImages.size()
+ " main images: " + mainImages);
return;
}
List<String> thumbnails = getValues(resource, thumbProperty);
if (thumbnails.size() != 1) {
updateLog.error(resource, "has " + thumbnails.size()
+ " thumbnails: " + thumbnails);
return;
}
FileInfo main = translateFile(resource, mainImages.get(0), "main image");
FileInfo thumb = translateFile(resource, thumbnails.get(0), "thumbnail");
if ((main == null) || (thumb == null)) {
return;
}
uploadedFileHelper.setImagesOnEntity(resource.getURI(), main, thumb);
translated.add(mainImages.get(0));
ResourceWrapper.removeAll(resource, imageProperty);
translated.add(thumbnails.get(0));
ResourceWrapper.removeAll(resource, thumbProperty);
}
/**
* Translate an image file into the new system
* <ul>
* <li>Attempt to infer MIME type.</li>
* <li>Copy into the File system.</li>
* <li>Create the File and Bytestream individuals in the model.</li>
* </ul>
*/
private FileInfo translateFile(Resource resource, String path, String label) {
File oldFile = imageDirectoryWithBackup.getExistingFile(path);
String filename = getSimpleFilename(path);
String mimeType = guessMimeType(resource, filename);
InputStream inputStream = null;
try {
inputStream = new FileInputStream(oldFile);
// Create the file individuals in the model
FileInfo fileInfo = uploadedFileHelper.createFile(filename,
mimeType, inputStream);
updateLog.log(resource, "translating " + label + " '" + path
+ "' into the file storage as '" + fileInfo.getUri() + "'");
return fileInfo;
} catch (IOException e) {
updateLog.error(resource, "Can't create the " + label + " file. ",
e);
return null;
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* Remove any path parts, and just get the filename and extension.
*/
private String getSimpleFilename(String path) {
return FilenameUtils.getName(path);
}
/**
* Guess what the MIME type might be.
*/
private String guessMimeType(Resource resource, String filename) {
if (filename.endsWith(".gif") || filename.endsWith(".GIF")) {
return "image/gif";
} else if (filename.endsWith(".png") || filename.endsWith(".PNG")) {
return "image/png";
} else if (filename.endsWith(".jpg") || filename.endsWith(".JPG")) {
return "image/jpeg";
} else if (filename.endsWith(".jpeg") || filename.endsWith(".JPEG")) {
return "image/jpeg";
} else if (filename.endsWith(".jpe") || filename.endsWith(".JPE")) {
return "image/jpeg";
} else {
updateLog.warn(resource,
"can't recognize the MIME type of this image file: '"
+ filename + "'");
return "image";
}
}
}

View file

@ -1,54 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.shared.Lock;
/**
* Utility methods that operate against the Model with proper locks.
*/
public class ModelWrapper {
public static Collection<Resource> listResourcesWithProperty(Model model,
Property property) {
List<Resource> list = new ArrayList<Resource>();
ResIterator iterator = model.listResourcesWithProperty(property);
try {
while (iterator.hasNext()) {
Resource resource = iterator.next();
list.add(resource);
}
} finally {
iterator.close();
}
return list;
}
public static void removeStatement(Model model, Statement stmt) {
model.enterCriticalSection(Lock.WRITE);
try {
model.remove(stmt);
} finally {
model.leaveCriticalSection();
}
}
public static void add(Model model, Resource subject, Property predicate,
String value) {
model.enterCriticalSection(Lock.WRITE);
try {
model.add(subject, predicate, value);
} finally {
model.leaveCriticalSection();
}
}
}

View file

@ -1,65 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.util.List;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
/**
* If a resource has more than one image or more than one thumbnail, this
* discards the extras.
*/
public class MultiplePropertyRemover extends FsuScanner {
public MultiplePropertyRemover(FSUController controller) {
super(controller);
}
/**
* By now, we have removed any non-literals or dead ends, so keep the first
* one and discard any extras.
*/
public void remove() {
updateLog.section("Checking for resources with more "
+ "than one main image, or more than one thumbnail.");
removeExtraProperties(imageProperty, "main image");
removeExtraProperties(thumbProperty, "thumbnail");
}
/**
* Check each resource that has this property.
*/
public void removeExtraProperties(Property prop, String label) {
for (Resource resource : ModelWrapper.listResourcesWithProperty(model,
prop)) {
removeExtraProperties(resource, prop, label);
}
}
/**
* If this resource has more than one of this property, delete the extras.
*/
private void removeExtraProperties(Resource resource, Property prop,
String label) {
List<Statement> stmts = getStatements(resource, prop);
for (int i = 1; i < stmts.size(); i++) {
Statement stmt = stmts.get(i);
RDFNode node = stmt.getObject();
if (node.isLiteral()) {
String value = ((Literal) node).getString();
updateLog.warn(resource, "removing extra " + label
+ " property: '" + value + "'");
} else {
updateLog.warn(resource, "removing extra " + label
+ " property: '" + node + "'");
}
ModelWrapper.removeStatement(model, stmt);
}
}
}

View file

@ -1,173 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.THUMBNAIL_HEIGHT;
import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.THUMBNAIL_WIDTH;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import com.hp.hpl.jena.rdf.model.Resource;
import com.sun.media.jai.codec.MemoryCacheSeekableStream;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.CropRectangle;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadThumbnailer;
/**
* Adjust any individual that has a main image but no thumbnail.
*/
public class NoThumbsAdjuster extends FsuScanner {
private ImageDirectoryWithBackup imageDirectoryWithBackup;
public NoThumbsAdjuster(FSUController controller) {
super(controller);
this.imageDirectoryWithBackup = controller
.getImageDirectoryWithBackup();
}
/**
* For every individual with main images but no thumbnails, create a
* thumbnail from the first main image.
*/
public void adjust() {
updateLog.section("Creating thumbnails to match main images.");
for (Resource resource : ModelWrapper.listResourcesWithProperty(model,
imageProperty)) {
if (resource.getProperty(thumbProperty) == null) {
createThumbnailFromMainImage(resource);
}
}
}
/**
* This individual has a main image but no thumbnail. Create one.
* <ul>
* <li>Figure a name for the thumbnail image.</li>
* <li>Make a scaled copy of the main image into the thumbnail.</li>
* <li>Set that file as a thumbnail (old-style) on the individual.</li>
* </ul>
*/
private void createThumbnailFromMainImage(Resource resource) {
String mainFilename = getValues(resource, imageProperty).get(0);
String thumbFilename = addFilenamePrefix("_thumbnail_", mainFilename);
updateLog.log(resource, "creating a thumbnail at '" + thumbFilename
+ "' from the main image at '" + mainFilename + "'");
File mainFile = imageDirectoryWithBackup.getExistingFile(mainFilename);
File thumbFile = imageDirectoryWithBackup.getNewfile(thumbFilename);
thumbFile = checkNameConflicts(thumbFile);
try {
CropRectangle crop = getImageSize(mainFile);
if (imageIsSmallEnoughAlready(crop)) {
copyMainImageToThumbnail(mainFile, thumbFile);
} else {
cropScaleAndStore(crop, mainFile, thumbFile);
}
ResourceWrapper.addProperty(resource, thumbProperty, thumbFilename);
} catch (IOException e) {
updateLog.error(resource, "failed to create thumbnail file '"
+ thumbFilename + "'", e);
}
}
private CropRectangle getImageSize(File file) throws IOException {
InputStream imageSource = null;
try {
imageSource = new FileInputStream(file);
MemoryCacheSeekableStream stream = new MemoryCacheSeekableStream(
imageSource);
RenderedOp image = JAI.create("stream", stream);
return new CropRectangle(0, 0, image.getHeight(), image.getWidth());
} finally {
if (imageSource != null) {
try {
imageSource.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private boolean imageIsSmallEnoughAlready(CropRectangle crop) {
return (crop.height <= THUMBNAIL_HEIGHT)
&& (crop.width <= THUMBNAIL_WIDTH);
}
private void copyMainImageToThumbnail(File mainFile, File thumbFile)
throws IOException {
InputStream imageSource = null;
try {
imageSource = new FileInputStream(mainFile);
storeImage(imageSource, thumbFile);
} finally {
if (imageSource != null) {
try {
imageSource.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void cropScaleAndStore(CropRectangle crop, File mainFile,
File thumbFile) throws IOException {
InputStream mainImageStream = null;
InputStream imageSource = null;
try {
mainImageStream = new FileInputStream(mainFile);
ImageUploadThumbnailer iut = new ImageUploadThumbnailer(
THUMBNAIL_HEIGHT, THUMBNAIL_WIDTH);
imageSource = iut.cropAndScale(mainImageStream, crop);
storeImage(imageSource, thumbFile);
} finally {
if (mainImageStream != null) {
try {
mainImageStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (imageSource != null) {
try {
imageSource.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void storeImage(InputStream source, File file) throws IOException {
OutputStream sink = null;
try {
sink = new FileOutputStream(file);
byte[] buffer = new byte[8192];
int howMany;
while (-1 != (howMany = source.read(buffer))) {
sink.write(buffer, 0, howMany);
}
} finally {
if (sink != null) {
try {
sink.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

View file

@ -1,71 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.util.ArrayList;
import java.util.List;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.shared.Lock;
/**
* All image properties should have literal values. Burn any that don't.
*/
public class NonLiteralPropertyRemover extends FsuScanner {
public NonLiteralPropertyRemover(FSUController controller) {
super(controller);
}
/**
* Remove any image properties whose objects are not {@link Literal}s.
*/
public void remove() {
updateLog.section("Checking for image properties whose objects "
+ "are not literals.");
removeNonLiterals(imageProperty, "image file");
removeNonLiterals(thumbProperty, "thumbnail");
}
/**
* Check all resources for bogus values on this property.
*/
private void removeNonLiterals(Property prop, String label) {
for (Resource resource : ModelWrapper.listResourcesWithProperty(model,
prop)) {
removeNonLiterals(resource, prop, label);
}
}
/**
* Check this resource for bogus values onthis property.
*/
private void removeNonLiterals(Resource resource, Property prop,
String label) {
List<RDFNode> bogusValues = new ArrayList<RDFNode>();
for (Statement stmt : ResourceWrapper.listProperties(resource, prop)) {
RDFNode object = stmt.getObject();
if (!object.isLiteral()) {
bogusValues.add(object);
}
}
for (RDFNode bogusValue : bogusValues) {
updateLog.warn(resource, "discarding " + label
+ " property with non-literal as object: '" + bogusValue
+ "'");
model.enterCriticalSection(Lock.WRITE);
try {
model.createStatement(resource, prop, bogusValue).remove();
} finally {
model.leaveCriticalSection();
}
}
}
}

View file

@ -1,63 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock;
/**
* Utility methods that get the appropriate model locks before manipluating
* resources.
*/
public class ResourceWrapper {
public static Statement getProperty(Resource resource, Property property) {
resource.getModel().enterCriticalSection(Lock.READ);
try {
return resource.getProperty(property);
} finally {
resource.getModel().leaveCriticalSection();
}
}
public static void addProperty(Resource resource, Property property,
String value) {
resource.getModel().enterCriticalSection(Lock.WRITE);
try {
resource.addProperty(property, value);
} finally {
resource.getModel().leaveCriticalSection();
}
}
public static void removeAll(Resource resource, Property property) {
resource.getModel().enterCriticalSection(Lock.WRITE);
try {
resource.removeAll(property);
} finally {
resource.getModel().leaveCriticalSection();
}
}
public static Collection<Statement> listProperties(Resource resource,
Property prop) {
List<Statement> list = new ArrayList<Statement>();
StmtIterator stmts = resource.listProperties(prop);
try {
while (stmts.hasNext()) {
list.add(stmts.next());
}
return list;
} finally {
stmts.close();
}
}
}

View file

@ -5,6 +5,10 @@ package edu.cornell.mannlib.vitro.webapp.filters;
import java.io.IOException; import java.io.IOException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -21,18 +25,27 @@ 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 com.hp.hpl.jena.graph.Graph;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.query.DataSource;
import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.DatasetFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.sdb.SDBFactory; import com.hp.hpl.jena.sdb.SDBFactory;
import com.hp.hpl.jena.sdb.Store; 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.sql.SDBConnection; import com.hp.hpl.jena.sdb.sql.SDBConnection;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig;
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
import edu.cornell.mannlib.vitro.webapp.dao.jena.SingleContentOntModelSelector;
import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraphMultilingual;
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
@ -89,6 +102,15 @@ public class WebappDaoFactorySDBPrep implements Filter {
Dataset dataset = null; Dataset dataset = null;
WebappDaoFactory wadf = null; WebappDaoFactory wadf = null;
// temporary scaffolding in the rdfapi dev branch
// TODO remove me
if (ConfigurationProperties.getBean(request).getProperty(
"VitroConnection.DataSource.endpointURI") != null) {
filterSparql(request, oms, defaultNamespace);
filterChain.doFilter(request, response);
return;
}
try { try {
if (bds == null || storeDesc == null || oms == null) { if (bds == null || storeDesc == null || oms == null) {
throw new RuntimeException("SDB store not property set up"); throw new RuntimeException("SDB store not property set up");
@ -140,6 +162,56 @@ public class WebappDaoFactorySDBPrep implements Filter {
} }
private void filterSparql(ServletRequest request, OntModelSelector oms, String defaultNamespace) {
log.info("---------");
VitroRequest vreq = new VitroRequest((HttpServletRequest) request);
Enumeration<String> headStrs = vreq.getHeaderNames();
while (headStrs.hasMoreElements()) {
String head = headStrs.nextElement();
log.info(head + " : " + vreq.getHeader(head));
}
List<String> langs = new ArrayList<String>();
log.info("Accept-Language: " + vreq.getHeader("Accept-Language"));
Enumeration<Locale> locs = vreq.getLocales();
while (locs.hasMoreElements()) {
Locale locale = locs.nextElement();
langs.add(locale.toString().replace("_", "-"));
log.info(locale.toString() + " / " + locale.getLanguage() + " + " + locale.getCountry() + " : " + locale.getDisplayCountry() + " | " + locale.getLanguage() + " : " + locale.getDisplayLanguage());
}
WebappDaoFactoryConfig config = new WebappDaoFactoryConfig();
config.setDefaultNamespace(defaultNamespace);
config.setPreferredLanguages(langs);
//okay let's make a graph-backed model
String endpointURI = ConfigurationProperties.getBean(
request).getProperty("VitroConnection.DataSource.endpointURI");
Graph g = new SparqlGraphMultilingual(endpointURI, langs);
//Graph g = new SparqlGraph(endpointURI);
Model m = ModelFactory.createModelForGraph(g);
OntModel om = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, m);
oms = new SingleContentOntModelSelector(om, oms.getDisplayModel(), oms.getUserAccountsModel());
DataSource dataset = DatasetFactory.create();
dataset.addNamedModel("fake:fake", m);
WebappDaoFactory wadf = new WebappDaoFactoryJena(oms, config);
//wadf = new WebappDaoFactorySDB(oms, dataset, config);
vreq.setWebappDaoFactory(wadf);
vreq.setFullWebappDaoFactory(wadf);
vreq.setUnfilteredWebappDaoFactory(wadf);
vreq.setWebappDaoFactory(wadf);
vreq.setAssertionsWebappDaoFactory(wadf);
vreq.setDataset(dataset);
vreq.setJenaOntModel(om);
vreq.setOntModelSelector(oms);
}
@Override @Override
public void init(FilterConfig filterConfig) throws ServletException { public void init(FilterConfig filterConfig) throws ServletException {
try { try {

View file

@ -43,12 +43,12 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent;
* Allows for real-time incremental materialization or retraction of RDFS- * Allows for real-time incremental materialization or retraction of RDFS-
* style class and property subsumption based ABox inferences as statements * style class and property subsumption based ABox inferences as statements
* are added to or removed from the (ABox or TBox) knowledge base. * are added to or removed from the (ABox or TBox) knowledge base.
* @author sjm222
*/ */
public class SimpleReasoner extends StatementListener { public class SimpleReasoner extends StatementListener {
private static final Log log = LogFactory.getLog(SimpleReasoner.class); private static final Log log = LogFactory.getLog(SimpleReasoner.class);
//private static final MyTempLogger log = new MyTempLogger();
private OntModel tboxModel; // asserted and inferred TBox axioms private OntModel tboxModel; // asserted and inferred TBox axioms
private OntModel aboxModel; // ABox assertions private OntModel aboxModel; // ABox assertions
@ -120,9 +120,9 @@ public class SimpleReasoner extends StatementListener {
} }
/* /*
* Performs selected incremental ABox reasoning based * Performs incremental ABox reasoning based
* on the addition of a new statement (aka assertion) * on the addition of a new statement
* to the ABox. * (aka assertion) to the ABox.
*/ */
@Override @Override
public void addedStatement(Statement stmt) { public void addedStatement(Statement stmt) {
@ -142,7 +142,7 @@ public class SimpleReasoner extends StatementListener {
} }
/* /*
* Performs selected incremental ABox reasoning based * Performs incremental ABox reasoning based
* on the retraction of a statement (aka assertion) * on the retraction of a statement (aka assertion)
* from the ABox. * from the ABox.
*/ */
@ -160,7 +160,12 @@ public class SimpleReasoner extends StatementListener {
} }
} }
public synchronized void handleRemovedStatement(Statement stmt) {
/*
* Synchronized part of removedStatement. Interacts
* with DeltaComputer.
*/
protected synchronized void handleRemovedStatement(Statement stmt) {
if (batchMode1) { if (batchMode1) {
aBoxDeltaModeler1.removedStatement(stmt); aBoxDeltaModeler1.removedStatement(stmt);
@ -176,7 +181,7 @@ public class SimpleReasoner extends StatementListener {
} }
/* /*
* Performs incremental selected ABox reasoning based * Performs incremental ABox reasoning based
* on changes to the class hierarchy. * on changes to the class hierarchy.
* *
* Handles rdfs:subclassOf, owl:equivalentClass, * Handles rdfs:subclassOf, owl:equivalentClass,
@ -229,7 +234,7 @@ public class SimpleReasoner extends StatementListener {
} }
/* /*
* Performs incremental selected ABox reasoning based * Performs incremental ABox reasoning based
* on changes to the class hierarchy. * on changes to the class hierarchy.
* *
* Handles rdfs:subclassOf, owl:equivalentClass, * Handles rdfs:subclassOf, owl:equivalentClass,
@ -281,10 +286,10 @@ public class SimpleReasoner extends StatementListener {
} }
} }
/* /*
* * This signature used when recomputing the whole ABox
*/ */
public void addedABoxTypeAssertion(Resource individual, Model inferenceModel, HashSet<String> unknownTypes) { protected void addedABoxTypeAssertion(Resource individual, Model inferenceModel, HashSet<String> unknownTypes) {
StmtIterator iter = null; StmtIterator iter = null;
@ -302,6 +307,7 @@ public class SimpleReasoner extends StatementListener {
aboxModel.leaveCriticalSection(); aboxModel.leaveCriticalSection();
} }
} }
/* /*
* Performs incremental reasoning based on a new type assertion * Performs incremental reasoning based on a new type assertion
* added to the ABox (assertion that an individual is of a certain * added to the ABox (assertion that an individual is of a certain
@ -309,9 +315,8 @@ public class SimpleReasoner extends StatementListener {
* *
* If it is added that B is of type A, then for each superclass of * If it is added that B is of type A, then for each superclass of
* A assert that B is of that type. * A assert that B is of that type.
*
*/ */
public void addedABoxTypeAssertion(Statement stmt, Model inferenceModel, HashSet<String> unknownTypes) { protected void addedABoxTypeAssertion(Statement stmt, Model inferenceModel, HashSet<String> unknownTypes) {
tboxModel.enterCriticalSection(Lock.READ); tboxModel.enterCriticalSection(Lock.READ);
@ -377,13 +382,10 @@ public class SimpleReasoner extends StatementListener {
* that B is of that type. * that B is of that type.
* *
*/ */
public void removedABoxTypeAssertion(Statement stmt, Model inferenceModel) { protected void removedABoxTypeAssertion(Statement stmt, Model inferenceModel) {
tboxModel.enterCriticalSection(Lock.READ); tboxModel.enterCriticalSection(Lock.READ);
// convert this method to use generic resources - not get ontclass, not cls.listSuperClasses...
// use model contains if want to log warning about type owl class
try { try {
OntClass cls = null; OntClass cls = null;
@ -431,7 +433,6 @@ public class SimpleReasoner extends StatementListener {
inferenceModel.enterCriticalSection(Lock.WRITE); inferenceModel.enterCriticalSection(Lock.WRITE);
try { try {
if (inferenceModel.contains(infStmt)) { if (inferenceModel.contains(infStmt)) {
//log.debug("Removing this inferred statement: " + infStmt.toString() + " - " + infStmt.getSubject().toString() + " - " + infStmt.getPredicate().toString() + " - " + infStmt.getObject().toString());
inferenceModel.remove(infStmt); inferenceModel.remove(infStmt);
} }
} finally { } finally {
@ -454,7 +455,7 @@ public class SimpleReasoner extends StatementListener {
// Returns true if it is entailed by class subsumption that // Returns true if it is entailed by class subsumption that
// subject is of type cls; otherwise returns false. // subject is of type cls; otherwise returns false.
public boolean entailedType(Resource subject, OntClass cls) { protected boolean entailedType(Resource subject, OntClass cls) {
aboxModel.enterCriticalSection(Lock.READ); aboxModel.enterCriticalSection(Lock.READ);
tboxModel.enterCriticalSection(Lock.READ); tboxModel.enterCriticalSection(Lock.READ);
@ -485,9 +486,9 @@ public class SimpleReasoner extends StatementListener {
/* /*
* If it is added that B is a subClass of A, then for each * If it is added that B is a subClass of A, then for each
* individual that is typed as B, either in the ABox or in the * individual that is typed as B, either in the ABox or in the
* inferred model, assert that it is of type A. * inferred model, infer that it is of type A.
*/ */
public void addedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) { protected void addedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) {
log.debug("subClass = " + subClass.getURI() + " superClass = " + superClass.getURI()); log.debug("subClass = " + subClass.getURI() + " superClass = " + superClass.getURI());
OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
unionModel.addSubModel(aboxModel); unionModel.addSubModel(aboxModel);
@ -530,7 +531,7 @@ public class SimpleReasoner extends StatementListener {
* UNLESS the individual is of some type C that is a subClass * UNLESS the individual is of some type C that is a subClass
* of A (including A itself) * of A (including A itself)
*/ */
public void removedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) { protected void removedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) {
OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
unionModel.addSubModel(aboxModel); unionModel.addSubModel(aboxModel);
unionModel.addSubModel(inferenceModel); unionModel.addSubModel(inferenceModel);
@ -567,10 +568,10 @@ public class SimpleReasoner extends StatementListener {
/* /*
* Find the most specific types (classes) of an individual and * Find the most specific types (classes) of an individual and
* indicate them for the individual with the core:mostSpecificType * indicate them for the individual with the mostSpecificType
* annotation. * annotation.
*/ */
public void setMostSpecificTypes(Resource individual, Model inferenceModel, HashSet<String> unknownTypes) { protected void setMostSpecificTypes(Resource individual, Model inferenceModel, HashSet<String> unknownTypes) {
tboxModel.enterCriticalSection(Lock.READ); tboxModel.enterCriticalSection(Lock.READ);
aboxModel.enterCriticalSection(Lock.READ); aboxModel.enterCriticalSection(Lock.READ);
@ -665,13 +666,13 @@ public class SimpleReasoner extends StatementListener {
return; return;
} }
public void setMostSpecificTypes(Resource individual, HashSet<String> typeURIs, Model inferenceModel) { protected void setMostSpecificTypes(Resource individual, HashSet<String> typeURIs, Model inferenceModel) {
inferenceModel.enterCriticalSection(Lock.WRITE); inferenceModel.enterCriticalSection(Lock.WRITE);
try { try {
Model retractions = ModelFactory.createDefaultModel(); Model retractions = ModelFactory.createDefaultModel();
// remove obsolete most-specific-type assertions // remove obsolete mostSpecificType assertions
StmtIterator iter = inferenceModel.listStatements(individual, mostSpecificType, (RDFNode) null); StmtIterator iter = inferenceModel.listStatements(individual, mostSpecificType, (RDFNode) null);
while (iter.hasNext()) { while (iter.hasNext()) {
@ -689,7 +690,7 @@ public class SimpleReasoner extends StatementListener {
inferenceModel.remove(retractions); inferenceModel.remove(retractions);
// add new most-specific-type assertions // add new mostSpecificType assertions
Iterator<String> typeIter = typeURIs.iterator(); Iterator<String> typeIter = typeURIs.iterator();
while (typeIter.hasNext()) { while (typeIter.hasNext()) {
@ -707,12 +708,12 @@ public class SimpleReasoner extends StatementListener {
return; return;
} }
private boolean recomputing = false;
/** /**
* Returns true if the reasoner is in the process of recomputing all * Returns true if the reasoner is in the process of recomputing all
* inferences. * inferences.
*/ */
private boolean recomputing = false;
public boolean isRecomputing() { public boolean isRecomputing() {
return recomputing; return recomputing;
} }
@ -731,14 +732,14 @@ public class SimpleReasoner extends StatementListener {
/* /*
* Recompute the entire ABox inference graph. The new * Recompute the entire ABox inference graph. The new
* inference graph is built up in a separate model and * inference graph is built in a separate model and
* then reconciled with the inference graph used by the * then reconciled with the inference graph in active
* application. The model reconciliation must be done * use. The model reconciliation must be done
* without reading the whole inference models into * without reading the whole inference models into
* memory in order to support very large ABox * memory in order to support very large ABox
* inference models. * inference models.
*/ */
public synchronized void recomputeABox() { protected synchronized void recomputeABox() {
HashSet<String> unknownTypes = new HashSet<String>(); HashSet<String> unknownTypes = new HashSet<String>();
@ -799,8 +800,8 @@ public class SimpleReasoner extends StatementListener {
log.info("Finished computing class-based ABox inferences"); log.info("Finished computing class-based ABox inferences");
// reflect the recomputed inferences into the application inference // reflect the recomputed inferences into the application
// model. // inference model.
log.info("Updating ABox inference model"); log.info("Updating ABox inference model");
StmtIterator iter = null; StmtIterator iter = null;
@ -913,23 +914,16 @@ public class SimpleReasoner extends StatementListener {
log.info("ABox inference model updated"); log.info("ABox inference model updated");
} }
public synchronized boolean isABoxReasoningAsynchronous() { /*
if (batchMode1 || batchMode2) { * Get the URIs for all individuals in the system
return true; */
} else { protected ArrayList<String> getAllIndividualURIs() {
return false;
}
}
public ArrayList<String> getAllIndividualURIs() {
String queryString = "select distinct ?subject where {?subject <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type}"; String queryString = "select distinct ?subject where {?subject <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type}";
return getIndividualURIs(queryString); return getIndividualURIs(queryString);
} }
public ArrayList<String> getIndividualURIs(String queryString) { protected ArrayList<String> getIndividualURIs(String queryString) {
ArrayList<String> individuals = new ArrayList<String>(); ArrayList<String> individuals = new ArrayList<String>();
aboxModel.enterCriticalSection(Lock.READ); aboxModel.enterCriticalSection(Lock.READ);
@ -960,6 +954,19 @@ public class SimpleReasoner extends StatementListener {
return individuals; return individuals;
} }
// system-configured reasoning modules (plugins)
public boolean isInterestedInRemovedStatement(Statement stmt) {
if (stmt.getPredicate().equals(RDF.type)) return true;
for (ReasonerPlugin plugin : getPluginList()) {
if (plugin.isInterestedInRemovedStatement(stmt)) return true;
}
return false;
}
protected void doPlugins(ModelUpdate.Operation op, Statement stmt) { protected void doPlugins(ModelUpdate.Operation op, Statement stmt) {
for (ReasonerPlugin plugin : getPluginList()) { for (ReasonerPlugin plugin : getPluginList()) {
@ -983,29 +990,16 @@ public class SimpleReasoner extends StatementListener {
} }
} }
public boolean isInterestedInRemovedStatement(Statement stmt) {
if (stmt.getPredicate().equals(RDF.type)) return true;
for (ReasonerPlugin plugin : getPluginList()) {
if (plugin.isInterestedInRemovedStatement(stmt)) return true;
}
return false;
}
//TODO remove this for 1.5
public synchronized void computeMostSpecificType() {
}
/** /**
* This is called when the system shuts down. * This is called when the application shuts down.
*/ */
public void setStopRequested() { public void setStopRequested() {
this.stopRequested = true; this.stopRequested = true;
} }
/*
* Utility method for logging
*/
public static String stmtString(Statement statement) { public static String stmtString(Statement statement) {
return " [subject = " + statement.getSubject().getURI() + return " [subject = " + statement.getSubject().getURI() +
"] [property = " + statement.getPredicate().getURI() + "] [property = " + statement.getPredicate().getURI() +
@ -1013,6 +1007,20 @@ public class SimpleReasoner extends StatementListener {
: ((Resource)statement.getObject()).getURI() + " (Resource)") + "]"; : ((Resource)statement.getObject()).getURI() + " (Resource)") + "]";
} }
// DeltaComputer
/*
* Asynchronous reasoning mode (DeltaComputer) is used in the case of batch removals.
*/
public synchronized boolean isABoxReasoningAsynchronous() {
if (batchMode1 || batchMode2) {
return true;
} else {
return false;
}
}
private volatile boolean deltaComputerProcessing = false; private volatile boolean deltaComputerProcessing = false;
private int eventCount = 0; private int eventCount = 0;
@ -1083,7 +1091,7 @@ public class SimpleReasoner extends StatementListener {
} }
} }
} else { } else {
log.warn("unexpected condition, invoked when batchMode1 and batchMode2 were both false"); log.warn("unexpected condition, invoked when batchMode1 and batchMode2 are both false");
deltaComputerProcessing = false; deltaComputerProcessing = false;
} }

View file

@ -13,12 +13,11 @@ import com.hp.hpl.jena.rdf.model.Statement;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread; import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread;
/** /**
* Route notification of changes to TBox to the incremental ABox reasoner. * Route notification of changes to TBox to the incremental ABox reasoner.
* The incremental ABox reasoner handles only subclass, superclass * The incremental ABox reasoner handles only subClass and
* and equivalent class axioms. * equivalentClass class axioms. Reasoning dones as a result of TBox
* * changes is always done in a separate thread.
*/ */
public class SimpleReasonerTBoxListener extends StatementListener { public class SimpleReasonerTBoxListener extends StatementListener {

View file

@ -20,7 +20,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.graph.Node;
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.ontology.OntModelSpec;
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.SDBFactory; import com.hp.hpl.jena.sdb.SDBFactory;
@ -48,6 +50,8 @@ public class FileGraphSetup implements ServletContextListener {
OntModelSelector baseOms = null; OntModelSelector baseOms = null;
try { try {
OntDocumentManager.getInstance().setProcessImports(true);
baseOms = ModelContext.getBaseOntModelSelector(sce.getServletContext()); baseOms = ModelContext.getBaseOntModelSelector(sce.getServletContext());
Store kbStore = (Store) sce.getServletContext().getAttribute("kbStore"); Store kbStore = (Store) sce.getServletContext().getAttribute("kbStore");
@ -78,6 +82,8 @@ public class FileGraphSetup implements ServletContextListener {
System.out.println("Throwable in listener " + this.getClass().getName()); System.out.println("Throwable in listener " + this.getClass().getName());
log.error(t); log.error(t);
t.printStackTrace(); t.printStackTrace();
} finally {
OntDocumentManager.getInstance().setProcessImports(false);
} }
if (isUpdateRequired(sce.getServletContext())) { if (isUpdateRequired(sce.getServletContext())) {
@ -114,7 +120,7 @@ public class FileGraphSetup implements ServletContextListener {
try { try {
FileInputStream fis = new FileInputStream( file ); FileInputStream fis = new FileInputStream( file );
try { try {
Model model = ModelFactory.createDefaultModel(); OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
if ( p.endsWith(".n3") || p.endsWith(".N3") || p.endsWith(".ttl") || p.endsWith(".TTL") ) { if ( p.endsWith(".n3") || p.endsWith(".N3") || p.endsWith(".ttl") || p.endsWith(".TTL") ) {
model.read( fis, null, "N3" ); model.read( fis, null, "N3" );
} else if ( p.endsWith(".owl") || p.endsWith(".OWL") || p.endsWith(".rdf") || p.endsWith(".RDF") || p.endsWith(".xml") || p.endsWith(".XML") ) { } else if ( p.endsWith(".owl") || p.endsWith(".OWL") || p.endsWith(".rdf") || p.endsWith(".RDF") || p.endsWith(".xml") || p.endsWith(".XML") ) {

View file

@ -68,6 +68,14 @@ public class JenaDataSourceSetup extends JenaDataSourceSetupBase
ServletContext ctx = sce.getServletContext(); ServletContext ctx = sce.getServletContext();
StartupStatus ss = StartupStatus.getBean(ctx); StartupStatus ss = StartupStatus.getBean(ctx);
// temporary scaffolding in the rdfapi dev branch
// TODO remove me
if (ConfigurationProperties.getBean(ctx).getProperty(
"VitroConnection.DataSource.endpointURI") != null) {
(new JenaDataSourceSetupSparql()).contextInitialized(sce);
return;
}
try { try {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
setUpJenaDataSource(ctx); setUpJenaDataSource(ctx);

View file

@ -2,9 +2,9 @@
package edu.cornell.mannlib.vitro.webapp.servlet.setup; package edu.cornell.mannlib.vitro.webapp.servlet.setup;
import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.File;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Set; import java.util.Set;

View file

@ -2,10 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.servlet.setup; package edu.cornell.mannlib.vitro.webapp.servlet.setup;
import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextEvent;

View file

@ -16,7 +16,6 @@ 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.mindswap.pellet.PelletOptions;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.OWL;
@ -45,6 +44,14 @@ public class SimpleReasonerSetup implements ServletContextListener {
@Override @Override
public void contextInitialized(ServletContextEvent sce) { public void contextInitialized(ServletContextEvent sce) {
// temporary scaffolding in the rdfapi dev branch
// TODO remove me
if (ConfigurationProperties.getBean(sce).getProperty(
"VitroConnection.DataSource.endpointURI") != null) {
return;
}
try { try {
// set up Pellet reasoning for the TBox // set up Pellet reasoning for the TBox
@ -60,12 +67,12 @@ public class SimpleReasonerSetup implements ServletContextListener {
} }
// Set various Pellet options for incremental consistency checking, etc. // Set various Pellet options for incremental consistency checking, etc.
PelletOptions.DL_SAFE_RULES = true; //PelletOptions.DL_SAFE_RULES = true;
PelletOptions.USE_COMPLETION_QUEUE = true; //PelletOptions.USE_COMPLETION_QUEUE = true;
PelletOptions.USE_TRACING = true; //PelletOptions.USE_TRACING = true;
PelletOptions.TRACK_BRANCH_EFFECTS = true; //PelletOptions.TRACK_BRANCH_EFFECTS = true;
PelletOptions.USE_INCREMENTAL_CONSISTENCY = true; //PelletOptions.USE_INCREMENTAL_CONSISTENCY = true;
PelletOptions.USE_INCREMENTAL_DELETION = true; //PelletOptions.USE_INCREMENTAL_DELETION = true;
PelletListener pelletListener = new PelletListener(unionOms.getTBoxModel(),assertionsOms.getTBoxModel(),inferencesOms.getTBoxModel(),ReasonerConfiguration.DEFAULT); PelletListener pelletListener = new PelletListener(unionOms.getTBoxModel(),assertionsOms.getTBoxModel(),inferencesOms.getTBoxModel(),ReasonerConfiguration.DEFAULT);
sce.getServletContext().setAttribute("pelletListener",pelletListener); sce.getServletContext().setAttribute("pelletListener",pelletListener);

View file

@ -20,16 +20,8 @@ import org.apache.commons.logging.LogFactory;
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.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.vocabulary.RDF;
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater; import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater;

View file

@ -1,144 +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 java.io.File;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDao;
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup;
import edu.cornell.mannlib.vitro.webapp.filestorage.updater.FileStorageAliasAdder;
import edu.cornell.mannlib.vitro.webapp.filestorage.updater.FileStorageUpdater;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
* Check that the conditions are met for updating uploaded files. If everything
* is in place, call the two updaters.
*
* The first updater converts from old-style (pre 1.0) to new-style (post 1.0)
* file storage.
*
* The second updater insures that all bytestreams store their own alias URLs
* (post 1.1.1).
*/
public class UpdateUploadedFiles implements ServletContextListener {
private static final Log log = LogFactory.getLog(UpdateUploadedFiles.class);
/**
* Nothing to do on teardown.
*/
@Override
public void contextDestroyed(ServletContextEvent sce) {
return;
}
/**
* Check that the ontology model, the old upload directory, and the file
* storage system are all valid. Then do the update.
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
try {
WebappDaoFactory wadf = (WebappDaoFactory) ctx
.getAttribute("assertionsWebappDaoFactory");
if (wadf == null) {
throw new IllegalStateException("Webapp DAO Factory is null. "
+ "The ServletContext does not contain an attribute "
+ "for '" + "assertionsWebappDaoFactory" + "'. "
+ "Does the log contain a previous exception from "
+ "JenaDataSourceSetup? Is it possible that web.xml "
+ "is not set up to run JenaDataSourceSetup before "
+ "UpdateUploadedFiles?");
}
OntModel jenaOntModel = (OntModel) ctx
.getAttribute(JenaBaseDao.ASSERTIONS_ONT_MODEL_ATTRIBUTE_NAME);
if (jenaOntModel == null) {
throw new IllegalStateException("Ontology model is null. "
+ "The ServletContext does not contain an attribute "
+ "for '"
+ JenaBaseDao.ASSERTIONS_ONT_MODEL_ATTRIBUTE_NAME
+ "'. "
+ "Does the log contain a previous exception from "
+ "JenaDataSourceSetup? Is it possible that web.xml "
+ "is not set up to run JenaDataSourceSetup before "
+ "UpdateUploadedFiles?");
}
FileStorage fileStorage = (FileStorage) ctx
.getAttribute(FileStorageSetup.ATTRIBUTE_NAME);
if (fileStorage == null) {
throw new IllegalStateException("File storage system is null. "
+ "The ServletContext does not contain an attribute "
+ "for '" + FileStorageSetup.ATTRIBUTE_NAME + "'. "
+ "Does the log contain a previous exception from "
+ "FileStorageSetup? Is it possible that web.xml is "
+ "not set up to run FileStorageSetup before "
+ "UpdateUploadedFiles?");
}
String vitroHomeDirectoryName = ConfigurationProperties
.getBean(ctx).getProperty(
FileStorageSetup.PROPERTY_VITRO_HOME_DIR);
if (vitroHomeDirectoryName == null) {
throw new IllegalStateException("Upload directory name is null");
}
File vitroHomeDirectory = new File(vitroHomeDirectoryName);
if (!vitroHomeDirectory.exists()) {
throw new IllegalStateException("Vitro home directory '"
+ vitroHomeDirectory.getAbsolutePath()
+ "' does not exist.");
}
File uploadDirectory = new File(vitroHomeDirectory,
FileStorageSetup.FILE_STORAGE_SUBDIRECTORY);
if (!uploadDirectory.exists()) {
uploadDirectory.mkdir();
if (!uploadDirectory.exists()) {
throw new IllegalStateException(
"Failed to create the file uploads directory: "
+ uploadDirectory.getAbsolutePath());
}
}
String vivoDefaultNamespace = ConfigurationProperties.getBean(ctx)
.getProperty(FileStorageSetup.PROPERTY_DEFAULT_NAMESPACE);
if (vivoDefaultNamespace == null) {
throw new IllegalStateException("Default namespace is null.");
}
String webappImagePath = ctx.getRealPath("images");
File webappImageDirectory = (webappImagePath == null) ? null
: new File(webappImagePath);
/*
* Update from old-style storage to new-style storage.
*/
FileStorageUpdater fsu = new FileStorageUpdater(wadf, jenaOntModel,
fileStorage, uploadDirectory, webappImageDirectory, ctx);
fsu.update();
/*
* Insure that every FileByteStream object has an alias URL.
*/
FileStorageAliasAdder fsaa = new FileStorageAliasAdder(
jenaOntModel, uploadDirectory, vivoDefaultNamespace);
fsaa.update();
} catch (Exception e) {
log.fatal("Unknown problem", e);
StartupStatus.getBean(ctx).fatal(this, "Unknown problem", e);
}
}
}

View file

@ -1,485 +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 java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
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.OntResource;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.RDF;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsLoader;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
* Convert any existing User resources (up to rel 1.2) in the UserAccounts Model
* to UserAccount resources (rel 1.3 and on).
*/
public class UpdateUserAccounts implements ServletContextListener {
private static final Log log = LogFactory.getLog(UpdateUserAccounts.class);
public static final String NS = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#";
public static final String USER = NS + "User";
public static final String USER_USERNAME = NS + "username";
public static final String USER_MD5PASSWORD = NS + "md5password";
public static final String USER_OLDPASSWORD = NS + "oldpassword";
public static final String USER_FIRSTTIME = NS + "firstTime";
public static final String USER_LOGINCOUNT = NS + "loginCount";
public static final String USER_ROLE = NS + "roleURI";
public static final String USER_LASTNAME = NS + "lastName";
public static final String USER_FIRSTNAME = NS + "firstName";
public static final String MAY_EDIT_AS = NS + "mayEditAs";
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
StartupStatus ss = StartupStatus.getBean(ctx);
try {
Updater updater = new Updater(ctx);
if (updater.isThereAnythingToDo()) {
updater.update();
}
} catch (Exception e) {
log.fatal("Failed to update user accounts information", e);
ss.fatal(this, "Failed to update user accounts information", e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// Nothing to destroy.
}
// ----------------------------------------------------------------------
// The Updater class
// ----------------------------------------------------------------------
private static class Updater {
private final ServletContext ctx;
private final MockUserDao userDao;
private final UserAccountsDao userAccountsDao;
public Updater(ServletContext ctx) {
this.ctx = ctx;
WebappDaoFactory wadf = (WebappDaoFactory) ctx
.getAttribute("webappDaoFactory");
userAccountsDao = wadf.getUserAccountsDao();
userDao = new MockUserDao(ctx);
}
/**
* If there is nothing to do, we shouldn't even create a Journal.
*/
public boolean isThereAnythingToDo() {
return !userDao.getAllUsers().isEmpty();
}
/**
* We found some old User resources, so convert them.
*/
public void update() throws IOException {
Journal journal = new Journal(ctx);
log.info("Updating user accounts info. Journal is in '"
+ journal.getPath() + "'");
try {
for (MockUser user : userDao.getAllUsers()) {
try {
UserAccount ua = getConvertedUser(user);
if (ua != null) {
journal.noteAlreadyConverted(user, ua);
} else {
journal.writeUser(user);
ua = convertToUserAccount(user);
userAccountsDao.insertUserAccount(ua);
journal.noteUserAccount(ua);
}
userDao.deleteUser(user);
journal.noteDeletedUser(user);
} catch (Exception e) {
log.error(e, e);
journal.noteException(e);
}
}
} finally {
journal.close();
}
}
private UserAccount getConvertedUser(MockUser user) {
return userAccountsDao.getUserAccountByEmail(user.getUsername());
}
private UserAccount convertToUserAccount(MockUser u) {
UserAccount ua = new UserAccount();
ua.setEmailAddress(nonNull(u.getUsername()));
ua.setFirstName(nonNull(u.getFirstName()));
ua.setLastName(nonNull(u.getLastName()));
ua.setMd5Password(nonNull(u.getMd5password()));
ua.setLoginCount(nonNegative(u.getLoginCount()));
ua.setPasswordChangeRequired(u.getLoginCount() == 0);
ua.setPasswordLinkExpires(0L);
ua.setStatus(Status.ACTIVE);
ua.setExternalAuthId(nonNull(u.getUsername()));
ua.setPermissionSetUris(translateFromRoleUri(u.getRoleURI()));
return ua;
}
private String nonNull(String value) {
return (value == null) ? "" : value;
}
private int nonNegative(int value) {
return Math.max(0, value);
}
private Set<String> translateFromRoleUri(String roleUri) {
String permissionSetUri = PermissionSetsLoader.URI_SELF_EDITOR;
if ("role:/4".equals(roleUri)) {
permissionSetUri = PermissionSetsLoader.URI_EDITOR;
} else if ("role:/5".equals(roleUri)) {
permissionSetUri = PermissionSetsLoader.URI_CURATOR;
} else if ("role:/50".equals(roleUri)) {
permissionSetUri = PermissionSetsLoader.URI_DBA;
}
return Collections.singleton(permissionSetUri);
}
}
// ----------------------------------------------------------------------
// The Journal class
// ----------------------------------------------------------------------
private static class Journal {
private final File file;
private final PrintWriter w;
private int errorCount;
Journal(ServletContext ctx) throws IOException {
String homeDirectoryPath = ConfigurationProperties.getBean(ctx)
.getProperty("vitro.home.directory");
if (homeDirectoryPath == null) {
throw new IllegalStateException(
"No value found for vitro.home.directory");
}
File homeDirectory = new File(homeDirectoryPath);
confirmIsDirectory(homeDirectory);
File upgradeDirectory = createDirectory(homeDirectory, "upgrade");
String filename = timestampedFilename("UpgradeUserAccounts", ".txt");
this.file = new File(upgradeDirectory, filename);
this.w = new PrintWriter(this.file);
w.println("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>");
w.println("PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>");
w.println("PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>");
w.println("PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#>");
w.println("");
}
public String getPath() {
return file.getAbsolutePath();
}
public void note(String... notes) {
w.println();
for (String note : notes) {
w.println("# " + note);
}
}
public void noteAlreadyConverted(MockUser user, UserAccount ua) {
note("UserAccount '" + ua.getUri() + "' already exists for User '"
+ user.getURI() + "', " + user.getFirstName() + " "
+ user.getLastName());
}
public void writeUser(MockUser u) {
w.println();
w.println("# converting User: ");
w.println(u.getURI());
w.println(" a vitro:User ;");
w.println(" vitro:username \"" + u.getUsername() + "\" ;");
w.println(" vitro:firstName \"" + u.getFirstName() + "\" ;");
w.println(" vitro:lastName \"" + u.getLastName() + "\" ;");
w.println(" vitro:md5password \"" + u.getMd5password() + "\" ;");
w.println(" vitro:loginCount " + u.getLoginCount() + " ;");
w.println(" vitro:roleUri \"" + u.getRoleURI() + "\" ;");
w.println(" .");
}
public void noteUserAccount(UserAccount ua) {
note("Created UserAccount '" + ua.getUri() + "' for "
+ ua.getFirstName() + " " + ua.getLastName());
}
public void noteDeletedUser(MockUser user) {
note("Delete User: '" + user.getURI() + "'");
}
public void noteException(Exception e) {
errorCount++;
note("Exception: " + e, " (full stack trace in Vitro log file)");
}
public void close() {
w.println("upgrade complete with " + errorCount + " errors.");
w.close();
}
private void confirmIsDirectory(File home) {
if (!home.exists()) {
throw new IllegalStateException("Vitro home directory '"
+ home.getPath() + "' does not exist.");
}
if (!home.isDirectory()) {
throw new IllegalStateException("Vitro home '" + home.getPath()
+ "' is not a directory.");
}
if (!home.canWrite()) {
throw new IllegalStateException(
"Can't write to Vitro home directory '"
+ home.getPath() + "'.");
}
}
private File createDirectory(File home, String name) {
File upgradeDirectory = new File(home, name);
if (!upgradeDirectory.exists()) {
upgradeDirectory.mkdirs();
if (!upgradeDirectory.exists()) {
throw new IllegalStateException(
"Failed to create the upgrade directory '"
+ upgradeDirectory.getPath() + "'");
}
}
if (!upgradeDirectory.isDirectory()) {
throw new IllegalStateException("Upgrade directory '"
+ upgradeDirectory.getPath() + "' is not a directory.");
}
if (!upgradeDirectory.canWrite()) {
throw new IllegalStateException(
"Can't write to Upgrade directory '"
+ upgradeDirectory.getPath() + "'.");
}
return upgradeDirectory;
}
private String timestampedFilename(String prefix, String suffix) {
SimpleDateFormat sdf = new SimpleDateFormat(
"yyyy-MM-dd'T'HH-mm-sss");
return prefix + "." + sdf.format(new Date()) + suffix;
}
}
// ----------------------------------------------------------------------
// Classes to replace the User and UserDao, just for the upgrade.
// ----------------------------------------------------------------------
private static class MockUser {
private String username;
private String roleURI;
private int loginCount;
private String md5password;
private String lastName;
private String firstName;
private String URI;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getRoleURI() {
return roleURI;
}
public void setRoleURI(String roleURI) {
this.roleURI = roleURI;
}
public int getLoginCount() {
return loginCount;
}
public void setLoginCount(int loginCount) {
this.loginCount = loginCount;
}
public String getMd5password() {
return md5password;
}
public void setMd5password(String md5password) {
this.md5password = md5password;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getURI() {
return URI;
}
public void setURI(String uRI) {
URI = uRI;
}
}
private static class MockUserDao {
private final OntModel model;
public MockUserDao(ServletContext ctx) {
this.model = ModelContext.getBaseOntModelSelector(ctx)
.getUserAccountsModel();
}
public Collection<MockUser> getAllUsers() {
List<MockUser> allUsersList = new ArrayList<MockUser>();
model.enterCriticalSection(Lock.READ);
try {
ClosableIterator<Statement> userStmtIt = model.listStatements(
null, RDF.type, resource(USER));
try {
while (userStmtIt.hasNext()) {
Statement stmt = userStmtIt.next();
OntResource subjRes = stmt.getSubject().as(
OntResource.class);
allUsersList.add(userFromUserInd(subjRes));
}
} finally {
userStmtIt.close();
}
} finally {
model.leaveCriticalSection();
}
return allUsersList;
}
private MockUser userFromUserInd(OntResource userInd) {
MockUser user = new MockUser();
user.setURI(userInd.getURI());
try {
user.setUsername(getStringPropertyValue(userInd, USER_USERNAME));
} catch (Exception e) {
// ignore it.
}
try {
user.setMd5password(getStringPropertyValue(userInd,
USER_MD5PASSWORD));
} catch (Exception e) {
// ignore it.
}
try {
user.setLoginCount(getIntegerPropertyValue(userInd,
USER_LOGINCOUNT));
} catch (Exception e) {
user.setLoginCount(0);
}
try {
user.setRoleURI(getStringPropertyValue(userInd, USER_ROLE));
} catch (Exception e) {
log.error("Unable to set user role\n", e);
e.printStackTrace();
user.setRoleURI("1");
}
try {
user.setLastName(getStringPropertyValue(userInd, USER_LASTNAME));
} catch (Exception e) {
// ignore it.
}
try {
user.setFirstName(getStringPropertyValue(userInd,
USER_FIRSTNAME));
} catch (Exception e) {
// ignore it.
}
return user;
}
private String getStringPropertyValue(OntResource userInd,
String propertyUri) {
Property property = model.getProperty(propertyUri);
Literal object = (Literal) userInd.getProperty(property)
.getObject();
return object.getString();
}
private int getIntegerPropertyValue(OntResource userInd,
String propertyUri) {
Property property = model.getProperty(propertyUri);
Literal object = (Literal) userInd.getProperty(property)
.getObject();
return object.getInt();
}
public void deleteUser(MockUser user) {
model.removeAll(resource(user.getURI()), null, null);
}
private Resource resource(String uri) {
return model.getResource(uri);
}
}
}

View file

@ -1,61 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.utils;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
/**
* Some static methods that help in dealing with image files.
*/
public class ImageUtil {
private static final String DEFAULT_IMAGE_PATH = "/images/placeholders/thumbnail.jpg";
private static final Map<String, String> DEFAULT_IMAGE_PATHS_BY_TYPE = initImagePaths();
private static Map<String, String> initImagePaths() {
Map<String, String> map = new HashMap<String, String>();
// No images other than the default.
return Collections.unmodifiableMap(map);
}
/**
* If we have a placeholder image for this exact type, return it. Otherwise,
* return the default.
*/
public static String getPlaceholderImagePathForType(String typeUri) {
for (Entry<String, String> entry : DEFAULT_IMAGE_PATHS_BY_TYPE
.entrySet()) {
if (typeUri.equals(entry.getKey())) {
return entry.getValue();
}
}
return DEFAULT_IMAGE_PATH;
}
/**
* If there is a placeholder image for any type that this Individual
* instantiates, return that image. Otherwise, return the default.
*/
public static String getPlaceholderImagePathForIndividual(
VitroRequest vreq, String individualUri) {
IndividualDao indDao = vreq.getWebappDaoFactory().getIndividualDao();
for (Entry<String, String> entry : DEFAULT_IMAGE_PATHS_BY_TYPE
.entrySet()) {
if (indDao.isIndividualOfClass(entry.getKey(), individualUri)) {
return entry.getValue();
}
}
return DEFAULT_IMAGE_PATH;
}
/** Never need to instantiate this -- all methods are static. */
private ImageUtil() {
// Nothing to do
}
}

View file

@ -97,7 +97,7 @@ public class ClassGroupPageData extends DataGetterBase implements DataGetter{
setAllClassCountsToZero(group); setAllClassCountsToZero(group);
} }
}else{ }else{
log.error("classgroup " + classGroupUri + " does not exist in the system"); throw new RuntimeException("classgroup " + classGroupUri + " does not exist in the system");
} }
} }

View file

@ -0,0 +1,238 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.web.images;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
* A utility for finding the URL of the correct Placeholder image.
*
* The mapping of image URLs to classes is created at startup, and stored in the
* ServletContext.
*/
public class PlaceholderUtil {
private static final Log log = LogFactory.getLog(PlaceholderUtil.class);
private static final String ATTRIBUTE_NAME = PlaceholderUtil.class
.getName();
private static final String PROPERTIES_FILE_PATH = "/images/placeholders/placeholders.properties";
private static final String DEFAULT_IMAGE_PATH = "/images/placeholders/thumbnail.jpg";
// ----------------------------------------------------------------------
// Static methods
// ----------------------------------------------------------------------
/**
* If we have a placeholder image for this exact type, return it. Otherwise,
* return the default.
*/
public static String getPlaceholderImagePathForType(VitroRequest vreq,
String typeUri) {
PlaceholderUtil pu = getPlaceholderUtil(vreq);
if (pu == null) {
return DEFAULT_IMAGE_PATH;
} else {
return pu.getPlaceholderImagePathForType(typeUri);
}
}
/**
* If there is a placeholder image for any type that this Individual
* instantiates, return that image. Otherwise, return the default.
*/
public static String getPlaceholderImagePathForIndividual(
VitroRequest vreq, String individualUri) {
PlaceholderUtil pu = getPlaceholderUtil(vreq);
if (pu == null) {
return DEFAULT_IMAGE_PATH;
} else {
IndividualDao iDao = vreq.getWebappDaoFactory().getIndividualDao();
return pu.getPlaceholderImagePathForIndividual(iDao, individualUri);
}
}
/** Get the PlaceholderUtil instance from the context, or null if none. */
private static PlaceholderUtil getPlaceholderUtil(VitroRequest vreq) {
if (vreq == null) {
return null;
}
ServletContext ctx = vreq.getSession().getServletContext();
Object attrib = ctx.getAttribute(ATTRIBUTE_NAME);
if (attrib instanceof PlaceholderUtil) {
return (PlaceholderUtil) attrib;
} else {
log.warn("Looked for a PlaceholerUtil, but found " + attrib);
return null;
}
}
// ----------------------------------------------------------------------
// The object
// ----------------------------------------------------------------------
private final Map<String, String> mapUrlsByClass;
private PlaceholderUtil(Map<String, String> map) {
this.mapUrlsByClass = Collections
.unmodifiableMap(new HashMap<String, String>(map));
}
/**
* If we have a placeholder image for this exact type, return it. Otherwise,
* return the default.
*/
private String getPlaceholderImagePathForType(String typeUri) {
if (typeUri == null) {
log.debug("getPlaceholderImagePathForType: typeUri is null");
return DEFAULT_IMAGE_PATH;
}
String url = mapUrlsByClass.get(typeUri);
if (url == null) {
log.debug("getPlaceholderImagePathForType: no value for '"
+ typeUri + "'");
return DEFAULT_IMAGE_PATH;
}
log.debug("getPlaceholderImagePathForType: value for '" + typeUri
+ "' is '" + url + "'");
return url;
}
/**
* If there is a placeholder image for any type that this Individual
* instantiates, return that image. Otherwise, return the default.
*/
private String getPlaceholderImagePathForIndividual(IndividualDao iDao,
String individualUri) {
if (individualUri == null) {
log.debug("getPlaceholderImagePathForIndividual: "
+ "individualUri is null");
return DEFAULT_IMAGE_PATH;
}
for (String classUri : mapUrlsByClass.keySet()) {
String imageUrl = mapUrlsByClass.get(classUri);
if (iDao.isIndividualOfClass(classUri, individualUri)) {
log.debug("getPlaceholderImagePathForIndividual: individual '"
+ individualUri + "' is of class '" + classUri
+ "', value is '" + imageUrl + "'");
return imageUrl;
}
}
log.debug("getPlaceholderImagePathForIndividual: individual '"
+ individualUri + "' is not of any recognized class");
return DEFAULT_IMAGE_PATH;
}
// ----------------------------------------------------------------------
// Classes used for setup
// ----------------------------------------------------------------------
public static class Setup implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext();
StartupStatus ss = StartupStatus.getBean(ctx);
try {
File propertiesFile = confirmRealPath(ctx, PROPERTIES_FILE_PATH);
Map<String, String> map = loadPropertiesToMap(propertiesFile);
confirmImagesArePresent(ctx, map);
ctx.setAttribute(ATTRIBUTE_NAME, new PlaceholderUtil(map));
} catch (SetupException e) {
if (e.getCause() == null) {
ss.warning(this, e.getMessage());
} else {
ss.warning(this, e.getMessage(), e.getCause());
}
}
}
private Map<String, String> loadPropertiesToMap(File propertiesFile)
throws SetupException {
Properties props = new Properties();
try {
props.load(new FileReader(propertiesFile));
} catch (IOException e) {
throw new SetupException(
"Can't load properties from the file at '"
+ PROPERTIES_FILE_PATH
+ "'. Is it in a valid format?", e);
}
Map<String, String> map = new HashMap<String, String>();
for (Enumeration<Object> keys = props.keys(); keys
.hasMoreElements();) {
String key = (String) keys.nextElement();
String value = props.getProperty(key);
map.put(key, value);
}
return map;
}
private void confirmImagesArePresent(ServletContext ctx,
Map<String, String> map) throws SetupException {
Set<String> imageUrls = new HashSet<String>();
imageUrls.add(DEFAULT_IMAGE_PATH);
imageUrls.addAll(map.values());
for (String imageUrl : imageUrls) {
confirmRealPath(ctx, imageUrl);
}
}
private File confirmRealPath(ServletContext ctx, String url)
throws SetupException {
String path = ctx.getRealPath(url);
if (path == null) {
throw new SetupException("Can't translate to real path: '"
+ url + "'");
}
File file = new File(path);
if (!file.exists()) {
throw new SetupException("No file found at '" + url + "'.");
}
if (!file.canRead()) {
throw new SetupException("Can't read the file at '" + url
+ "'.");
}
return file;
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
sce.getServletContext().removeAttribute(ATTRIBUTE_NAME);
}
}
private static class SetupException extends Exception {
public SetupException(String message) {
super(message);
}
public SetupException(String message, Throwable cause) {
super(message, cause);
}
}
}

View file

@ -0,0 +1,57 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.web.methods;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
import freemarker.core.Environment;
import freemarker.template.TemplateModelException;
/**
* Get a URL for the placeholder image for this Individual, based on the VClass
* that the Individual belongs to.
*/
public class IndividualPlaceholderImageUrlMethod extends BaseTemplateMethodModel {
@SuppressWarnings("rawtypes")
@Override
public String exec(List args) throws TemplateModelException {
if (args.size() != 1) {
throw new TemplateModelException("Wrong number of arguments");
}
String uri = (String) args.get(0);
Environment env = Environment.getCurrentEnvironment();
HttpServletRequest request = (HttpServletRequest) env.getCustomAttribute("request");
VitroRequest vreq = new VitroRequest(request);
String imageUrl = PlaceholderUtil.getPlaceholderImagePathForIndividual(vreq, uri);
return UrlBuilder.getUrl(imageUrl);
}
@Override
public Map<String, Object> help(String name) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("return value", "The URL of the placeholder image for this individual, " +
"based on the VClasses that the individual belongs to.");
List<String>params = new ArrayList<String>();
params.add("Uri of individual");
map.put("parameters", params);
List<String> examples = new ArrayList<String>();
examples.add(name + "(individual.uri)");
map.put("examples", examples);
return map;
}
}

View file

@ -76,15 +76,11 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel {
return UrlBuilder.getIndividualProfileUrl(individual, vreq); return UrlBuilder.getIndividualProfileUrl(individual, vreq);
} }
// For image, we use the default list view and Individual methods to reconstruct the image
// url from various triples. A custom list view would require that logic to be duplicated here.
public String getImageUrl() { public String getImageUrl() {
String imageUrl = individual.getImageUrl(); String imageUrl = individual.getImageUrl();
return imageUrl == null ? null : getUrl(imageUrl); return imageUrl == null ? null : getUrl(imageUrl);
} }
// For image, we use the default list view and Individual methods to reconstruct the image
// url from various triples. A custom list view would require that logic to be duplicated here.
public String getThumbUrl() { public String getThumbUrl() {
String thumbUrl = individual.getThumbUrl(); String thumbUrl = individual.getThumbUrl();
return thumbUrl == null ? null : getUrl(thumbUrl); return thumbUrl == null ? null : getUrl(thumbUrl);

View file

@ -207,7 +207,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
ObjectPropertyDao opDao = wdf.getObjectPropertyDao(); ObjectPropertyDao opDao = wdf.getObjectPropertyDao();
ObjectProperty op = opDao.getObjectPropertyByURI(propertyUri); ObjectProperty op = opDao.getObjectPropertyByURI(propertyUri);
if (op == null) { if (op == null) {
log.error("ObjectProperty op returned null from opDao.getObjectPropertyByURI()"); log.error("ObjectProperty op returned null from opDao.getObjectPropertyByURI(" + propertyUri + ")");
} else if (op.getURI() == null) { } else if (op.getURI() == null) {
log.error("ObjectProperty op returned with null propertyURI from opDao.getObjectPropertyByURI()"); log.error("ObjectProperty op returned with null propertyURI from opDao.getObjectPropertyByURI()");
} else { } else {

View file

@ -111,7 +111,8 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
} }
public String getAddUrl() { public String getAddUrl() {
return addUrl; //log.info("addUrl=" + addUrl);
return (addUrl != null) ? addUrl : "";
} }
public Map<String, Object> getVerboseDisplay() { public Map<String, Object> getVerboseDisplay() {

View file

@ -638,18 +638,6 @@ public class IndividualFilteringByStatementTest extends AbstractTestClass {
// Un-implemented methods // Un-implemented methods
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@Override
public boolean isSubjectOriented() {
throw new RuntimeException(
"ObjectPropertyStatement.isSubjectOriented() not implemented.");
}
@Override
public void setSubjectOriented(boolean subjectOriented) {
throw new RuntimeException(
"ObjectPropertyStatement.setSubjectOriented() not implemented.");
}
@Override @Override
public void setSubjectURI(String subjectURI) { public void setSubjectURI(String subjectURI) {
throw new RuntimeException( throw new RuntimeException(

View file

@ -9,12 +9,16 @@ import java.util.Map;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.junit.Test; import org.junit.Test;
import com.hp.hpl.jena.rdf.model.Literal;
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.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.dao.InsertException; import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfigurationConstants;
public class ProcessRdfFormTest extends AbstractTestClass{ public class ProcessRdfFormTest extends AbstractTestClass{
@ -243,6 +247,137 @@ public class ProcessRdfFormTest extends AbstractTestClass{
ResourceFactory.createResource("http://test.com/uri3"))); ResourceFactory.createResource("http://test.com/uri3")));
} }
@Test
//Edit existing statement
public void forcedNewResourceTest() throws Exception{
/* A very basic new statement edit. */
EditConfigurationVTwo config = new EditConfigurationVTwo();
config.setEditKey("mockEditKey");
config.setN3Required(Arrays.asList("?newRes ?test2 ?test3 ." ));
config.setUrisOnform(Arrays.asList( "newRes", "test2", "test3"));
//set uris in scope to include an existing value for new resource
config.addUrisInScope("newRes", Arrays.asList("<http://test.com/uri1>"));
config.addNewResource("newRes", null);
config.setEntityToReturnTo("?newRes");
Map<String,String[]> values = new HashMap<String, String[]>();
//value from form should indicate that newRes should have new uri created
values.put("newRes", (new String[] {EditConfigurationConstants.NEW_URI_SENTINEL}));
values.put("test2", (new String[] {"http://test.com/uri2"}));
values.put("test3", (new String[] {"http://test.com/uri3"}));
values.put("editKey", (new String[] {"mockEditKey"}));
MultiValueEditSubmission submission = new MultiValueEditSubmission(values, config);
ProcessRdfForm processor = new ProcessRdfForm(config,getMockNewURIMaker());
/* test just the N3 substitution part */
List<String>req = config.getN3Required();
List<String>opt = config.getN3Optional();
processor.subInValuesToN3( config , submission, req, opt, null , null);
assertNotNull(req);
assertTrue( req.size() > 0);
assertNotNull(req.get(0));
assertEquals("<"+NEWURI_STRING + "0> <http://test.com/uri2> <http://test.com/uri3> .", req.get(0));
assertEquals("<" + NEWURI_STRING + "0>", submission.getEntityToReturnTo());
/* test the N3 and parse RDF parts */
AdditionsAndRetractions changes = processor.process( config, submission );
assertNotNull( changes );
assertNotNull( changes.getAdditions() );
assertNotNull( changes.getRetractions());
assertTrue( changes.getAdditions().size() == 1 );
//the old uri should be removed
assertTrue( changes.getRetractions().size() == 0 );
assertTrue( changes.getAdditions().contains(
ResourceFactory.createResource(NEWURI_STRING + "0"),
ResourceFactory.createProperty("http://test.com/uri2"),
ResourceFactory.createResource("http://test.com/uri3")));
}
/* An edit of an existing statement set where some statements need to be replaced while
* others must be retained. */
@Test
public void basicEditReplaceStatement() throws Exception{
String testXURI = "http://test.com/uriX";
String testYURI = "http://test.com/uriY";
String testZURIOrginal = "http://test.com/uriZ";
String testZURIChanged = "http://test.com/uriZChanged";
String zType = "http://test.com/TestType";
String rdfsLabel = "http://www.w3.org/2000/01/rdf-schema#label";
/* set up model */
Model model = ModelFactory.createDefaultModel();
//?x ?y ?zOriginal.
model.add(model.createResource(testXURI),
model.createProperty(testYURI),
model.createResource(testZURIOrginal));
//?zOriginal a TestType.
model.add(model.createResource(testZURIOrginal),
RDF.type,
model.createResource(zType));
//?zOriginal label "zLabel";
model.add(model.createResource(testZURIOrginal),
RDFS.label,
model.createLiteral("Z Original Label"));
/* set up EditConfiguration */
EditConfigurationVTwo config = new EditConfigurationVTwo();
config.setEditKey("mockEditKey");
config.setLiteralsOnForm(Arrays.asList("zLabel"));
config.setUrisOnform(Arrays.asList("testX", "testY", "testZ"));
config.setN3Required( Arrays.asList("?testX ?testY ?testZ ." ));
config.setN3Optional( Arrays.asList("?testZ a <" + zType + "> . \n" +
"?testZ <" + rdfsLabel + "> ?zLabel ." ));
//mimicking an existing value for the label
config.addLiteralInScope("zLabel", model.createLiteral("Z Original Label"));
config.setVarNameForSubject("testX");
config.setSubjectUri(testXURI);
config.setPredicateUri(testYURI);
config.setVarNameForPredicate("testY");
config.setObject(testZURIOrginal);
config.setVarNameForObject("testZ");
config.addField(new FieldVTwo().setName("zLabel"));
config.prepareForObjPropUpdate(model);
/* set up Submission */
Map<String,String[]> values = new HashMap<String, String[]>();
values.put("testZ", (new String[] {testZURIChanged}));
values.put("zLabel", (new String[] {"New Z Label"}));
values.put("editKey", (new String[] {"mockEditKey"}));
MultiValueEditSubmission submission = new MultiValueEditSubmission(values, config);
ProcessRdfForm processor = new ProcessRdfForm(config,getMockNewURIMaker());
AdditionsAndRetractions changes = processor.process( config, submission );
assertNotNull( changes );
assertNotNull( changes.getAdditions() );
assertNotNull( changes.getRetractions());
// assertTrue( changes.getAdditions().size() == 3 );
//only one statement should be retracted
// assertTrue( changes.getRetractions().size() == 1 );
assertTrue( changes.getAdditions().contains(
ResourceFactory.createResource(testXURI),
ResourceFactory.createProperty(testYURI),
ResourceFactory.createResource(testZURIChanged)));
assertTrue( changes.getRetractions().contains(
ResourceFactory.createResource(testXURI),
ResourceFactory.createProperty(testYURI),
ResourceFactory.createResource(testZURIOrginal)));
}
String NEWURI_STRING= "http://newURI/n"; String NEWURI_STRING= "http://newURI/n";

View file

@ -55,16 +55,6 @@ public class ObjectPropertyStatementDaoStub implements
.getObjectURI()); .getObjectURI());
} }
@Override
public boolean isSubjectOriented() {
return false;
}
@Override
public void setSubjectOriented(boolean subjectOriented) {
throw new UnsupportedOperationException();
}
@Override @Override
public String getSubjectURI() { public String getSubjectURI() {
return s; return s;

View file

@ -7,7 +7,6 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao; import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao;
import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
@ -144,12 +143,6 @@ return this.objectPropertyStatementDao; }
// Un-implemented methods // Un-implemented methods
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@Override
public Map<String, String> getProperties() {
throw new RuntimeException(
"WebappDaoFactory.getProperties() not implemented.");
}
@Override @Override
public String checkURI(String uriStr) { public String checkURI(String uriStr) {
throw new RuntimeException( throw new RuntimeException(
@ -169,7 +162,7 @@ return this.objectPropertyStatementDao; }
} }
@Override @Override
public String[] getPreferredLanguages() { public List<String> getPreferredLanguages() {
throw new RuntimeException( throw new RuntimeException(
"WebappDaoFactory.getPreferredLanguages() not implemented."); "WebappDaoFactory.getPreferredLanguages() not implemented.");
} }
@ -192,12 +185,6 @@ return this.objectPropertyStatementDao; }
"WebappDaoFactory.getUserURI() not implemented."); "WebappDaoFactory.getUserURI() not implemented.");
} }
@Override
public Classes2ClassesDao getClasses2ClassesDao() {
throw new RuntimeException(
"WebappDaoFactory.getClasses2ClassesDao() not implemented.");
}
@Override @Override
public DatatypeDao getDatatypeDao() { public DatatypeDao getDatatypeDao() {
throw new RuntimeException( throw new RuntimeException(

View file

@ -32,4 +32,4 @@ display:Home
########## Data Getter ############ ########## Data Getter ############
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#homeDataGetter> <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#homeDataGetter>
a <java:edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.BrowseDataGetter> . a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.BrowseDataGetter> .

View file

@ -22,6 +22,7 @@ auth:ADMIN
auth:hasPermission simplePermission:SeeStartupStatus ; auth:hasPermission simplePermission:SeeStartupStatus ;
auth:hasPermission simplePermission:UseAdvancedDataToolsPages ; auth:hasPermission simplePermission:UseAdvancedDataToolsPages ;
auth:hasPermission simplePermission:UseMiscellaneousAdminPages ; auth:hasPermission simplePermission:UseMiscellaneousAdminPages ;
auth:hasPermission simplePermission:UseSparqlQueryPage ;
# permissions for CURATOR and above. # permissions for CURATOR and above.
auth:hasPermission simplePermission:EditOntology ; auth:hasPermission simplePermission:EditOntology ;

View file

@ -24,6 +24,8 @@ edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase
edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup
edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil$Setup
# Update the URIs on Permission Sets on UserAccounts from model (1.4) to 1.5. # Update the URIs on Permission Sets on UserAccounts from model (1.4) to 1.5.
edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdatePermissionSetUris edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdatePermissionSetUris

View file

@ -7,7 +7,7 @@
<%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %> <%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %>
<%@page import="edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission" %> <%@page import="edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission" %>
<% request.setAttribute("requestedActions", SimplePermission.MANAGE_PORTALS.ACTION); %> <% request.setAttribute("requestedActions", SimplePermission.USE_SPARQL_QUERY_PAGE.ACTION); %>
<vitro:confirmAuthorization /> <vitro:confirmAuthorization />
<body> <body>

View file

@ -0,0 +1,38 @@
/* http://keith-wood.name/realPerson.html
Real Person Form Submission for jQuery v1.0.1.
Written by Keith Wood (kwood{at}iinet.com.au) June 2009.
Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
Please attribute the author if you use it. */
/* Real Person jQuery plugin styles v1.0.1. */
.realperson-challenge {
display: inline-block;
background-color: #ddd;
width: 150px;
padding-top: 10px;
padding-left: 12px;
}
.realperson-text {
font-family: "Courier New",monospace;
font-size: 6px;
font-weight: bold;
letter-spacing: -1px;
line-height: 3px;
color: #000;
}
.realperson-regen {
padding-top: 4px;
padding-right: 6px;
font-size: 12px;
text-align: center;
cursor: pointer;
}
.realpersonLabel {
display: block;
}
#defaultReal {
margin-left: 20px;
vertical-align: top;
margin-top: 3px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

View file

@ -0,0 +1,17 @@
#
# Assign placeholder images to classes of individuals.
#
# If showing an individual that has no image, a placeholder image may be shown.
# By default, the placeholder is /images/placeholders/thumbnail.jpg. However,
# this file allows you to associate classes with special placeholder images, and
# if the individual belongs to such a class, the special placeholder is shown
# instead of the default.
#
# EXAMPLE:
# http\://xmlns.com/foaf/0.1/Person = /images/placeholders/person.thumbnail.jpg
# means that any individual of type foaf:Person will be represented by
# person.thumbnail.jpg
#
# NOTE: a colon is a special character in a properties file, and must be escaped
# by a backslash.

View file

@ -44,7 +44,7 @@ function itemElement(template, uri, label, classLabel, imageUrl, removeInfo) {
this.uri = uri; this.uri = uri;
this.label = label; this.label = label;
this.classLabel = classLabel; this.classLabel = classLabel;
this.imageUrl = (imageUrl) ? imageUrl : imageUrl="../images/placeholders/person.thumbnail.jpg"; this.imageUrl = imageUrl;
this.removeInfo = removeInfo; this.removeInfo = removeInfo;
this.toString = function() { this.toString = function() {

View file

@ -6,41 +6,9 @@ function ValidateForm(formName) {
errors = false; errors = false;
var errorList; var errorList;
if (document.forms[formName].RequiredFields) {
errorList = 'Please fill out the following required fields:\n';
// build array of required fields
reqStr = document.forms[formName].RequiredFields.value;
requiredFields = reqStr.split(',');
// build array holding the names of required fields as
// displayed in error box
if (document.forms[formName].RequiredFieldsNames) {
reqNameStr = document.forms[formName].RequiredFieldsNames.value;
} else {
reqNameStr = document.forms[formName].RequiredFields.value;
}
requiredNames = reqNameStr.split(',');
// Loop through form elements, checking for required fields
while ((x < document.forms[formName].elements.length)) {
if (document.forms[formName].elements[x].name == requiredFields[y]) {
if (document.forms[formName].elements[x].value == '') {
errorList += requiredNames[y] + '\n';
errors = true;
}
y++;
}
x++;
}
if (errors) {
alert(errorList);
return false;
}
x = 0;
y = 0;
}
// Check for Email formatting // Check for Email formatting
if (document.forms[formName].EmailFields) { if (document.forms[formName].EmailFields) {
errorList = 'Please format your e-mail address as: \"userid@institution.edu\" or enter another complete email address'; errorList = '\nPlease format your e-mail address as:\n \"userid@institution.edu\" or enter another complete and valid email address';
// build array of required fields // build array of required fields
emailStr = document.forms[formName].EmailFields.value; emailStr = document.forms[formName].EmailFields.value;
emailFields = emailStr.split(','); emailFields = emailStr.split(',');

Some files were not shown because too many files have changed in this diff Show more