diff --git a/webapp/build.xml b/webapp/build.xml index 3ed917b8a..0a009efa7 100644 --- a/webapp/build.xml +++ b/webapp/build.xml @@ -115,6 +115,16 @@ deploy - Deploy the application directly into the Tomcat webapps directory. + + + + + + + + + + diff --git a/webapp/config/licenser/known_exceptions.txt b/webapp/config/licenser/known_exceptions.txt index 659c9d2e5..665d8a46d 100644 --- a/webapp/config/licenser/known_exceptions.txt +++ b/webapp/config/licenser/known_exceptions.txt @@ -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/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. webapp/web/themes/enhanced/css/blueprint/liquid.css diff --git a/webapp/src/edu/cornell/mannlib/vedit/controller/OperationController.java b/webapp/src/edu/cornell/mannlib/vedit/controller/OperationController.java index 29096400f..ba5a740ed 100644 --- a/webapp/src/edu/cornell/mannlib/vedit/controller/OperationController.java +++ b/webapp/src/edu/cornell/mannlib/vedit/controller/OperationController.java @@ -441,14 +441,14 @@ public class OperationController extends BaseEditController { } catch (InvocationTargetException e) { log.error(this.getClass().getName()+" encountered exception performing two-stage update"); Throwable innerE = e.getTargetException(); - log.error(innerE); + log.error(innerE, innerE); if (innerE.getMessage()!=null) { - log.error(innerE.getMessage()); + //log.error(innerE.getMessage()); epo.setAttribute("globalErrorMsg",innerE.getMessage()); } return FAILURE; } catch (IllegalAccessException iae) { - log.error(iae); + log.error(iae, iae); epo.setAttribute("globalErrorMessage", "Illegal access - see error logs."); return FAILURE; } @@ -459,15 +459,15 @@ public class OperationController extends BaseEditController { log.error(this.getClass().getName()+" encountered exception performing edit action"); Throwable innerE = e.getTargetException(); //innerE.printStackTrace(); - log.error(innerE); + log.error(innerE, innerE); if (innerE.getMessage()!=null) { //System.out.println(innerE.getMessage()); - log.error(innerE.getMessage()); + //log.error(innerE.getMessage()); epo.setAttribute("globalErrorMsg",innerE.getMessage()); } return FAILURE; } catch (IllegalAccessException iae) { - log.error(iae); + log.error(iae, iae); epo.setAttribute("globalErrorMessage", "Illegal access - see error logs."); return FAILURE; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java index 78bc20a7c..f3e9b2618 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java @@ -84,6 +84,8 @@ public class SimplePermission extends Permission { "UseMiscellaneousEditorPages"); public static final SimplePermission USE_MISCELLANEOUS_PAGES = new SimplePermission( "UseMiscellaneousPages"); + public static final SimplePermission USE_SPARQL_QUERY_PAGE = new SimplePermission( + "UseSparqlQueryPage"); public static List getAllInstances() { return new ArrayList(allInstances.values()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ObjectPropertyStatement.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ObjectPropertyStatement.java index cbe60b321..f904eecac 100755 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ObjectPropertyStatement.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ObjectPropertyStatement.java @@ -7,10 +7,6 @@ public interface ObjectPropertyStatement { public String toString(); - public boolean isSubjectOriented(); - - public void setSubjectOriented(boolean subjectOriented); - public String getSubjectURI(); public void setSubjectURI(String subjectURI); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ObjectPropertyStatementImpl.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ObjectPropertyStatementImpl.java index 789dc9e91..e5f638a04 100755 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ObjectPropertyStatementImpl.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/ObjectPropertyStatementImpl.java @@ -18,9 +18,7 @@ public class ObjectPropertyStatementImpl implements ObjectPropertyStatement private String propertyURI = null; private ObjectProperty property = null; - private String qualifier = null; - private boolean subjectOriented = true; //is the range the item of interest? - private String description = null; //generated desc based on subjectOriented during sql query. + private boolean subjectOriented = true; //is the range the item of interest? public ObjectPropertyStatementImpl() { } @@ -37,23 +35,7 @@ public class ObjectPropertyStatementImpl implements ObjectPropertyStatement String prop = (getProperty()!=null)?getProperty().getDomainPublic():"by propURI"+getPropertyURI(); String ran = (getObject()!= null)?getObject().getName():"objectURI:"+getObjectURI(); String dom = (getSubject()!= null)?getSubject().getName():"subjectURI:"+getSubjectURI(); - String orent = (isSubjectOriented() )?"subject oriented":"object oriented"; - 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; + return "Object Property Statements: "+dom+" "+prop+" to "+ran+" "; } /* (non-Javadoc) @@ -99,7 +81,12 @@ public class ObjectPropertyStatementImpl implements ObjectPropertyStatement * @see edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement#setSubject(edu.cornell.mannlib.vitro.webapp.beans.Individual) */ public void setSubject(Individual subject) { - this.subject = subject; + this.subject = subject; + if (subject == null || subject.isAnonymous()) { + setSubjectURI(null); + } else { + setSubjectURI(subject.getURI()); + } } @@ -135,7 +122,12 @@ public class ObjectPropertyStatementImpl implements ObjectPropertyStatement * @see edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement#setObject(edu.cornell.mannlib.vitro.webapp.beans.Individual) */ public void setObject(Individual object) { - this.object = object; + this.object = object; + if (object == null || object.isAnonymous()) { + setObjectURI(null); + } else { + setObjectURI(object.getURI()); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClass.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClass.java index 2a6445e29..41d4b8799 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClass.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/beans/VClass.java @@ -133,8 +133,14 @@ public class VClass extends BaseResourceBean implements Comparable * Sorts alphabetically by name */ public int compareTo (VClass o1) { - Collator collator = Collator.getInstance(); - return collator.compare(this.getName(),o1.getName()); + if (this.getName() == null) { + return 1; + } else if (o1.getName() == null) { + return -1; + } else { + Collator collator = Collator.getInstance(); + return collator.compare(this.getName(),o1.getName()); + } } /** diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/MailUsersServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/MailUsersServlet.java index 647ebcab2..95279bb90 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/MailUsersServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/MailUsersServlet.java @@ -128,8 +128,6 @@ public class MailUsersServlet extends VitroHttpServlet { msgBuf.append("" + lineSeparator ); 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(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryServlet.java index dd6db37c2..4fcd2f614 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryServlet.java @@ -101,7 +101,7 @@ public class SparqlQueryServlet extends BaseEditController { throws ServletException, IOException { if (!isAuthorizedToDisplayPage(request, response, - SimplePermission.USE_ADVANCED_DATA_TOOLS_PAGES.ACTIONS)) { + SimplePermission.USE_SPARQL_QUERY_PAGE.ACTIONS)) { return; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java index e1d18a8a7..873872216 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroRequest.java @@ -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.dao.WebappDaoFactory; 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; public class VitroRequest extends HttpServletRequestWrapper { @@ -78,6 +79,10 @@ public class VitroRequest extends HttpServletRequestWrapper { setAttribute("jenaOntModel", ontModel); } + public void setOntModelSelector(OntModelSelector oms) { + setAttribute("ontModelSelector", oms); + } + /** gets assertions + inferences WebappDaoFactory with no filtering **/ public WebappDaoFactory getFullWebappDaoFactory() { Object webappDaoFactoryAttr = _req.getAttribute("fullWebappDaoFactory"); @@ -97,12 +102,26 @@ public class VitroRequest extends HttpServletRequestWrapper { public WebappDaoFactory getAssertionsWebappDaoFactory() { Object webappDaoFactoryAttr = _req.getSession().getAttribute("assertionsWebappDaoFactory"); if (webappDaoFactoryAttr instanceof WebappDaoFactory) { + log.info("Returning assertionsWebappDaoFactory from session"); return (WebappDaoFactory) webappDaoFactoryAttr; } 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 */ public WebappDaoFactory getDeductionsWebappDaoFactory() { Object webappDaoFactoryAttr = _req.getSession().getAttribute("deductionsWebappDaoFactory"); @@ -137,6 +156,16 @@ public class VitroRequest extends HttpServletRequestWrapper { return jenaOntModel; } + public OntModelSelector getOntModelSelector() { + Object o = this.getAttribute("ontModelSelector"); + if (o instanceof OntModelSelector) { + return (OntModelSelector) o; + } else { + return null; + } + } + + public OntModel getAssertionsOntModel() { OntModel jenaOntModel = (OntModel)_req.getSession().getAttribute( JenaBaseDao.ASSERTIONS_ONT_MODEL_ATTRIBUTE_NAME ); if ( jenaOntModel == null ) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsPage.java index 092e9c7e9..5854cbe6c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/UserAccountsPage.java @@ -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 DEFAULT_IMAGE_URL = UrlBuilder - .getUrl("/images/placeholders/person.thumbnail.jpg"); - /** * After the account is created, or the password is reset, the user has this * many days to repond to the email. @@ -109,7 +106,6 @@ public abstract class UserAccountsPage extends AbstractPageHandler { UrlBuilder.getUrl("/accounts/firstTimeExternal")); map.put("accountsAjax", UrlBuilder.getUrl("/accountsAjax")); map.put("proxyAjax", UrlBuilder.getUrl("/proxiesAjax")); - map.put("defaultImageUrl", DEFAULT_IMAGE_URL); return map; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java index 672d2883f..0b2e81045 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java @@ -237,6 +237,7 @@ public class UserAccountsEditPage extends UserAccountsPage { if (!isRootUser()) { body.put("roles", buildListOfSelectableRoles()); + body.put("externalAuthPermitted", Boolean.TRUE); } body.put("profileTypes", buildProfileTypesList()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ManageProxiesListPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ManageProxiesListPage.java index 8783f02a7..6847fb236 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ManageProxiesListPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ManageProxiesListPage.java @@ -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.TemplateResponseValues; 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 @@ -134,8 +134,8 @@ public class ManageProxiesListPage extends AbstractPageHandler { private ProxyItemInfo wrapProxyItem(ProxyItemInfo item) { String imagePath = item.getImageUrl(); if (imagePath.isEmpty()) { - imagePath = ImageUtil - .getPlaceholderImagePathForType(VitroVocabulary.USERACCOUNT); + imagePath = PlaceholderUtil.getPlaceholderImagePathForType(vreq, + VitroVocabulary.USERACCOUNT); } UserAccount ua = userAccountsDao.getUserAccountByUri(item.getUri()); @@ -151,8 +151,8 @@ public class ManageProxiesListPage extends AbstractPageHandler { private ProxyItemInfo wrapProfileItem(ProxyItemInfo item) { String imagePath = item.getImageUrl(); if (imagePath.isEmpty()) { - imagePath = ImageUtil.getPlaceholderImagePathForIndividual(vreq, - item.getUri()); + imagePath = PlaceholderUtil.getPlaceholderImagePathForIndividual( + vreq, item.getUri()); } return new ProfileItemWrapper(item.getUri(), item.getLabel(), diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/BasicProxiesGetter.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/BasicProxiesGetter.java index 23c239e82..674acf9cb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/BasicProxiesGetter.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/BasicProxiesGetter.java @@ -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.jena.ModelContext; 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.SparqlQueryUtils; +import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil; /** * Get the basic auto-complete info for the proxy selection. @@ -64,8 +64,9 @@ public class BasicProxiesGetter extends AbstractAjaxResponder { OntModelSelector oms = ModelContext.getUnionOntModelSelector(ctx); userAccountsModel = oms.getUserAccountsModel(); - placeholderImageUrl = UrlBuilder.getUrl(ImageUtil - .getPlaceholderImagePathForType(VitroVocabulary.USERACCOUNT)); + placeholderImageUrl = UrlBuilder.getUrl(PlaceholderUtil + .getPlaceholderImagePathForType(vreq, + VitroVocabulary.USERACCOUNT)); } @Override diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/MoreProfileInfo.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/MoreProfileInfo.java index 77eaee0ad..9b62a1c7a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/MoreProfileInfo.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/MoreProfileInfo.java @@ -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.freemarker.UrlBuilder; 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. @@ -79,7 +79,7 @@ public class MoreProfileInfo extends AbstractAjaxResponder { private String getFullImageUrl(Individual ind) { String path = ind.getThumbUrl(); if ((path == null) || path.isEmpty()) { - path = ImageUtil.getPlaceholderImagePathForIndividual(vreq, + path = PlaceholderUtil.getPlaceholderImagePathForIndividual(vreq, ind.getURI()); } return UrlBuilder.getUrl(path); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsMyAccountPage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsMyAccountPage.java index 19feb2bc4..791b3d277 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsMyAccountPage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsMyAccountPage.java @@ -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.responsevalues.ResponseValues; 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. @@ -268,7 +270,9 @@ public class UserAccountsMyAccountPage extends UserAccountsPage { String userUri = proxyUser.getUri(); String label = assembleUserAccountLabel(proxyUser); String classLabel = ""; - String imageUrl = ""; + String imageUrl = UrlBuilder.getUrl(PlaceholderUtil + .getPlaceholderImagePathForType(vreq, + VitroVocabulary.USERACCOUNT)); // Does this user have a profile? Can we get better info? Individual proxyProfilePage = getProfilePage(proxyUser); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesOperationController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesOperationController.java index 7829d9765..292524c72 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesOperationController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesOperationController.java @@ -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.beans.Classes2Classes; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; public class Classes2ClassesOperationController extends BaseEditController { @@ -58,7 +57,6 @@ public class Classes2ClassesOperationController extends BaseEditController { return; } - Classes2ClassesDao dao = request.getFullWebappDaoFactory().getClasses2ClassesDao(); VClassDao vcDao = request.getFullWebappDaoFactory().getVClassDao(); String modeStr = request.getParameter("opMode"); @@ -81,7 +79,7 @@ public class Classes2ClassesOperationController extends BaseEditController { Classes2Classes c2c = new Classes2Classes(); c2c.setSubclassURI(subclassURIstrs[i]); c2c.setSuperclassURI(superclassURIstr); - dao.deleteClasses2Classes(c2c); + vcDao.deleteClasses2Classes(c2c); } } } @@ -98,7 +96,7 @@ public class Classes2ClassesOperationController extends BaseEditController { Classes2Classes c2c = new Classes2Classes(); c2c.setSuperclassURI(superclassURIstrs[i]); c2c.setSubclassURI(subclassURIstr); - dao.deleteClasses2Classes(c2c); + vcDao.deleteClasses2Classes(c2c); } } } @@ -112,7 +110,7 @@ public class Classes2ClassesOperationController extends BaseEditController { Classes2Classes c2c = new Classes2Classes(); c2c.setSuperclassURI(request.getParameter("SuperclassURI")); c2c.setSubclassURI(request.getParameter("SubclassURI")); - dao.insertNewClasses2Classes(c2c); + vcDao.insertNewClasses2Classes(c2c); } } } catch (Exception e) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesRetryController.java index 011d8d757..298cda38f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Classes2ClassesRetryController.java @@ -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.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; public class Classes2ClassesRetryController extends BaseEditController { @@ -44,9 +43,8 @@ public class Classes2ClassesRetryController extends BaseEditController { action = epo.getAction(); } - Classes2ClassesDao c2cDao = request.getFullWebappDaoFactory().getClasses2ClassesDao(); VClassDao vcDao = request.getFullWebappDaoFactory().getVClassDao(); - epo.setDataAccessObject(c2cDao); + epo.setDataAccessObject(vcDao); Classes2Classes objectForEditing = new Classes2Classes(); String superclassURIstr = request.getParameter("SuperclassURI"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityEditController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityEditController.java index 3e2e6bce1..029774720 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityEditController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityEditController.java @@ -46,8 +46,9 @@ public class EntityEditController extends BaseEditController { String entURI = request.getParameter("uri"); 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); if (ent == null) { try { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityRetryController.java index 4cc312433..5decb70d3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/EntityRetryController.java @@ -78,7 +78,11 @@ public class EntityRetryController extends BaseEditController { 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); WebappDaoFactory myWebappDaoFactory = wadf.getUserAwareDaoFactory(loginBean.getUserURI()); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassRetryController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassRetryController.java index 57da63de7..7cb320d77 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassRetryController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/VclassRetryController.java @@ -197,7 +197,7 @@ public class VclassRetryController extends BaseEditController { Classes2Classes c2c = new Classes2Classes(); c2c.setSubclassURI(((VClass)newObj).getURI()); c2c.setSuperclassURI(superclassURI); - daoFactory.getClasses2ClassesDao().insertNewClasses2Classes(c2c); + daoFactory.getVClassDao().insertNewClasses2Classes(c2c); } public void doUpdated(Object oldObj, Object newObj, EditProcessObject epo) { // nothing to do diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BaseSiteAdminController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BaseSiteAdminController.java index 454f3da96..5ed66765a 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BaseSiteAdminController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/BaseSiteAdminController.java @@ -198,9 +198,11 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet { urls.put("ingest", UrlBuilder.getUrl("/ingest")); urls.put("rdfData", UrlBuilder.getUrl("/uploadRDFForm")); urls.put("rdfExport", UrlBuilder.getUrl("/export")); - urls.put("sparqlQuery", UrlBuilder.getUrl("/admin/sparqlquery")); 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; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ContactMailController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ContactMailController.java index 0224f6ae3..13774949c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ContactMailController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ContactMailController.java @@ -2,6 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker; +import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; @@ -25,6 +26,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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.freemarker.TemplateProcessingHelper.TemplateProcessingException; 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 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_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_BACKUP = "contactForm-backup.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 protected String getTitle(String siteName, VitroRequest vreq) { @@ -70,9 +76,13 @@ public class ContactMailController extends FreemarkerHttpServlet { String webuseremail = nonNullAndTrim(vreq, WEB_USEREMAIL_PARAM); String comments = nonNullAndTrim(vreq, COMMENTS_PARAM); String formType = nonNullAndTrim(vreq, "DeliveryType"); + String captchaInput = nonNullAndTrim(vreq, "defaultReal"); + String captchaDisplay = nonNullAndTrim(vreq, "defaultRealHash"); - if (validateInput(webusername, webuseremail, comments) != null) { - return errorParametersNotValid(); + String errorMsg = validateInput(webusername, webuseremail, comments, captchaInput, captchaDisplay); + + if ( errorMsg != null) { + return errorParametersNotValid(errorMsg, webusername, webuseremail, comments); } String spamReason = checkForSpam(comments, formType); @@ -107,14 +117,14 @@ public class ContactMailController extends FreemarkerHttpServlet { deliveryfrom, originalReferer, vreq.getRemoteAddr(), config, vreq); try { - // Write the email to a backup file - FileWriter fw = new FileWriter(getServletContext().getRealPath(EMAIL_BACKUP_FILE_PATH),true); + // Write the message to the journal file + FileWriter fw = new FileWriter(locateTheJournalFile(vreq),true); PrintWriter outFile = new PrintWriter(fw); writeBackupCopy(outFile, msgText, config, vreq); - Session s = FreemarkerEmailFactory.getEmailSession(vreq); - try { + // Send the message + Session s = FreemarkerEmailFactory.getEmailSession(vreq); sendMessage(s, webuseremail, webusername, recipients, deliveryfrom, msgText); } catch (AddressException e) { 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) { String originalReferer = (String) vreq.getSession().getAttribute("contactFormReferer"); if (originalReferer != null) { @@ -263,20 +307,28 @@ public class ContactMailController extends FreemarkerHttpServlet { } private String validateInput(String webusername, String webuseremail, - String comments) { + String comments, String captchaInput, String captchaDisplay) { 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() ){ - return "A proper webuser email field was not found in the form submitted."; + return "Please enter a valid email address."; } 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; } @@ -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() { Map body = new HashMap(); body.put("errorMessage", @@ -324,11 +385,14 @@ public class ContactMailController extends FreemarkerHttpServlet { return new TemplateResponseValues(TEMPLATE_ERROR, body); } - private ResponseValues errorParametersNotValid() { - // rjy7 We should reload the form, not go to the error page! + private ResponseValues errorParametersNotValid(String errorMsg, String webusername, String webuseremail, String comments) { Map body = new HashMap(); - body.put("errorMessage", "Invalid submission"); - return new TemplateResponseValues(TEMPLATE_ERROR, body); + body.put("errorMessage", errorMsg); + 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() { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerConfiguration.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerConfiguration.java index 5940db33e..7093b5962 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerConfiguration.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerConfiguration.java @@ -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.controller.VitroRequest; 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.FileTemplateLoader; import freemarker.cache.MultiTemplateLoader; @@ -108,6 +112,9 @@ public class FreemarkerConfiguration extends Configuration { sharedVariables.putAll(getMethods()); sharedVariables.put("siteTagline", appBean.getShortHand()); + //Put in edit configuration constants - useful for freemarker templates/editing + sharedVariables.put("editConfigurationConstants", EditConfigurationConstants.exportConstants()); + for ( Map.Entry variable : sharedVariables.entrySet() ) { try { setSharedVariable(variable.getKey(), variable.getValue()); @@ -156,8 +163,9 @@ public class FreemarkerConfiguration extends Configuration { public static Map getMethods() { Map map = new HashMap(); - map.put("profileUrl", new edu.cornell.mannlib.vitro.webapp.web.methods.IndividualProfileUrlMethod()); - map.put("localName", new edu.cornell.mannlib.vitro.webapp.web.methods.IndividualLocalNameMethod()); + map.put("profileUrl", new IndividualProfileUrlMethod()); + map.put("localName", new IndividualLocalNameMethod()); + map.put("placeholderImageUrl", new IndividualPlaceholderImageUrlMethod()); return map; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java index 876f1bb04..470d19bdb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java @@ -338,42 +338,38 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { return appBean.getThemeDir().replaceAll("/$", ""); } - /** - * Define the request-specific URLs that are accessible to the templates. - * @param VitroRequest vreq - */ - private void setRequestUrls(VitroRequest vreq) { - + /** + * Define the request-specific URLs that are accessible to the templates. + * Merge it with the context-specific URLs from the configuration, because + * this map will mask that one. + */ + private Map buildRequestUrls(VitroRequest vreq) { + Map requestUrls = new HashMap(); + FreemarkerConfiguration config = (FreemarkerConfiguration)vreq.getAttribute("freemarkerConfig"); TemplateModel urlModel = config.getSharedVariable("urls"); try { @SuppressWarnings("unchecked") - Map urls = (Map) DeepUnwrap.permissiveUnwrap(urlModel); + Map configUrls = (Map) DeepUnwrap.permissiveUnwrap(urlModel); + requestUrls.putAll(configUrls); // This is request-specific because email can be configured // and de-configured in the application interface. if (FreemarkerEmailFactory.isConfigured(vreq)) { - urls.put("contact", UrlBuilder.getUrl(Route.CONTACT)); - } else { - urls.remove("contact"); // clear value from a previous request + requestUrls.put("contact", UrlBuilder.getUrl(Route.CONTACT)); } - urls.put("currentPage", getCurrentPageUrl(vreq)); - urls.put("referringPage", getReferringPageUrl(vreq)); + requestUrls.put("currentPage", getCurrentPageUrl(vreq)); + requestUrls.put("referringPage", getReferringPageUrl(vreq)); if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.EDIT_OWN_ACCOUNT.ACTIONS)) { - urls.put("myAccount", UrlBuilder.getUrl("/accounts/myAccount")); - } else { - urls.remove("myAccount"); // clear value from a previous request + requestUrls.put("myAccount", UrlBuilder.getUrl("/accounts/myAccount")); } - - config.setSharedVariable("urls", urls); - } catch (TemplateModelException e) { log.error(e, e); } - + return requestUrls; } 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. map.put("title", getTitle(vreq.getAppBean().getApplicationName(), vreq)); - setRequestUrls(vreq); + map.put("urls", buildRequestUrls(vreq)); map.put("menu", getDisplayModelMenu(vreq)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java index 3438e0a9e..bbcce862f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java @@ -36,6 +36,7 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup; import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest; +import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil; /** * 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. */ 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. */ public static final String ACTION_UPLOAD = "upload"; @@ -141,7 +136,8 @@ public class ImageUploadController extends FreemarkerHttpServlet { String imageUri = entity.getMainImageUri(); 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(), VitroVocabulary.IND_MAIN_IMAGE, imageUri); } else if (imageUri != null) { @@ -157,7 +153,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { return Actions.UNAUTHORIZED; } } - + /** *

* Parse the multi-part request, process the request, and produce the @@ -405,12 +401,13 @@ public class ImageUploadController extends FreemarkerHttpServlet { private TemplateResponseValues showAddImagePage(VitroRequest vreq, Individual entity) { - String placeholderUrl = vreq.getParameter(PARAMETER_PLACEHOLDER_URL); - String formAction = (entity == null) ? "" : formAction(entity.getURI(), - ACTION_UPLOAD, placeholderUrl); + ACTION_UPLOAD); String cancelUrl = (entity == null) ? "" : exitPageUrl(vreq, entity.getURI()); + String placeholderUrl = (entity == null) ? "" : UrlBuilder + .getUrl(PlaceholderUtil.getPlaceholderImagePathForIndividual( + vreq, entity.getURI())); TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_NEW); @@ -437,12 +434,11 @@ public class ImageUploadController extends FreemarkerHttpServlet { */ private TemplateResponseValues showReplaceImagePage(VitroRequest vreq, Individual entity, ImageInfo imageInfo) { - String placeholderUrl = vreq.getParameter(PARAMETER_PLACEHOLDER_URL); TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_REPLACE); rv.put(BODY_THUMBNAIL_URL, UrlBuilder.getUrl(imageInfo.getThumbnail() .getBytestreamAliasUrl())); - rv.put(BODY_DELETE_URL, formAction(entity.getURI(), ACTION_DELETE_EDIT, placeholderUrl)); - rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_UPLOAD, placeholderUrl)); + rv.put(BODY_DELETE_URL, formAction(entity.getURI(), ACTION_DELETE_EDIT)); + rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_UPLOAD)); rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI())); rv.put(BODY_TITLE, "Replace image" + forName(entity)); rv.put(BODY_MAX_FILE_SIZE, MAXIMUM_FILE_SIZE / (1024 * 1024)); @@ -468,12 +464,11 @@ public class ImageUploadController extends FreemarkerHttpServlet { */ private TemplateResponseValues showCropImagePage(VitroRequest vreq, Individual entity, String imageUrl, Dimensions dimensions) { - String placeholderUrl = vreq.getParameter(PARAMETER_PLACEHOLDER_URL); TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_CROP); rv.put(BODY_MAIN_IMAGE_URL, UrlBuilder.getUrl(imageUrl)); rv.put(BODY_MAIN_IMAGE_HEIGHT, dimensions.height); 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_TITLE, "Crop Photo" + forName(entity)); return rv; @@ -518,11 +513,9 @@ public class ImageUploadController extends FreemarkerHttpServlet { * back to this controller, along with the desired action and the Entity * URI. */ - private String formAction(String entityUri, String action, - String placeholderUrl) { - ParamMap params = new ParamMap( - PARAMETER_ENTITY_URI, entityUri, PARAMETER_ACTION, action, - PARAMETER_PLACEHOLDER_URL, placeholderUrl); + private String formAction(String entityUri, String action) { + ParamMap params = new ParamMap(PARAMETER_ENTITY_URI, entityUri, + PARAMETER_ACTION, action); return UrlBuilder.getPath(URL_HERE, params); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/Classes2ClassesDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/Classes2ClassesDao.java deleted file mode 100644 index 61f4e607e..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/Classes2ClassesDao.java +++ /dev/null @@ -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); - -} \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassDao.java index e3f696491..6d6e269ab 100755 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/VClassDao.java @@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.dao; 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.VClassGroup; @@ -65,7 +66,11 @@ public interface VClassDao { List getVClassesForProperty(String vclassURI, String propertyURI); - void addVClassesToGroup(VClassGroup group); + void addVClassesToGroup(VClassGroup group); + + void insertNewClasses2Classes(Classes2Classes c2c); + + void deleteClasses2Classes(Classes2Classes c2c); @SuppressWarnings("unchecked") void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedClasses);/* (non-Javadoc) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactory.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactory.java index eeeb844ad..05eccbccf 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactory.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactory.java @@ -3,7 +3,6 @@ package edu.cornell.mannlib.vitro.webapp.dao; import java.util.List; -import java.util.Map; import java.util.Set; public interface WebappDaoFactory { @@ -12,12 +11,6 @@ public interface WebappDaoFactory { * Free any resources associated with this WebappDaoFactory */ public void close(); - - /** - * Retrieves a map containing arbitrary key-value pairs describing this - * WebappDaoFactory - */ - public Map getProperties(); /** * Checks a URI String for two things: well-formedness and uniqueness in the @@ -39,7 +32,7 @@ public interface WebappDaoFactory { public Set getNonuserNamespaces(); - public String[] getPreferredLanguages(); + public List getPreferredLanguages(); /** * 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 =============== */ - /** - * returns a Data Access Object for working with class subsumption axioms - */ - public Classes2ClassesDao getClasses2ClassesDao(); - /** * returns a Data Access Object for working with DataProperties */ diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryConfig.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryConfig.java index faf017275..72d14454b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryConfig.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryConfig.java @@ -2,30 +2,29 @@ package edu.cornell.mannlib.vitro.webapp.dao; +import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Set; public class WebappDaoFactoryConfig { - private String[] preferredLanguages; + private List preferredLanguages; private String defaultNamespace; private Set nonUserNamespaces; public WebappDaoFactoryConfig() { - preferredLanguages = new String[3]; - preferredLanguages[0] = "en-US"; - preferredLanguages[1] = "en"; - preferredLanguages[2] = "EN"; + preferredLanguages = Arrays.asList("en-US", "en", "EN"); defaultNamespace = "http://vitro.mannlib.cornell.edu/ns/default#"; nonUserNamespaces = new HashSet(); nonUserNamespaces.add(VitroVocabulary.vitroURI); } - public String[] getPreferredLanguages() { + public List getPreferredLanguages() { return this.preferredLanguages; } - public void setPreferredLanguages(String[] pl) { + public void setPreferredLanguages(List pl) { this.preferredLanguages = pl; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementFiltering.java index c16386649..0bd8fa060 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/ObjectPropertyStatementFiltering.java @@ -56,10 +56,6 @@ public class ObjectPropertyStatementFiltering implements ObjectPropertyStatement return innerStmt.getSubjectURI(); } - public boolean isSubjectOriented() { - return innerStmt.isSubjectOriented(); - } - public void setObject(Individual object) { innerStmt.setObject(object); } @@ -80,10 +76,6 @@ public class ObjectPropertyStatementFiltering implements ObjectPropertyStatement innerStmt.setSubject(subject); } - public void setSubjectOriented(boolean subjectOriented) { - innerStmt.setSubjectOriented(subjectOriented); - } - public void setSubjectURI(String subjectURI) { innerStmt.setSubjectURI(subjectURI); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/VClassDaoFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/VClassDaoFiltering.java index e11ccddf8..fd1a87c65 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/VClassDaoFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/VClassDaoFiltering.java @@ -11,6 +11,7 @@ import java.util.List; import net.sf.jga.algorithms.Filter; import net.sf.jga.fn.UnaryFunctor; 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.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; @@ -240,6 +241,14 @@ public class VClassDaoFiltering extends BaseFiltering implements VClassDao{ 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) { return innerVClassDao.isSubClassOf(vc1, vc2); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java index 405421ddd..7ebe23b0d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/filtering/WebappDaoFactoryFiltering.java @@ -7,7 +7,6 @@ import java.util.Map; import java.util.Set; 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.DataPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; @@ -76,10 +75,6 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory { /* ******************* filtering *********************** */ - public Map getProperties() { - return innerWebappDaoFactory.getProperties(); - } - public String checkURI(String uriStr) { return innerWebappDaoFactory.checkURI(uriStr); } @@ -101,7 +96,7 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory { return innerWebappDaoFactory.getNonuserNamespaces(); } - public String[] getPreferredLanguages() { + public List getPreferredLanguages() { return innerWebappDaoFactory.getPreferredLanguages(); } @@ -168,10 +163,6 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory { /* ******************* non-filtering DAOs *************************** */ - public Classes2ClassesDao getClasses2ClassesDao() { - return innerWebappDaoFactory.getClasses2ClassesDao(); - } - public DatatypeDao getDatatypeDao() { return innerWebappDaoFactory.getDatatypeDao(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/Classes2ClassesDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/Classes2ClassesDaoJena.java deleted file mode 100644 index fd503f05f..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/Classes2ClassesDaoJena.java +++ /dev/null @@ -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(); - } - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/EmptyReifier.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/EmptyReifier.java index 95535cce8..a2e3b74ac 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/EmptyReifier.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/EmptyReifier.java @@ -43,17 +43,17 @@ public class EmptyReifier implements Reifier { @Override public ExtendedIterator find(TripleMatch arg0) { - return WrappedIterator.create(Collections.EMPTY_LIST.iterator()); + return g.find(arg0); } @Override public ExtendedIterator findEither(TripleMatch arg0, boolean arg1) { - return WrappedIterator.create(Collections.EMPTY_LIST.iterator()); + return find(arg0); } @Override public ExtendedIterator findExposed(TripleMatch arg0) { - return WrappedIterator.create(Collections.EMPTY_LIST.iterator()); + return find(arg0); } @Override @@ -68,14 +68,14 @@ public class EmptyReifier implements Reifier { @Override public boolean handledAdd(Triple arg0) { - // TODO Auto-generated method stub - return false; + g.add(arg0); + return true; } @Override public boolean handledRemove(Triple arg0) { - // TODO Auto-generated method stub - return false; + g.delete(arg0); + return true; } @Override @@ -98,20 +98,17 @@ public class EmptyReifier implements Reifier { @Override public void remove(Triple arg0) { - // TODO Auto-generated method stub - + g.delete(arg0); } @Override public void remove(Node arg0, Triple arg1) { - // TODO Auto-generated method stub - + g.delete(arg1); } @Override public int size() { - // TODO Auto-generated method stub - return 0; + return g.size(); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoSDB.java index 412aaca30..e65923c0f 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualDaoSDB.java @@ -187,9 +187,10 @@ public class IndividualDaoSDB extends IndividualDaoJena { continue; } if (uri != null && !uri.equals(currRes.getURI())) { - Individual ent = makeIndividual(uri, label); - if (ent != null) { - ents.add(ent); + try { + ents.add(makeIndividual(uri, label)); + } catch (IndividualNotFoundException e) { + // don't add } uri = currRes.getURI(); label = null; @@ -201,9 +202,10 @@ public class IndividualDaoSDB extends IndividualDaoJena { label = labelLit.getLexicalForm(); } if (!rs.hasNext()) { - Individual ent = makeIndividual(uri, label); - if (ent != null) { - ents.add(ent); + try { + ents.add(makeIndividual(uri, label)); + } catch (IndividualNotFoundException e) { + // don't add } } } @@ -237,8 +239,12 @@ public class IndividualDaoSDB extends IndividualDaoJena { if (currRes.isAnon()) { continue; } - filteredIndividualList.add( - makeIndividual(currRes.getURI(), null)); + try { + filteredIndividualList.add( + makeIndividual(currRes.getURI(), null)); + } catch (IndividualNotFoundException e) { + // don't add + } } } finally { dataset.getLock().leaveCriticalSection(); @@ -247,7 +253,7 @@ public class IndividualDaoSDB extends IndividualDaoJena { return filteredIndividualList; } - private Individual makeIndividual(String uri, String label) { + private Individual makeIndividual(String uri, String label) throws IndividualNotFoundException { Individual ent = new IndividualSDB(uri, this.dwf, datasetMode, getWebappDaoFactory(), SKIP_INITIALIZATION); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java index 1dbbaa1a2..6700ca1a3 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/IndividualSDB.java @@ -109,7 +109,7 @@ public class IndividualSDB extends IndividualImpl implements Individual { DatasetWrapperFactory datasetWrapperFactory, SDBDatasetMode datasetMode, WebappDaoFactoryJena wadf, - boolean skipInitialization) { + boolean skipInitialization) throws IndividualNotFoundException { this.individualURI = individualURI; this.datasetMode = datasetMode; this.dwf = datasetWrapperFactory; @@ -176,7 +176,7 @@ public class IndividualSDB extends IndividualImpl implements Individual { public IndividualSDB(String individualURI, DatasetWrapperFactory datasetWrapperFactory, SDBDatasetMode datasetMode, - WebappDaoFactoryJena wadf) { + WebappDaoFactoryJena wadf) throws IndividualNotFoundException { this(individualURI, datasetWrapperFactory, datasetMode, @@ -184,7 +184,7 @@ public class IndividualSDB extends IndividualImpl implements Individual { !SKIP_INITIALIZATION); } - public class IndividualNotFoundException extends RuntimeException {} + public class IndividualNotFoundException extends Exception {} private void setUpURIParts(OntResource ind) { 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)) { continue; } - Individual subj = new IndividualSDB(((OntResource) s.getSubject().as(OntResource.class)).getURI(), this.dwf, datasetMode, webappDaoFactory); - Individual obj = new IndividualSDB(((OntResource) s.getObject().as(OntResource.class)).getURI(), this.dwf, datasetMode, webappDaoFactory); + Individual subj = null; + 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()); // 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 @@ -517,15 +533,19 @@ public class IndividualSDB extends IndividualImpl implements Individual { while (values.hasNext()) { result = values.next(); RDFNode value = result.get("object"); - if (value.canAs(OntResource.class)) { - relatedIndividuals.add( - new IndividualSDB( - ((OntResource) value.as(OntResource.class)) - .getURI(), - this.dwf, - datasetMode, - webappDaoFactory) ); - } + try { + if (value.canAs(OntResource.class)) { + relatedIndividuals.add( + new IndividualSDB( + ((OntResource) value.as(OntResource.class)) + .getURI(), + this.dwf, + datasetMode, + webappDaoFactory) ); + } + } catch (IndividualNotFoundException e) { + // don't add to the list + } } } finally { dataset.getLock().leaveCriticalSection(); @@ -555,9 +575,13 @@ public class IndividualSDB extends IndividualImpl implements Individual { QuerySolution result = results.next(); RDFNode value = result.get("object"); if (value != null && value.canAs(OntResource.class)) { - return new IndividualSDB( - ((OntResource) value.as(OntResource.class)).getURI(), - dwf, datasetMode, webappDaoFactory); + try { + return new IndividualSDB( + ((OntResource) value.as(OntResource.class)).getURI(), + dwf, datasetMode, webappDaoFactory); + } catch (IndividualNotFoundException e) { + return null; + } } } return null; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java index d0cffb4ee..15ace02c8 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/JenaBaseDao.java @@ -80,7 +80,7 @@ public class JenaBaseDao extends JenaBaseDaoCon { protected String DEFAULT_NAMESPACE; protected Set NONUSER_NAMESPACES; - protected String[] PREFERRED_LANGUAGES; + protected List PREFERRED_LANGUAGES; /* ******************* constructor ************************* */ @@ -501,7 +501,7 @@ public class JenaBaseDao extends JenaBaseDaoCon { } } } 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) { - log.error("Error in updatePropertyDateTimeValue"); - log.error(e, e); + log.error("Error in updatePropertyDateTimeValue", e); } } @@ -767,7 +766,7 @@ public class JenaBaseDao extends JenaBaseDaoCon { if (label.isLiteral()) { Literal labelLit = ((Literal)label); String labelLanguage = labelLit.getLanguage(); - if ( (labelLanguage==null) && (lang==null) ) { + if ( (labelLanguage == null) && (lang == null || lang.isEmpty()) ) { return labelLit; } if ( (lang != null) && (lang.equals(labelLanguage)) ) { @@ -856,6 +855,10 @@ public class JenaBaseDao extends JenaBaseDaoCon { private Literal tryPropertyForPreferredLanguages( OntResource r, Property p, boolean alsoTryNoLang ) { Literal label = null; List labels = r.listPropertyValues(p).toList(); + + if (labels.size() == 0) { + return null; + } // Sort by lexical value to guarantee consistent results Collections.sort(labels, new Comparator() { @@ -871,8 +874,7 @@ public class JenaBaseDao extends JenaBaseDaoCon { } }); - for (int i=0; i getMostSpecificTypesInClassgroupsForIndividual(String subjectUri) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntologyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntologyDaoJena.java index e7e3e3339..067a29cf2 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntologyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/OntologyDaoJena.java @@ -132,7 +132,7 @@ public class OntologyDaoJena extends JenaBaseDao implements OntologyDao { try { com.hp.hpl.jena.ontology.Ontology o = ontModel.createOntology(adjustOntologyURI(ontology.getURI())); 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) { addPropertyStringValue(o,ONTOLOGY_PREFIX_ANNOT,ontology.getPrefix(),ontModel); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java index fba1936e1..8112a4965 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/PropertyDaoJena.java @@ -3,7 +3,6 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; 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.shared.Lock; import com.hp.hpl.jena.sparql.resultset.ResultSetMem; +import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.RDFS; @@ -596,6 +596,31 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { } } + private List listSuperClasses(OntClass ontClass) { + return relatedClasses(ontClass, RDFS.subClassOf); + } + + private List listEquivalentClasses(OntClass ontClass) { + return relatedClasses(ontClass, OWL.equivalentClass); + } + + private List relatedClasses(OntClass ontClass, + com.hp.hpl.jena.rdf.model.Property property) { + List classes = new ArrayList(); + 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 getAllPropInstByVClasses(List vclasses) { List propInsts = new ArrayList(); @@ -628,8 +653,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { OntClass ontClass = getOntClass(ontModel,VClassURI); if (ontClass != null) { List relatedClasses = new ArrayList(); - relatedClasses.addAll(ontClass.listEquivalentClasses().toList()); - relatedClasses.addAll(ontClass.listSuperClasses().toList()); + relatedClasses.addAll(listEquivalentClasses(ontClass)); + relatedClasses.addAll(listSuperClasses(ontClass)); for (OntClass relatedClass : relatedClasses) { // find properties in restrictions if (relatedClass.isRestriction()) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SimpleOntModelSelector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SimpleOntModelSelector.java index 73c356a38..7564dc891 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SimpleOntModelSelector.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SimpleOntModelSelector.java @@ -14,14 +14,14 @@ import com.hp.hpl.jena.shared.Lock; */ public class SimpleOntModelSelector implements OntModelSelector { - private OntModel fullModel; - private OntModel aboxModel; - private OntModel applicationMetadataModel; - private OntModel tboxModel; - private OntModel userAccountsModel; + protected OntModel fullModel; + protected OntModel aboxModel; + protected OntModel applicationMetadataModel; + protected OntModel tboxModel; + protected OntModel userAccountsModel; - private OntModelSpec DEFAULT_ONT_MODEL_SPEC = OntModelSpec.OWL_MEM; - private OntModel displayModel; + protected OntModelSpec DEFAULT_ONT_MODEL_SPEC = OntModelSpec.OWL_MEM; + protected OntModel displayModel; /** * Construct an OntModelSelector with a bunch of empty models diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SingleContentOntModelSelector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SingleContentOntModelSelector.java new file mode 100644 index 000000000..b9d65d2c1 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SingleContentOntModelSelector.java @@ -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; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraph.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraph.java index 54d0d9280..702c89434 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraph.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraph.java @@ -82,11 +82,25 @@ public class SparqlGraph implements GraphWithPerform { @Override public void performAdd(Triple t) { - String updateString = "INSERT DATA { " + //log.info("adding " + t); + + String updateString = "INSERT DATA { GRAPH { " + sparqlNode(t.getSubject(), "") + " " + sparqlNode(t.getPredicate(), "") + " " + sparqlNode(t.getObject(), "") + - "}"; + " } }"; + + if (false) { + try { + + throw new RuntimeException("Breakpoint"); + } catch (RuntimeException e) { + log.error(e, e); + //throw(e); + } + } + + //log.info(updateString); try { RepositoryConnection conn = getConnection(); @@ -108,11 +122,15 @@ public class SparqlGraph implements GraphWithPerform { @Override public void performDelete(Triple t) { - String updateString = "DELETE DATA { " + log.info ("************** DELETE!!!!! ********************"); + + String updateString = "DELETE DATA { GRAPH { " + sparqlNode(t.getSubject(), "") + " " + sparqlNode(t.getPredicate(), "") + " " + sparqlNode(t.getObject(), "") + - "}"; + " } }"; + + log.info(updateString); try { RepositoryConnection conn = getConnection(); @@ -158,6 +176,7 @@ public class SparqlGraph implements GraphWithPerform { @Override public void delete(Triple arg0) throws DeleteDeniedException { + log.info("********************** DELETE!!!!!! ************************"); performDelete(arg0); } @@ -212,7 +231,7 @@ public class SparqlGraph implements GraphWithPerform { .append(sparqlNode(object, "?o")) .append("\n}"); - log.info(findQuery.toString()); + //log.info(findQuery.toString()); ResultSet rs = execSelect(findQuery.toString()); //rs = execSelect(findQuery.toString()); //rs = execSelect(findQuery.toString()); @@ -226,6 +245,7 @@ public class SparqlGraph implements GraphWithPerform { //log.info(t); triplist.add(t); } + //log.info(triplist.size() + " results"); return WrappedIterator.create(triplist.iterator()); } @@ -236,7 +256,7 @@ public class SparqlGraph implements GraphWithPerform { @Override public BulkUpdateHandler getBulkUpdateHandler() { if (this.bulkUpdateHandler == null) { - this.bulkUpdateHandler = new SimpleBulkUpdateHandler(this); + this.bulkUpdateHandler = new SparqlGraphBulkUpdater(this); } return this.bulkUpdateHandler; } @@ -383,7 +403,7 @@ public class SparqlGraph implements GraphWithPerform { try { return new ResultSetMem(qe.execSelect()); } finally { - log.info((System.currentTimeMillis() - startTime) + " to execute via Jena"); + //log.info((System.currentTimeMillis() - startTime) + " to execute via Jena"); qe.close(); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphMultilingual.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphMultilingual.java new file mode 100644 index 000000000..dd8f719e0 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SparqlGraphMultilingual.java @@ -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 langs; + + + public SparqlGraphMultilingual(String endpointURI, List 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 find(TripleMatch arg0) { + //log.info("find(TripleMatch) " + arg0); + Triple t = arg0.asTriple(); + return find(t.getSubject(), t.getPredicate(), t.getObject()); + } + + @Override + public ExtendedIterator find(Node subject, Node predicate, Node object) { + + long startTime = System.currentTimeMillis(); + + ExtendedIterator rawResults = super.find(subject, predicate, object); + long rawTime = System.currentTimeMillis() - startTime; + + List tripList = new ArrayList(); + 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 tripl = new LinkedList(); + 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 { + + 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; + } + } + + } + + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java index cdc1221a4..e33d777c1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VClassDaoJena.java @@ -9,6 +9,9 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import com.hp.hpl.jena.ontology.AllValuesFromRestriction; import com.hp.hpl.jena.ontology.AnnotationProperty; import com.hp.hpl.jena.ontology.CardinalityRestriction; @@ -58,108 +61,110 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.PelletListener; public class VClassDaoJena extends JenaBaseDao implements VClassDao { - + + protected static final Log log = LogFactory.getLog(VClassDaoJena.class); + public VClassDaoJena(WebappDaoFactoryJena wadf) { super(wadf); } - + @Override protected OntModel getOntModel() { - return getOntModelSelector().getTBoxModel(); + return getOntModelSelector().getTBoxModel(); } - + /* ************************************************** */ - + public String getLabelForClass(OntClass cls,boolean withPrefix,boolean forPickList) { - cls.getModel().enterCriticalSection(Lock.READ); - try { - if (cls.isAnon()) { - if (cls.isRestriction()) { - Restriction rest = cls.asRestriction(); - OntProperty onProperty = rest.getOnProperty(); - String labelStr = "restriction on " + getLabelOrId(onProperty) + ": "; - if (rest.isAllValuesFromRestriction() || rest.isSomeValuesFromRestriction()) { - Resource fillerRes = null; - if (rest.isAllValuesFromRestriction()) { - AllValuesFromRestriction avfRest = rest.asAllValuesFromRestriction(); - fillerRes = avfRest.getAllValuesFrom(); - labelStr += "all values from "; - } else { - SomeValuesFromRestriction svfRest = rest.asSomeValuesFromRestriction(); - fillerRes = svfRest.getSomeValuesFrom(); - labelStr += "some values from "; - } - if (fillerRes.canAs(OntClass.class)) { - OntClass avf = (OntClass) fillerRes.as(OntClass.class); - labelStr += getLabelForClass(avf,withPrefix,forPickList); - } else { - try { - labelStr += getLabelOrId( (OntResource) fillerRes.as(OntResource.class)); - } catch (Exception e) { - labelStr += "???"; - } - } - } else if (rest.isHasValueRestriction()) { - HasValueRestriction hvRest = rest.asHasValueRestriction(); - labelStr += "has value "; - RDFNode fillerNode = hvRest.getHasValue(); - try { - if (fillerNode.isResource()) { - labelStr += getLabelOrId((OntResource)fillerNode.as(OntResource.class)); - } else { - labelStr += ((Literal) fillerNode.as(Literal.class)).getLexicalForm(); - } - } catch (Exception e) { - labelStr += "???"; - } - } else if (rest.isMinCardinalityRestriction()) { - MinCardinalityRestriction mcRest = rest.asMinCardinalityRestriction(); - labelStr += "minimum cardinality "; - labelStr += mcRest.getMinCardinality(); - } else if (rest.isMaxCardinalityRestriction()) { - MaxCardinalityRestriction mcRest = rest.asMaxCardinalityRestriction(); - labelStr += "maximum cardinality "; - labelStr += mcRest.getMaxCardinality(); - } else if (rest.isCardinalityRestriction()) { - CardinalityRestriction cRest = rest.asCardinalityRestriction(); - labelStr += "cardinality "; - labelStr += cRest.getCardinality(); - } - return labelStr; - } else if (isBooleanClassExpression(cls)) { - String labelStr = "("; - if (cls.isComplementClass()) { - labelStr += "not "; - ComplementClass ccls = (ComplementClass) cls.as(ComplementClass.class); - labelStr += getLabelForClass(ccls.getOperand(),withPrefix,forPickList); - } else if (cls.isIntersectionClass()) { - IntersectionClass icls = (IntersectionClass) cls.as(IntersectionClass.class); - for (Iterator operandIt = icls.listOperands(); operandIt.hasNext();) { - OntClass operand = (OntClass) operandIt.next(); - labelStr += getLabelForClass(operand,withPrefix,forPickList); - if (operandIt.hasNext()) { - labelStr += " and "; - } - } - } else if (cls.isUnionClass()) { - UnionClass icls = (UnionClass) cls.as(UnionClass.class); - for (Iterator operandIt = icls.listOperands(); operandIt.hasNext();) { - OntClass operand = (OntClass) operandIt.next(); - labelStr += getLabelForClass(operand,withPrefix,forPickList); - if (operandIt.hasNext()) { - labelStr += " or "; - } - } - } - return labelStr+")"; - } else { - // BJL23 2009-02-19 - // I'm putting the link markup in because I need it, - // but obviously we need to factor this out into the display layer. - return "[anonymous class]"; - } - } else { - if (withPrefix || forPickList) { + cls.getModel().enterCriticalSection(Lock.READ); + try { + if (cls.isAnon()) { + if (cls.isRestriction()) { + Restriction rest = cls.asRestriction(); + OntProperty onProperty = rest.getOnProperty(); + String labelStr = "restriction on " + getLabelOrId(onProperty) + ": "; + if (rest.isAllValuesFromRestriction() || rest.isSomeValuesFromRestriction()) { + Resource fillerRes = null; + if (rest.isAllValuesFromRestriction()) { + AllValuesFromRestriction avfRest = rest.asAllValuesFromRestriction(); + fillerRes = avfRest.getAllValuesFrom(); + labelStr += "all values from "; + } else { + SomeValuesFromRestriction svfRest = rest.asSomeValuesFromRestriction(); + fillerRes = svfRest.getSomeValuesFrom(); + labelStr += "some values from "; + } + if (fillerRes.canAs(OntClass.class)) { + OntClass avf = (OntClass) fillerRes.as(OntClass.class); + labelStr += getLabelForClass(avf,withPrefix,forPickList); + } else { + try { + labelStr += getLabelOrId( (OntResource) fillerRes.as(OntResource.class)); + } catch (Exception e) { + labelStr += "???"; + } + } + } else if (rest.isHasValueRestriction()) { + HasValueRestriction hvRest = rest.asHasValueRestriction(); + labelStr += "has value "; + RDFNode fillerNode = hvRest.getHasValue(); + try { + if (fillerNode.isResource()) { + labelStr += getLabelOrId((OntResource)fillerNode.as(OntResource.class)); + } else { + labelStr += ((Literal) fillerNode.as(Literal.class)).getLexicalForm(); + } + } catch (Exception e) { + labelStr += "???"; + } + } else if (rest.isMinCardinalityRestriction()) { + MinCardinalityRestriction mcRest = rest.asMinCardinalityRestriction(); + labelStr += "minimum cardinality "; + labelStr += mcRest.getMinCardinality(); + } else if (rest.isMaxCardinalityRestriction()) { + MaxCardinalityRestriction mcRest = rest.asMaxCardinalityRestriction(); + labelStr += "maximum cardinality "; + labelStr += mcRest.getMaxCardinality(); + } else if (rest.isCardinalityRestriction()) { + CardinalityRestriction cRest = rest.asCardinalityRestriction(); + labelStr += "cardinality "; + labelStr += cRest.getCardinality(); + } + return labelStr; + } else if (isBooleanClassExpression(cls)) { + String labelStr = "("; + if (cls.isComplementClass()) { + labelStr += "not "; + ComplementClass ccls = (ComplementClass) cls.as(ComplementClass.class); + labelStr += getLabelForClass(ccls.getOperand(),withPrefix,forPickList); + } else if (cls.isIntersectionClass()) { + IntersectionClass icls = (IntersectionClass) cls.as(IntersectionClass.class); + for (Iterator operandIt = icls.listOperands(); operandIt.hasNext();) { + OntClass operand = (OntClass) operandIt.next(); + labelStr += getLabelForClass(operand,withPrefix,forPickList); + if (operandIt.hasNext()) { + labelStr += " and "; + } + } + } else if (cls.isUnionClass()) { + UnionClass icls = (UnionClass) cls.as(UnionClass.class); + for (Iterator operandIt = icls.listOperands(); operandIt.hasNext();) { + OntClass operand = (OntClass) operandIt.next(); + labelStr += getLabelForClass(operand,withPrefix,forPickList); + if (operandIt.hasNext()) { + labelStr += " or "; + } + } + } + return labelStr+")"; + } else { + // BJL23 2009-02-19 + // I'm putting the link markup in because I need it, + // but obviously we need to factor this out into the display layer. + return "[anonymous class]"; + } + } else { + if (withPrefix || forPickList) { OntologyDao oDao=getWebappDaoFactory().getOntologyDao(); Ontology o = (Ontology)oDao.getOntologyByURI(cls.getNameSpace()); if (o!=null) { @@ -169,56 +174,56 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { return(getLabelOrId(cls)+(o.getPrefix()==null?(o.getName()==null?" (unspec)":" ("+o.getName()+")"):" ("+o.getPrefix()+")")); } } else { - return getLabelOrId(cls); + return getLabelOrId(cls); } - } - return getLabelOrId(cls); - } - } catch (Exception e) { - return "???"; - } finally { - cls.getModel().leaveCriticalSection(); - } + } + return getLabelOrId(cls); + } + } catch (Exception e) { + return "???"; + } finally { + cls.getModel().leaveCriticalSection(); + } } public void deleteVClass(VClass cls) { - deleteVClass(cls,getOntModel()); + deleteVClass(cls,getOntModel()); } public void deleteVClass(String URI) { - deleteVClass(URI,getOntModel()); + deleteVClass(URI,getOntModel()); } public void deleteVClass(String URI, OntModel ontModel) { - ontModel.enterCriticalSection(Lock.WRITE); - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); - try { - OntClass cls = getOntClass(ontModel,URI); - if (cls != null) { - //Remove restriction class. - Iterator restIt = ontModel.listSubjectsWithProperty(OWL.allValuesFrom, cls); - while(restIt.hasNext()) { - Resource restRes = restIt.next(); - if (restRes.canAs(OntResource.class)) { - OntResource restOntRes = (OntResource) restRes.as(OntResource.class); - smartRemove(restOntRes, ontModel); - } - } - restIt = ontModel.listSubjectsWithProperty(OWL.someValuesFrom, cls); - while(restIt.hasNext()) { - Resource restRes = restIt.next(); - if (restRes.canAs(OntResource.class)) { - OntResource restOntRes = (OntResource) restRes.as(OntResource.class); - smartRemove(restOntRes, ontModel); - } - } - removeRulesMentioningResource(cls, ontModel); - smartRemove(cls, ontModel); - } - } finally { - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); - ontModel.leaveCriticalSection(); - } + ontModel.enterCriticalSection(Lock.WRITE); + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); + try { + OntClass cls = getOntClass(ontModel,URI); + if (cls != null) { + //Remove restriction class. + Iterator restIt = ontModel.listSubjectsWithProperty(OWL.allValuesFrom, cls); + while(restIt.hasNext()) { + Resource restRes = restIt.next(); + if (restRes.canAs(OntResource.class)) { + OntResource restOntRes = (OntResource) restRes.as(OntResource.class); + smartRemove(restOntRes, ontModel); + } + } + restIt = ontModel.listSubjectsWithProperty(OWL.someValuesFrom, cls); + while(restIt.hasNext()) { + Resource restRes = restIt.next(); + if (restRes.canAs(OntResource.class)) { + OntResource restOntRes = (OntResource) restRes.as(OntResource.class); + smartRemove(restOntRes, ontModel); + } + } + removeRulesMentioningResource(cls, ontModel); + smartRemove(cls, ontModel); + } + } finally { + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); + ontModel.leaveCriticalSection(); + } } public void deleteVClass(VClass cls, OntModel ontModel) { @@ -226,218 +231,218 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { } public List getDisjointWithClassURIs(String classURI) { - OntClass ontClass = getOntClass(getOntModel(), classURI); - List uriList = new ArrayList(); - getOntModel().enterCriticalSection(Lock.READ); - try { - for (Iterator i = ontClass.listDisjointWith(); i.hasNext(); ) { - OntClass disjointClass = (OntClass) i.next(); - uriList.add(getClassURIStr(disjointClass)); - } - } catch (ProfileException pe) { - // Current language profile does not support disjointWith axioms. - // We'd prefer to return an empty list instead of throwing an exception. - } finally { - getOntModel().leaveCriticalSection(); - } - return uriList; + OntClass ontClass = getOntClass(getOntModel(), classURI); + List uriList = new ArrayList(); + getOntModel().enterCriticalSection(Lock.READ); + try { + for (Iterator i = ontClass.listDisjointWith(); i.hasNext(); ) { + OntClass disjointClass = (OntClass) i.next(); + uriList.add(getClassURIStr(disjointClass)); + } + } catch (ProfileException pe) { + // Current language profile does not support disjointWith axioms. + // We'd prefer to return an empty list instead of throwing an exception. + } finally { + getOntModel().leaveCriticalSection(); + } + return uriList; } - + public void addDisjointWithClass(String classURI, String disjointClassURI) { - getOntModel().enterCriticalSection(Lock.WRITE); - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); - try { - OntClass ontClass = getOntClass(getOntModel(),classURI); - OntClass disjointClass = getOntClass(getOntModel(),disjointClassURI); - ontClass.addDisjointWith(disjointClass); - } finally { - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); - getOntModel().leaveCriticalSection(); - } + getOntModel().enterCriticalSection(Lock.WRITE); + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); + try { + OntClass ontClass = getOntClass(getOntModel(),classURI); + OntClass disjointClass = getOntClass(getOntModel(),disjointClassURI); + ontClass.addDisjointWith(disjointClass); + } finally { + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); + getOntModel().leaveCriticalSection(); + } } - + public void removeDisjointWithClass(String classURI, String disjointClassURI) { - getOntModel().enterCriticalSection(Lock.WRITE); - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); - try { - OntClass ontClass = getOntClass(getOntModel(),classURI); - OntClass disjointClass = getOntClass(getOntModel(),disjointClassURI); - ontClass.removeDisjointWith(disjointClass); - } finally { - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); - getOntModel().leaveCriticalSection(); - } + getOntModel().enterCriticalSection(Lock.WRITE); + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); + try { + OntClass ontClass = getOntClass(getOntModel(),classURI); + OntClass disjointClass = getOntClass(getOntModel(),disjointClassURI); + ontClass.removeDisjointWith(disjointClass); + } finally { + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); + getOntModel().leaveCriticalSection(); + } } - + public List getEquivalentClassURIs(String classURI) { - List equivalentClassURIs = new ArrayList(); - getOntModel().enterCriticalSection(Lock.READ); - try { - OntClass ontClass = getOntClass(getOntModel(), classURI); - ClosableIterator equivalentOntClassIt = ontClass.listEquivalentClasses(); - try { - for (Iterator eqOntClassIt = equivalentOntClassIt; eqOntClassIt.hasNext(); ) { - OntClass eqClass = (OntClass) eqOntClassIt.next(); - equivalentClassURIs.add(getClassURIStr(eqClass)); - } - } finally { - equivalentOntClassIt.close(); - } - } catch (ProfileException pe) { - // Current language profile does not support equivalent classes. - // We'd prefer to return an empty list instead of throwing an exception - } catch (Exception e) { + List equivalentClassURIs = new ArrayList(); + getOntModel().enterCriticalSection(Lock.READ); + try { + OntClass ontClass = getOntClass(getOntModel(), classURI); + ClosableIterator equivalentOntClassIt = ontClass.listEquivalentClasses(); + try { + for (Iterator eqOntClassIt = equivalentOntClassIt; eqOntClassIt.hasNext(); ) { + OntClass eqClass = (OntClass) eqOntClassIt.next(); + equivalentClassURIs.add(getClassURIStr(eqClass)); + } + } finally { + equivalentOntClassIt.close(); + } + } catch (ProfileException pe) { + // Current language profile does not support equivalent classes. + // We'd prefer to return an empty list instead of throwing an exception + } catch (Exception e) { // we'll try this again using a different method that - // doesn't try to convert to OntClass + // doesn't try to convert to OntClass List supList = this.listDirectObjectPropertyValues( getOntModel().getResource(classURI), OWL.equivalentClass); for (Resource res : supList) { equivalentClassURIs.add(getClassURIStr(res)); } - } finally { - getOntModel().leaveCriticalSection(); - } - return equivalentClassURIs; + } finally { + getOntModel().leaveCriticalSection(); + } + return equivalentClassURIs; } - + public void addSuperclass(VClass vclass, VClass superclass) { - addSuperclass(vclass.getURI(),superclass.getURI()); + addSuperclass(vclass.getURI(),superclass.getURI()); } - + public void addSuperclass(String vclassURI, String superclassURI) { - Classes2Classes c2c = new Classes2Classes(); - c2c.setSubclassURI(vclassURI); - c2c.setSuperclassURI(superclassURI); - getWebappDaoFactory().getClasses2ClassesDao().insertNewClasses2Classes(c2c); + Classes2Classes c2c = new Classes2Classes(); + c2c.setSubclassURI(vclassURI); + c2c.setSuperclassURI(superclassURI); + insertNewClasses2Classes(c2c); } - + public void removeSuperclass(VClass vclass, VClass superclass) { - removeSuperclass(vclass.getURI(),superclass.getURI()); + removeSuperclass(vclass.getURI(),superclass.getURI()); } - + public void removeSuperclass(String vclassURI, String superclassURI) { - Classes2Classes c2c = new Classes2Classes(); - c2c.setSubclassURI(vclassURI); - c2c.setSuperclassURI(superclassURI); - getWebappDaoFactory().getClasses2ClassesDao().deleteClasses2Classes(c2c); + Classes2Classes c2c = new Classes2Classes(); + c2c.setSubclassURI(vclassURI); + c2c.setSuperclassURI(superclassURI); + deleteClasses2Classes(c2c); } - + public void addSubclass(VClass vclass, VClass subclass) { - addSubclass(vclass.getURI(),subclass.getURI()); + addSubclass(vclass.getURI(),subclass.getURI()); } - + public void addSubclass(String vclassURI, String subclassURI) { - Classes2Classes c2c = new Classes2Classes(); - c2c.setSubclassURI(subclassURI); - c2c.setSuperclassURI(vclassURI); - getWebappDaoFactory().getClasses2ClassesDao().insertNewClasses2Classes(c2c); + Classes2Classes c2c = new Classes2Classes(); + c2c.setSubclassURI(subclassURI); + c2c.setSuperclassURI(vclassURI); + insertNewClasses2Classes(c2c); } - + public void removeSubclass(VClass vclass, VClass subclass) { - removeSubclass(vclass.getURI(),subclass.getURI()); + removeSubclass(vclass.getURI(),subclass.getURI()); } - + public void removeSubclass(String vclassURI, String subclassURI) { - Classes2Classes c2c = new Classes2Classes(); - c2c.setSubclassURI(subclassURI); - c2c.setSuperclassURI(vclassURI); - getWebappDaoFactory().getClasses2ClassesDao().deleteClasses2Classes(c2c); + Classes2Classes c2c = new Classes2Classes(); + c2c.setSubclassURI(subclassURI); + c2c.setSuperclassURI(vclassURI); + deleteClasses2Classes(c2c); } - + public void addEquivalentClass(String classURI, String equivalentClassURI) { - getOntModel().enterCriticalSection(Lock.WRITE); - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); - try { - OntClass ontClass = getOntClass(getOntModel(),classURI); - OntClass eqClass = getOntClass(getOntModel(),equivalentClassURI); - ontClass.addEquivalentClass(eqClass); - eqClass.addEquivalentClass(ontClass); - } finally { - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); - getOntModel().leaveCriticalSection(); - } + getOntModel().enterCriticalSection(Lock.WRITE); + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); + try { + OntClass ontClass = getOntClass(getOntModel(),classURI); + OntClass eqClass = getOntClass(getOntModel(),equivalentClassURI); + ontClass.addEquivalentClass(eqClass); + eqClass.addEquivalentClass(ontClass); + } finally { + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); + getOntModel().leaveCriticalSection(); + } } - + public void removeEquivalentClass(String classURI, String equivalentClassURI) { - getOntModel().enterCriticalSection(Lock.WRITE); - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); - try { - OntClass ontClass = getOntClass(getOntModel(),classURI); - OntClass eqClass = getOntClass(getOntModel(),equivalentClassURI); - ontClass.removeEquivalentClass(eqClass); - eqClass.removeEquivalentClass(ontClass); - if (ontClass.isAnon()) { - smartRemove(ontClass, getOntModel()); - } - if (eqClass.isAnon()) { - smartRemove(eqClass, getOntModel()); - } - } finally { - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); - getOntModel().leaveCriticalSection(); - } + getOntModel().enterCriticalSection(Lock.WRITE); + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); + try { + OntClass ontClass = getOntClass(getOntModel(),classURI); + OntClass eqClass = getOntClass(getOntModel(),equivalentClassURI); + ontClass.removeEquivalentClass(eqClass); + eqClass.removeEquivalentClass(ontClass); + if (ontClass.isAnon()) { + smartRemove(ontClass, getOntModel()); + } + if (eqClass.isAnon()) { + smartRemove(eqClass, getOntModel()); + } + } finally { + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); + getOntModel().leaveCriticalSection(); + } } - + public List getAllSubClassURIs(String classURI) { - HashSet nodeSet = new HashSet(); - nodeSet.add(classURI); - getAllSubClassURIs(classURI, nodeSet); - nodeSet.remove(classURI); - List outputList = new ArrayList(); - outputList.addAll(nodeSet); - return outputList; + HashSet nodeSet = new HashSet(); + nodeSet.add(classURI); + getAllSubClassURIs(classURI, nodeSet); + nodeSet.remove(classURI); + List outputList = new ArrayList(); + outputList.addAll(nodeSet); + return outputList; } - + public void getAllSubClassURIs(String classURI, HashSet subtree){ List directSubclasses = getSubClassURIs(classURI); Iterator it=directSubclasses.iterator(); while(it.hasNext()){ String uri = (String)it.next(); if (!subtree.contains(uri)) { - subtree.add(uri); - getAllSubClassURIs(uri,subtree); + subtree.add(uri); + getAllSubClassURIs(uri,subtree); } } } public List getAllSuperClassURIs(String classURI) { - - List superclassURIs = null; - - //String infersTypes = getWebappDaoFactory().getProperties().get("infersTypes"); - //if ("true".equalsIgnoreCase(infersTypes)) { - - PelletListener pl = getWebappDaoFactory().getPelletListener(); - if (pl != null && pl.isConsistent() && !pl.isInErrorState() && !pl.isReasoning()) { - superclassURIs = new ArrayList(); - OntClass cls = getOntClass(getOntModel(),classURI); - StmtIterator superClassIt = getOntModel().listStatements(cls,RDFS.subClassOf,(RDFNode)null); - while (superClassIt.hasNext()) { - Statement stmt = superClassIt.nextStatement(); - if (stmt.getObject().canAs(OntResource.class)) { - OntResource superRes = (OntResource) stmt.getObject().as(OntResource.class); - String test = getClassURIStr(superRes); - superclassURIs.add(test); - } - } - return superclassURIs; - } else { - HashSet nodeSet = new HashSet(); - nodeSet.add(classURI); - getAllSuperClassURIs(classURI, nodeSet); - //nodeSet.remove(classURI); - return new ArrayList(nodeSet); - } + + List superclassURIs = null; + + //String infersTypes = getWebappDaoFactory().getProperties().get("infersTypes"); + //if ("true".equalsIgnoreCase(infersTypes)) { + + PelletListener pl = getWebappDaoFactory().getPelletListener(); + if (pl != null && pl.isConsistent() && !pl.isInErrorState() && !pl.isReasoning()) { + superclassURIs = new ArrayList(); + OntClass cls = getOntClass(getOntModel(),classURI); + StmtIterator superClassIt = getOntModel().listStatements(cls,RDFS.subClassOf,(RDFNode)null); + while (superClassIt.hasNext()) { + Statement stmt = superClassIt.nextStatement(); + if (stmt.getObject().canAs(OntResource.class)) { + OntResource superRes = (OntResource) stmt.getObject().as(OntResource.class); + String test = getClassURIStr(superRes); + superclassURIs.add(test); + } + } + return superclassURIs; + } else { + HashSet nodeSet = new HashSet(); + nodeSet.add(classURI); + getAllSuperClassURIs(classURI, nodeSet); + //nodeSet.remove(classURI); + return new ArrayList(nodeSet); + } } - + public void getAllSuperClassURIs(String classURI, HashSet subtree){ List directSuperclasses = getSuperClassURIs(classURI, true); Iterator it=directSuperclasses.iterator(); while(it.hasNext()){ String uri = (String)it.next(); if (!subtree.contains(uri)) { - subtree.add(uri); - getAllSuperClassURIs(uri,subtree); + subtree.add(uri); + getAllSuperClassURIs(uri,subtree); } } } @@ -446,11 +451,12 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { List classes = new ArrayList(); getOntModel().enterCriticalSection(Lock.READ); try { - ClosableIterator classIt = getOntModel().listClasses(); + ClosableIterator classIt = getOntModel().listIndividuals(OWL.Class); try { while (classIt.hasNext()) { try { - OntClass cls = classIt.next(); + Individual classInd = classIt.next(); + OntClass cls = (OntClass) classInd.as(OntClass.class); if (!cls.isAnon() && !(NONUSER_NAMESPACES.contains(cls.getNameSpace()))) { classes.add(new VClassJena(cls,getWebappDaoFactory())); } @@ -467,68 +473,72 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { Collections.sort(classes); return classes; } - + private Iterator smarterListHierarchyRootClasses(OntModel ontModel) { - return smarterListHierarchyRootClasses(ontModel, null); + return smarterListHierarchyRootClasses(ontModel, null); } - + /** * The basic idea here is that we ignore anonymous superclasses for the purpose * of determining whether something is a root class. * We also avoid ClassCastExceptions deep in Jena-land by eschewing Jena's * listSuperClasses() method. * @author bjl23 - */ + */ private Iterator smarterListHierarchyRootClasses(OntModel ontModel, String ontologyURI) { - List rootClassList = new ArrayList(); - ClosableIterator ci = ontModel.listClasses(); - try { - for (ClosableIterator i = ci ; i.hasNext(); ) { - try { - OntClass ontClass = (OntClass) i.next(); - boolean isRoot = true; - for (Iterator j = ontClass.listPropertyValues(RDFS.subClassOf); j.hasNext(); ) { - Resource res = (Resource) j.next(); - if (res.canAs(OntClass.class)) { - OntClass superClass = (OntClass) res.as(OntClass.class); - if (!superClass.isAnon() && - ((ontologyURI==null) || (ontologyURI.equals(superClass.getNameSpace()))) && - !OWL.Thing.equals(superClass) && - !superClass.equals(ontClass) && - !( ontModel.contains(ontClass,OWL.equivalentClass,superClass) || - ontModel.contains(superClass,OWL.equivalentClass,ontClass) ) ) { - if ( (superClass.getNameSpace() != null) - && (!(NONUSER_NAMESPACES.contains( - superClass.getNameSpace()))) ) { - isRoot=false; - break; - } - } - } - } - if (isRoot) { - rootClassList.add(ontClass); - } - } catch (ClassCastException cce) { - log.error(cce); - } - } - } finally { - ci.close(); - } - return rootClassList.iterator(); + List rootClassList = new ArrayList(); + ClosableIterator ci = ontModel.listIndividuals(OWL.Class); + try { + for (ClosableIterator i = ci ; i.hasNext(); ) { + try { + Individual classInd = i.next(); + // if (!classInd.canAs(OntClass.class)) { + // continue; + // } + OntClass ontClass = (OntClass) classInd.as(OntClass.class); + boolean isRoot = true; + for (Iterator j = ontClass.listPropertyValues(RDFS.subClassOf); j.hasNext(); ) { + Resource res = (Resource) j.next(); + if (res.canAs(OntClass.class)) { + OntClass superClass = (OntClass) res.as(OntClass.class); + if (!superClass.isAnon() && + ((ontologyURI==null) || (ontologyURI.equals(superClass.getNameSpace()))) && + !OWL.Thing.equals(superClass) && + !superClass.equals(ontClass) && + !( ontModel.contains(ontClass,OWL.equivalentClass,superClass) || + ontModel.contains(superClass,OWL.equivalentClass,ontClass) ) ) { + if ( (superClass.getNameSpace() != null) + && (!(NONUSER_NAMESPACES.contains( + superClass.getNameSpace()))) ) { + isRoot=false; + break; + } + } + } + } + if (isRoot) { + rootClassList.add(ontClass); + } + } catch (ClassCastException cce) { + log.error(cce, cce); + } + } + } finally { + ci.close(); + } + return rootClassList.iterator(); } public List getRootClasses() { - return getRootClasses(null); + return getRootClasses(null); } - + private List getRootClasses(String ontologyURI) { List rootClasses = new ArrayList(); getOntModel().enterCriticalSection(Lock.READ); try { - Iterator rootIt = smarterListHierarchyRootClasses( - getOntModel(), ontologyURI); + Iterator rootIt = smarterListHierarchyRootClasses( + getOntModel(), ontologyURI); while (rootIt.hasNext()) { OntClass cls = rootIt.next(); if (!cls.isAnon() && cls.getNameSpace() != null @@ -545,40 +555,40 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { public List getOntologyRootClasses(String ontologyURI) { - if (ontologyURI == null) { - throw new RuntimeException("can't find root classes for null ontology URI"); - } - // return getRootClasses(ontologyURI); - List ontologyRootClasses = new ArrayList(); - OntModel ontModel = getOntModel(); - ontModel.enterCriticalSection(Lock.READ); - try { - Iterator ontClassIt = ontModel.listClasses(); - while (ontClassIt.hasNext()) { - OntClass ontClass = ontClassIt.next(); - if (ontologyURI.equals(ontClass.getNameSpace())) { - boolean root = true; - StmtIterator superStmtIt = ontModel.listStatements(ontClass, RDFS.subClassOf, (RDFNode) null); - try { - while (superStmtIt.hasNext()) { - Statement superStmt = superStmtIt.nextStatement(); - if ( superStmt.getObject().isResource() && ontologyURI.equals(((Resource) superStmt.getObject()).getNameSpace()) ) { - root = false; - break; - } - } - } finally { - superStmtIt.close(); - } - if (root) { - ontologyRootClasses.add(new VClassJena(ontClass,getWebappDaoFactory())); - } - } - } - } finally { - ontModel.leaveCriticalSection(); - } - return ontologyRootClasses; + if (ontologyURI == null) { + throw new RuntimeException("can't find root classes for null ontology URI"); + } + // return getRootClasses(ontologyURI); + List ontologyRootClasses = new ArrayList(); + OntModel ontModel = getOntModel(); + ontModel.enterCriticalSection(Lock.READ); + try { + Iterator ontClassIt = ontModel.listClasses(); + while (ontClassIt.hasNext()) { + OntClass ontClass = ontClassIt.next(); + if (ontologyURI.equals(ontClass.getNameSpace())) { + boolean root = true; + StmtIterator superStmtIt = ontModel.listStatements(ontClass, RDFS.subClassOf, (RDFNode) null); + try { + while (superStmtIt.hasNext()) { + Statement superStmt = superStmtIt.nextStatement(); + if ( superStmt.getObject().isResource() && ontologyURI.equals(((Resource) superStmt.getObject()).getNameSpace()) ) { + root = false; + break; + } + } + } finally { + superStmtIt.close(); + } + if (root) { + ontologyRootClasses.add(new VClassJena(ontClass,getWebappDaoFactory())); + } + } + } + } finally { + ontModel.leaveCriticalSection(); + } + return ontologyRootClasses; } public List getSubClassURIs(String classURI) { @@ -591,15 +601,15 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { subURIs.add(getClassURIStr(cls)); } } catch (Exception e) { - // we'll try this again using a different method that doesn't try to convert to OntClass - List supList = this.listDirectObjectPropertySubjects(getOntModel().getResource(classURI), RDFS.subClassOf); - for (Resource res : supList) { - subURIs.add(res.getURI()); - } + // we'll try this again using a different method that doesn't try to convert to OntClass + List supList = this.listDirectObjectPropertySubjects(getOntModel().getResource(classURI), RDFS.subClassOf); + for (Resource res : supList) { + subURIs.add(res.getURI()); + } } return subURIs; } - + public List getSuperClassURIs(String classURI, boolean direct) { List supURIs = new ArrayList(); OntClass subClass = getOntClass(getOntModel(), classURI); @@ -610,54 +620,54 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { supURIs.add(getClassURIStr(cls)); } } catch (Exception e) { - //TODO make this attempt respect the direct argument - // we'll try this again using a different method that doesn't try to convert to OntClass - List supList = this.listDirectObjectPropertyValues(getOntModel().getResource(classURI), RDFS.subClassOf); - for (Resource res : supList) { - supURIs.add(getClassURIStr(res)); - } + //TODO make this attempt respect the direct argument + // we'll try this again using a different method that doesn't try to convert to OntClass + List supList = this.listDirectObjectPropertyValues(getOntModel().getResource(classURI), RDFS.subClassOf); + for (Resource res : supList) { + supURIs.add(getClassURIStr(res)); + } } return supURIs; } public VClass getTopConcept() { - VClass top = new VClass(); - if (getOntModel().getProfile().NAMESPACE().equals(RDFS.getURI())) { - top.setURI(RDF.getURI()+"Resource"); - } else { - top.setURI( (getOntModel().getProfile().THING().getURI()!=null) ? (getOntModel().getProfile().THING().getURI()): null); - } - if (top.getURI() != null) { - top.setName(top.getLocalName()); - return top; - } else { - return null; - } + VClass top = new VClass(); + if (getOntModel().getProfile().NAMESPACE().equals(RDFS.getURI())) { + top.setURI(RDF.getURI()+"Resource"); + } else { + top.setURI( (getOntModel().getProfile().THING().getURI()!=null) ? (getOntModel().getProfile().THING().getURI()): null); + } + if (top.getURI() != null) { + top.setName(top.getLocalName()); + return top; + } else { + return null; + } } - + public VClass getBottomConcept() { - VClass bottom = new VClass(); - if (getOntModel().getProfile().NAMESPACE().equals(RDFS.getURI())) { - return null; - } else { - bottom.setURI( (getOntModel().getProfile().NOTHING().getURI()!=null) ? (getOntModel().getProfile().NOTHING().getURI()): null); - } - if (bottom.getURI() != null) { - bottom.setName(bottom.getLocalName()); - return bottom; - } else { - return null; - } + VClass bottom = new VClass(); + if (getOntModel().getProfile().NAMESPACE().equals(RDFS.getURI())) { + return null; + } else { + bottom.setURI( (getOntModel().getProfile().NOTHING().getURI()!=null) ? (getOntModel().getProfile().NOTHING().getURI()): null); + } + if (bottom.getURI() != null) { + bottom.setName(bottom.getLocalName()); + return bottom; + } else { + return null; + } } - + public VClass getVClassByURI(String URIStr) { getOntModel().enterCriticalSection(Lock.READ); try { - OntClass cls = getOntClass(getOntModel(),URIStr); + OntClass cls = getOntClass(getOntModel(),URIStr); if (cls != null) { return new VClassJena(cls,getWebappDaoFactory()); } else { - return null; + return null; } } finally { getOntModel().leaveCriticalSection(); @@ -665,74 +675,74 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { } public void insertNewVClass(VClass cls) throws InsertException { - insertNewVClass(cls,getOntModelSelector().getTBoxModel()); + insertNewVClass(cls,getOntModelSelector().getTBoxModel()); } public List getVClassesForProperty(String propertyURI, boolean domainSide) { - return getVClassesForProperty(null, propertyURI, domainSide); + return getVClassesForProperty(null, propertyURI, domainSide); } - + public List getVClassesForProperty(String vclassURI, String propertyURI) { - return getVClassesForProperty(vclassURI, propertyURI, true); + return getVClassesForProperty(vclassURI, propertyURI, true); } - + private List getVClassesForProperty(String vclassURI, String propertyURI, boolean domainSide) { List vClasses = new ArrayList(); getOntModel().enterCriticalSection(Lock.READ); try { ObjectProperty op = getOntModel().getObjectProperty(propertyURI); if (op != null) { - OntResource superclass = null; - if (vclassURI != null) { - // TODO need a getAllSuperPropertyURIs method in ObjectPropertyDao - List superproperties = getWebappDaoFactory().getObjectPropertyDao().getSuperPropertyURIs(propertyURI,false); - superproperties.add(propertyURI); - HashSet subjSuperclasses = new HashSet(getAllSuperClassURIs(vclassURI)); - subjSuperclasses.add(vclassURI); - for (String objectPropertyURI : superproperties) { - for (Iterator restStmtIt = getOntModel().listStatements(null,OWL.onProperty,getOntModel().getProperty(objectPropertyURI)); restStmtIt.hasNext();) { - Statement restStmt = (Statement) restStmtIt.next(); - Resource restRes = restStmt.getSubject(); - for (Iterator axStmtIt = getOntModel().listStatements(null,null,restRes); axStmtIt.hasNext();) { - Statement axStmt = (Statement) axStmtIt.next(); - OntResource subjOntRes = null; - if (axStmt.getSubject().canAs(OntResource.class)) { - subjOntRes = (OntResource) axStmt.getSubject().as(OntResource.class); - } - if ( - (subjOntRes != null) && (subjSuperclasses.contains(getClassURIStr(subjOntRes))) && - (axStmt.getPredicate().equals(RDFS.subClassOf) || (axStmt.getPredicate().equals(OWL.equivalentClass))) - ) { - if (restRes.canAs(AllValuesFromRestriction.class)) { - AllValuesFromRestriction avfRest = (AllValuesFromRestriction) restRes.as(AllValuesFromRestriction.class); - Resource avf = avfRest.getAllValuesFrom(); - if (avf.canAs(OntClass.class)) { - superclass = (OntClass) avfRest.getAllValuesFrom().as(OntClass.class); - } - } - } - } - } - } - } - if (superclass == null) { - superclass = (domainSide) ? op.getRange() : op.getDomain(); - if (superclass == null) { - superclass = getOntModel().getOntResource(OWL.Thing.getURI()); - } - } + OntResource superclass = null; + if (vclassURI != null) { + // TODO need a getAllSuperPropertyURIs method in ObjectPropertyDao + List superproperties = getWebappDaoFactory().getObjectPropertyDao().getSuperPropertyURIs(propertyURI,false); + superproperties.add(propertyURI); + HashSet subjSuperclasses = new HashSet(getAllSuperClassURIs(vclassURI)); + subjSuperclasses.add(vclassURI); + for (String objectPropertyURI : superproperties) { + for (Iterator restStmtIt = getOntModel().listStatements(null,OWL.onProperty,getOntModel().getProperty(objectPropertyURI)); restStmtIt.hasNext();) { + Statement restStmt = (Statement) restStmtIt.next(); + Resource restRes = restStmt.getSubject(); + for (Iterator axStmtIt = getOntModel().listStatements(null,null,restRes); axStmtIt.hasNext();) { + Statement axStmt = (Statement) axStmtIt.next(); + OntResource subjOntRes = null; + if (axStmt.getSubject().canAs(OntResource.class)) { + subjOntRes = (OntResource) axStmt.getSubject().as(OntResource.class); + } + if ( + (subjOntRes != null) && (subjSuperclasses.contains(getClassURIStr(subjOntRes))) && + (axStmt.getPredicate().equals(RDFS.subClassOf) || (axStmt.getPredicate().equals(OWL.equivalentClass))) + ) { + if (restRes.canAs(AllValuesFromRestriction.class)) { + AllValuesFromRestriction avfRest = (AllValuesFromRestriction) restRes.as(AllValuesFromRestriction.class); + Resource avf = avfRest.getAllValuesFrom(); + if (avf.canAs(OntClass.class)) { + superclass = (OntClass) avfRest.getAllValuesFrom().as(OntClass.class); + } + } + } + } + } + } + } + if (superclass == null) { + superclass = (domainSide) ? op.getRange() : op.getDomain(); + if (superclass == null) { + superclass = getOntModel().getOntResource(OWL.Thing.getURI()); + } + } if (superclass != null) { - VClass superVclass; - if (superclass.isAnon()) { - superVclass = getVClassByURI(getClassURIStr(superclass)); - } else { - superVclass = getVClassByURI(superclass.getURI()); - } + VClass superVclass; + if (superclass.isAnon()) { + superVclass = getVClassByURI(getClassURIStr(superclass)); + } else { + superVclass = getVClassByURI(superclass.getURI()); + } if (superVclass != null) { vClasses.add(superVclass); //Commenting out this section to prevent all subclasses of owl:Thing //returned if range is owl:Thing, refer to NIHVIVO-3357 - /* String isInferencing = getWebappDaoFactory().getProperties().get("infersTypes"); + /* String isInferencing = getWebappDaoFactory().getProperties().get("infersTypes"); // if this model infers types based on the taxonomy, adding the subclasses will only // waste time for no benefit PelletListener pl = getWebappDaoFactory().getPelletListener(); @@ -755,263 +765,309 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao { return vClasses; } -///////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////// - public void addVClassesToGroup(VClassGroup group) { - addVClassesToGroup(group, true); - } + public void addVClassesToGroup(VClassGroup group) { + addVClassesToGroup(group, true); + } - @Deprecated - public void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedClasses) { - addVClassesToGroup(group, includeUninstantiatedClasses, false); - } + @Deprecated + public void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedClasses) { + addVClassesToGroup(group, includeUninstantiatedClasses, false); + } - @Deprecated - public void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedClasses, boolean getIndividualCount) { - getOntModel().enterCriticalSection(Lock.READ); - - if (getIndividualCount) { - group.setIndividualCount( getClassGroupInstanceCount(group)); - } - - try { - if ((group != null) && (group.getURI() != null)) { - Resource groupRes = ResourceFactory.createResource(group.getURI()); - AnnotationProperty inClassGroup = getOntModel().getAnnotationProperty(VitroVocabulary.IN_CLASSGROUP); - if (inClassGroup != null) { - ClosableIterator annotIt = getOntModel().listStatements((OntClass)null,inClassGroup,groupRes); - try { - while (annotIt.hasNext()) { - try { - Statement annot = (Statement) annotIt.next(); - Resource cls = (Resource) annot.getSubject(); - VClass vcw = (VClass) getVClassByURI(cls.getURI()); - if (vcw != null) { - boolean classIsInstantiated = false; - if (getIndividualCount) { - Model aboxModel = getOntModelSelector().getABoxModel(); - aboxModel.enterCriticalSection(Lock.READ); - int count = 0; - try { - String countQueryStr = "SELECT COUNT(*) WHERE \n" + - "{ ?s a <" + cls.getURI() + "> } \n"; - Query countQuery = QueryFactory.create(countQueryStr, Syntax.syntaxARQ); - QueryExecution qe = QueryExecutionFactory.create(countQuery, aboxModel); - ResultSet rs =qe.execSelect(); - count = Integer.parseInt(((Literal) rs.nextSolution().get(".1")).getLexicalForm()); - //count = aboxModel.listStatements(null,RDF.type,cls).toList().size(); - } finally { - aboxModel.leaveCriticalSection(); - } - vcw.setEntityCount(count); - classIsInstantiated = (count > 0); - } else if (includeUninstantiatedClasses == false) { - // Note: to support SDB models, may want to do this with - // SPARQL and LIMIT 1 if SDB can take advantage of it - Model aboxModel = getOntModelSelector().getABoxModel(); - aboxModel.enterCriticalSection(Lock.READ); - try { - ClosableIterator countIt = aboxModel.listStatements(null,RDF.type,cls); - try { - if (countIt.hasNext()) { - classIsInstantiated = true; - } - } finally { - countIt.close(); - } - } finally { - aboxModel.leaveCriticalSection(); - } + @Deprecated + public void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedClasses, boolean getIndividualCount) { + getOntModel().enterCriticalSection(Lock.READ); + + if (getIndividualCount) { + group.setIndividualCount( getClassGroupInstanceCount(group)); + } + + try { + if ((group != null) && (group.getURI() != null)) { + Resource groupRes = ResourceFactory.createResource(group.getURI()); + AnnotationProperty inClassGroup = getOntModel().getAnnotationProperty(VitroVocabulary.IN_CLASSGROUP); + if (inClassGroup != null) { + ClosableIterator annotIt = getOntModel().listStatements((OntClass)null,inClassGroup,groupRes); + try { + while (annotIt.hasNext()) { + try { + Statement annot = (Statement) annotIt.next(); + Resource cls = (Resource) annot.getSubject(); + VClass vcw = (VClass) getVClassByURI(cls.getURI()); + if (vcw != null) { + boolean classIsInstantiated = false; + if (getIndividualCount) { + Model aboxModel = getOntModelSelector().getABoxModel(); + aboxModel.enterCriticalSection(Lock.READ); + int count = 0; + try { + String countQueryStr = "SELECT COUNT(*) WHERE \n" + + "{ ?s a <" + cls.getURI() + "> } \n"; + Query countQuery = QueryFactory.create(countQueryStr, Syntax.syntaxARQ); + QueryExecution qe = QueryExecutionFactory.create(countQuery, aboxModel); + ResultSet rs =qe.execSelect(); + count = Integer.parseInt(((Literal) rs.nextSolution().get(".1")).getLexicalForm()); + //count = aboxModel.listStatements(null,RDF.type,cls).toList().size(); + } finally { + aboxModel.leaveCriticalSection(); } - - if (includeUninstantiatedClasses || classIsInstantiated) { - group.add(vcw); + vcw.setEntityCount(count); + classIsInstantiated = (count > 0); + } else if (includeUninstantiatedClasses == false) { + // Note: to support SDB models, may want to do this with + // SPARQL and LIMIT 1 if SDB can take advantage of it + Model aboxModel = getOntModelSelector().getABoxModel(); + aboxModel.enterCriticalSection(Lock.READ); + try { + ClosableIterator countIt = aboxModel.listStatements(null,RDF.type,cls); + try { + if (countIt.hasNext()) { + classIsInstantiated = true; + } + } finally { + countIt.close(); + } + } finally { + aboxModel.leaveCriticalSection(); } } - } catch (ClassCastException cce) { - log.error(cce, cce); + + if (includeUninstantiatedClasses || classIsInstantiated) { + group.add(vcw); + } } + } catch (ClassCastException cce) { + log.error(cce, cce); } - } finally { - annotIt.close(); } + } finally { + annotIt.close(); } } - java.util.Collections.sort(group.getVitroClassList()); - } finally { - getOntModel().leaveCriticalSection(); } + java.util.Collections.sort(group.getVitroClassList()); + } finally { + getOntModel().leaveCriticalSection(); } + } - int getClassGroupInstanceCount(VClassGroup vcg){ - Model ontModel = getOntModel(); - ontModel.enterCriticalSection(Lock.READ); - int count = 0; - try { - String queryText = + int getClassGroupInstanceCount(VClassGroup vcg){ + Model ontModel = getOntModel(); + ontModel.enterCriticalSection(Lock.READ); + int count = 0; + try { + String queryText = "SELECT COUNT( DISTINCT ?instance ) WHERE { \n" + - " ?class <"+VitroVocabulary.IN_CLASSGROUP+"> <"+vcg.getURI() +"> .\n" + - " ?instance a ?class . \n" + - "}" ; - Query countQuery = QueryFactory.create(queryText, Syntax.syntaxARQ); - QueryExecution qe = QueryExecutionFactory.create(countQuery, ontModel); - ResultSet rs =qe.execSelect(); - count = Integer.parseInt(((Literal) rs.nextSolution().get(".1")).getLexicalForm()); - }catch(Exception ex){ - log.error(ex,ex); - } finally { - ontModel.leaveCriticalSection(); - } - return count; - } - - - public void addVClassesToGroups(List groups) { - getOntModel().enterCriticalSection(Lock.READ); - try { - if (groups != null) { - Iterator groupIt = groups.iterator(); - while (groupIt.hasNext()) { - VClassGroup g = (VClassGroup) groupIt.next(); - addVClassesToGroup(g); - } - } - } finally { - getOntModel().leaveCriticalSection(); - } + " ?class <"+VitroVocabulary.IN_CLASSGROUP+"> <"+vcg.getURI() +"> .\n" + + " ?instance a ?class . \n" + + "}" ; + Query countQuery = QueryFactory.create(queryText, Syntax.syntaxARQ); + QueryExecution qe = QueryExecutionFactory.create(countQuery, ontModel); + ResultSet rs =qe.execSelect(); + count = Integer.parseInt(((Literal) rs.nextSolution().get(".1")).getLexicalForm()); + }catch(Exception ex){ + log.error(ex,ex); + } finally { + ontModel.leaveCriticalSection(); } + return count; + } - public int insertNewVClass(VClass cls, OntModel ontModel) throws InsertException { - ontModel.enterCriticalSection(Lock.WRITE); - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); - try { - String errMsgStr = getWebappDaoFactory().checkURI(cls.getURI()); - if (errMsgStr != null) { - throw new InsertException(errMsgStr); - } - OntClass ontCls = ontModel.createClass(cls.getURI()); - try { - if (cls.getName() != null && cls.getName().length() > 0) { - ontCls.setLabel(cls.getName(), (String) getDefaultLanguage()); - } else { - ontCls.removeAll(RDFS.label); - } - } catch (Exception e) { - log.error("error setting label for class "+cls.getURI()); + + public void addVClassesToGroups(List groups) { + getOntModel().enterCriticalSection(Lock.READ); + try { + if (groups != null) { + Iterator groupIt = groups.iterator(); + while (groupIt.hasNext()) { + VClassGroup g = (VClassGroup) groupIt.next(); + addVClassesToGroup(g); } - try { - if (cls.getGroupURI() != null && cls.getGroupURI().length()>0) { - String badURIErrorStr = checkURI(cls.getGroupURI()); - if (badURIErrorStr == null) { - ontCls.addProperty(IN_CLASSGROUP, getOntModel().getResource(cls.getGroupURI())); - } else { - log.error(badURIErrorStr); - } - } - } catch (Exception e) { - log.error("error linking class "+cls.getURI()+" to class group"); - } - addPropertyStringValue(ontCls,SHORTDEF,cls.getShortDef(),ontModel); - addPropertyStringValue(ontCls,EXAMPLE_ANNOT,cls.getExample(),ontModel); - addPropertyStringValue(ontCls,DESCRIPTION_ANNOT,cls.getDescription(),ontModel); - addPropertyIntValue(ontCls,DISPLAY_LIMIT,cls.getDisplayLimit(),ontModel); - addPropertyIntValue(ontCls,DISPLAY_RANK_ANNOT,cls.getDisplayRank(),ontModel); - - ontCls.removeAll(HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT); - if (HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT != null && cls.getHiddenFromDisplayBelowRoleLevel() != null) { // only need to add if present - try { - ontCls.addProperty(HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT, ResourceFactory.createResource(cls.getHiddenFromDisplayBelowRoleLevel().getURI())); - } catch (Exception e) { - log.error("error adding HiddenFromDisplayBelowRoleLevel annotation to class "+cls.getURI()); - } - } - - ontCls.removeAll(PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT); - if (PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT != null && cls.getProhibitedFromUpdateBelowRoleLevel() != null) { // only need to add if present - try { - ontCls.addProperty(PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT, ResourceFactory.createResource(cls.getProhibitedFromUpdateBelowRoleLevel().getURI())); - } catch (Exception e) { - log.error("error adding ProhibitedFromUpdateBelowRoleLevel annotation to class "+cls.getURI()); - } - } - - /* OPTIONAL annotation properties */ - addPropertyStringValue(ontCls,PROPERTY_CUSTOMENTRYFORMANNOT,cls.getCustomEntryForm(),ontModel); - addPropertyStringValue(ontCls,PROPERTY_CUSTOMDISPLAYVIEWANNOT,cls.getCustomDisplayView(),ontModel); - addPropertyStringValue(ontCls,PROPERTY_CUSTOMSHORTVIEWANNOT,cls.getCustomShortView(),ontModel); - addPropertyStringValue(ontCls,PROPERTY_CUSTOMSEARCHVIEWANNOT,cls.getCustomSearchView(),ontModel); - addPropertyFloatValue(ontCls, SEARCH_BOOST_ANNOT, cls.getSearchBoost(), ontModel); - } finally { - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); - ontModel.leaveCriticalSection(); + } + } finally { + getOntModel().leaveCriticalSection(); + } + } + + public int insertNewVClass(VClass cls, OntModel ontModel) throws InsertException { + ontModel.enterCriticalSection(Lock.WRITE); + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); + try { + String errMsgStr = getWebappDaoFactory().checkURI(cls.getURI()); + if (errMsgStr != null) { + throw new InsertException(errMsgStr); } - return 0; - } - - public void updateVClass(VClass cls) { - updateVClass(cls,getOntModel()); - } - - public void updateVClass(VClass cls, OntModel ontModel) { - ontModel.enterCriticalSection(Lock.WRITE); - ontModel.getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); + OntClass ontCls = ontModel.createClass(cls.getURI()); try { - OntClass ontCls = ontModel.getOntClass(cls.getURI()); - - if (ontCls != null) { - updateRDFSLabel(ontCls, cls.getName()); - updatePropertyResourceURIValue(ontCls,IN_CLASSGROUP,cls.getGroupURI(),ontModel); - updatePropertyStringValue(ontCls,SHORTDEF,cls.getShortDef(),ontModel); - updatePropertyStringValue(ontCls,EXAMPLE_ANNOT,cls.getExample(),ontModel); - updatePropertyStringValue(ontCls,DESCRIPTION_ANNOT,cls.getDescription(),ontModel); - updatePropertyNonNegativeIntValue(ontCls,DISPLAY_LIMIT,cls.getDisplayLimit(),ontModel); - updatePropertyNonNegativeIntValue(ontCls,DISPLAY_RANK_ANNOT,cls.getDisplayRank(),ontModel); - updatePropertyFloatValue(ontCls, SEARCH_BOOST_ANNOT, cls.getSearchBoost(), ontModel); - - if (cls.getHiddenFromDisplayBelowRoleLevel() != null) { - updatePropertyResourceURIValue(ontCls,HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT,cls.getHiddenFromDisplayBelowRoleLevel().getURI(),ontModel); - } - - if (cls.getProhibitedFromUpdateBelowRoleLevel() != null) { - updatePropertyResourceURIValue(ontCls,PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT,cls.getProhibitedFromUpdateBelowRoleLevel().getURI(),ontModel); - } - - updatePropertyStringValue(ontCls,PROPERTY_CUSTOMENTRYFORMANNOT,cls.getCustomEntryForm(),ontModel); - updatePropertyStringValue(ontCls,PROPERTY_CUSTOMDISPLAYVIEWANNOT,cls.getCustomDisplayView(),ontModel); - updatePropertyStringValue(ontCls,PROPERTY_CUSTOMSHORTVIEWANNOT,cls.getCustomShortView(),ontModel); - updatePropertyStringValue(ontCls,PROPERTY_CUSTOMSEARCHVIEWANNOT,cls.getCustomSearchView(),ontModel); + if (cls.getName() != null && cls.getName().length() > 0) { + ontCls.setLabel(cls.getName(), (String) getDefaultLanguage()); } else { - log.error("error: cannot find jena class "+cls.getURI()+" for updating"); + ontCls.removeAll(RDFS.label); } - } finally { - getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); - ontModel.leaveCriticalSection(); + } catch (Exception e) { + log.error("error setting label for class "+cls.getURI()); } + try { + if (cls.getGroupURI() != null && cls.getGroupURI().length()>0) { + String badURIErrorStr = checkURI(cls.getGroupURI()); + if (badURIErrorStr == null) { + ontCls.addProperty(IN_CLASSGROUP, getOntModel().getResource(cls.getGroupURI())); + } else { + log.error(badURIErrorStr); + } + } + } catch (Exception e) { + log.error("error linking class "+cls.getURI()+" to class group"); + } + addPropertyStringValue(ontCls,SHORTDEF,cls.getShortDef(),ontModel); + addPropertyStringValue(ontCls,EXAMPLE_ANNOT,cls.getExample(),ontModel); + addPropertyStringValue(ontCls,DESCRIPTION_ANNOT,cls.getDescription(),ontModel); + addPropertyIntValue(ontCls,DISPLAY_LIMIT,cls.getDisplayLimit(),ontModel); + addPropertyIntValue(ontCls,DISPLAY_RANK_ANNOT,cls.getDisplayRank(),ontModel); + + ontCls.removeAll(HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT); + if (HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT != null && cls.getHiddenFromDisplayBelowRoleLevel() != null) { // only need to add if present + try { + ontCls.addProperty(HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT, ResourceFactory.createResource(cls.getHiddenFromDisplayBelowRoleLevel().getURI())); + } catch (Exception e) { + log.error("error adding HiddenFromDisplayBelowRoleLevel annotation to class "+cls.getURI()); + } + } + + ontCls.removeAll(PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT); + if (PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT != null && cls.getProhibitedFromUpdateBelowRoleLevel() != null) { // only need to add if present + try { + ontCls.addProperty(PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT, ResourceFactory.createResource(cls.getProhibitedFromUpdateBelowRoleLevel().getURI())); + } catch (Exception e) { + log.error("error adding ProhibitedFromUpdateBelowRoleLevel annotation to class "+cls.getURI()); + } + } + + /* OPTIONAL annotation properties */ + addPropertyStringValue(ontCls,PROPERTY_CUSTOMENTRYFORMANNOT,cls.getCustomEntryForm(),ontModel); + addPropertyStringValue(ontCls,PROPERTY_CUSTOMDISPLAYVIEWANNOT,cls.getCustomDisplayView(),ontModel); + addPropertyStringValue(ontCls,PROPERTY_CUSTOMSHORTVIEWANNOT,cls.getCustomShortView(),ontModel); + addPropertyStringValue(ontCls,PROPERTY_CUSTOMSEARCHVIEWANNOT,cls.getCustomSearchView(),ontModel); + addPropertyFloatValue(ontCls, SEARCH_BOOST_ANNOT, cls.getSearchBoost(), ontModel); + } finally { + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); + ontModel.leaveCriticalSection(); } - + return 0; + } + + public void updateVClass(VClass cls) { + updateVClass(cls,getOntModel()); + } + + public void updateVClass(VClass cls, OntModel ontModel) { + ontModel.enterCriticalSection(Lock.WRITE); + ontModel.getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),true)); + try { + OntClass ontCls = ontModel.getOntClass(cls.getURI()); + + if (ontCls != null) { + updateRDFSLabel(ontCls, cls.getName()); + updatePropertyResourceURIValue(ontCls,IN_CLASSGROUP,cls.getGroupURI(),ontModel); + updatePropertyStringValue(ontCls,SHORTDEF,cls.getShortDef(),ontModel); + updatePropertyStringValue(ontCls,EXAMPLE_ANNOT,cls.getExample(),ontModel); + updatePropertyStringValue(ontCls,DESCRIPTION_ANNOT,cls.getDescription(),ontModel); + updatePropertyNonNegativeIntValue(ontCls,DISPLAY_LIMIT,cls.getDisplayLimit(),ontModel); + updatePropertyNonNegativeIntValue(ontCls,DISPLAY_RANK_ANNOT,cls.getDisplayRank(),ontModel); + updatePropertyFloatValue(ontCls, SEARCH_BOOST_ANNOT, cls.getSearchBoost(), ontModel); + + if (cls.getHiddenFromDisplayBelowRoleLevel() != null) { + updatePropertyResourceURIValue(ontCls,HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT,cls.getHiddenFromDisplayBelowRoleLevel().getURI(),ontModel); + } + + if (cls.getProhibitedFromUpdateBelowRoleLevel() != null) { + updatePropertyResourceURIValue(ontCls,PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT,cls.getProhibitedFromUpdateBelowRoleLevel().getURI(),ontModel); + } + + updatePropertyStringValue(ontCls,PROPERTY_CUSTOMENTRYFORMANNOT,cls.getCustomEntryForm(),ontModel); + updatePropertyStringValue(ontCls,PROPERTY_CUSTOMDISPLAYVIEWANNOT,cls.getCustomDisplayView(),ontModel); + updatePropertyStringValue(ontCls,PROPERTY_CUSTOMSHORTVIEWANNOT,cls.getCustomShortView(),ontModel); + updatePropertyStringValue(ontCls,PROPERTY_CUSTOMSEARCHVIEWANNOT,cls.getCustomSearchView(),ontModel); + } else { + log.error("error: cannot find jena class "+cls.getURI()+" for updating"); + } + } finally { + getOntModel().getBaseModel().notifyEvent(new EditEvent(getWebappDaoFactory().getUserURI(),false)); + ontModel.leaveCriticalSection(); + } + } + + 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(); + } + } + public boolean isSubClassOf(VClass vc1, VClass vc2) { - if (vc1 == null || vc2 == null) { - return false; - } - return isSubClassOf(vc1.getURI(), vc2.getURI()); + if (vc1 == null || vc2 == null) { + return false; + } + return isSubClassOf(vc1.getURI(), vc2.getURI()); } - + public boolean isSubClassOf(String vclassURI1, String vclassURI2) { - if (vclassURI1 == null || vclassURI2 == null) { - return false; - } - OntModel ontModel = getOntModel(); - try { - ontModel.enterCriticalSection(Lock.READ); - OntClass oc1 = getOntClass(ontModel, vclassURI1); - OntClass oc2 = getOntClass(ontModel, vclassURI2); - if (oc1 == null || oc2 == null) { - return false; - } - return ontModel.contains(oc1, RDFS.subClassOf, oc2); - } finally { - ontModel.leaveCriticalSection(); - } + if (vclassURI1 == null || vclassURI2 == null) { + return false; + } + OntModel ontModel = getOntModel(); + try { + ontModel.enterCriticalSection(Lock.READ); + OntClass oc1 = getOntClass(ontModel, vclassURI1); + OntClass oc2 = getOntClass(ontModel, vclassURI2); + if (oc1 == null || oc2 == null) { + return false; + } + return ontModel.contains(oc1, RDFS.subClassOf, oc2); + } finally { + ontModel.leaveCriticalSection(); + } } - + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java index aa7682f0e..055d1501b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/WebappDaoFactoryJena.java @@ -30,7 +30,6 @@ import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.util.iterator.ClosableIterator; 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.DataPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; @@ -233,7 +232,7 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { return config.getDefaultNamespace(); } - public String[] getPreferredLanguages() { + public List getPreferredLanguages() { return config.getPreferredLanguages(); } @@ -311,13 +310,6 @@ public class WebappDaoFactoryJena implements WebappDaoFactory { else return userAccountsDao = new UserAccountsDaoJena(this); } - - Classes2ClassesDao classes2ClassesDao = null; - public Classes2ClassesDao getClasses2ClassesDao() { - if(classes2ClassesDao == null ) - classes2ClassesDao = new Classes2ClassesDaoJena(this); - return classes2ClassesDao; - } DataPropertyStatementDao dataPropertyStatementDao = null; public DataPropertyStatementDao getDataPropertyStatementDao() { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java index 6ac3b4f68..2a2e1fda1 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/pellet/PelletListener.java @@ -163,7 +163,9 @@ public class PelletListener implements ModelChangedListener { this.deletedDataProperties = ModelFactory.createDefaultModel(); this.mainModel.enterCriticalSection(Lock.READ); try { - addedStatements(mainModel); + for (ObjectPropertyStatementPattern pat : this.inferenceDrivingPatternAllowSet) { + addedStatements(mainModel.listStatements((Resource) null, pat.getPredicate(), (RDFNode) null)); + } if (!skipReasoningUponInitialization) { this.foreground = foreground; notifyEvent(null,new EditEvent(null,false)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/ProcessRdfForm.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/ProcessRdfForm.java index 079e19ef3..8d4f503b4 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/ProcessRdfForm.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/ProcessRdfForm.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; 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.jena.DependentResourceDeleteJena; 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; /** @@ -41,8 +43,7 @@ public class ProcessRdfForm { private EditN3GeneratorVTwo populator; private Map urisForNewResources = null; - - /** + /** * Construct the ProcessRdfForm object. */ public ProcessRdfForm( EditConfigurationVTwo config, NewURIMaker newURIMaker){ @@ -171,7 +172,13 @@ public class ProcessRdfForm { //need to substitute into the return to URL becase it may need new resource URIs List 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 ********* */ substituteInMultiURIs(submission.getUrisFromForm(), requiredAsserts, optionalAsserts, URLToReturnTo); logSubstitue( "Added form URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts); @@ -182,10 +189,13 @@ public class ProcessRdfForm { logSubstitue( "Added form Literals", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts); //Retractions does NOT get values from form. + + /* *********** Add subject, object and predicate ******** */ substituteInSubPredObjURIs(editConfig, requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts, URLToReturnTo); logSubstitue( "Added sub, pred and obj URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts); + /* ********* Existing URIs and Literals ********** */ substituteInMultiURIs(editConfig.getUrisInScope(), requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts, URLToReturnTo); @@ -197,7 +207,8 @@ public class ProcessRdfForm { //Both Assertions and Retractions get existing values. /* ************ Edits may need new resources *********** */ - urisForNewResources = URIsForNewRsources(editConfig, newURIMaker); + //moved this up? + //urisForNewResources = URIsForNewRsources(editConfig, newURIMaker); substituteInURIs( urisForNewResources, requiredAsserts, optionalAsserts, URLToReturnTo); logSubstitue( "Added URIs for new Resources", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts); // Only Assertions get new resources. @@ -205,7 +216,9 @@ public class ProcessRdfForm { 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){ //Add retractions for dependent resource delete if that is configured and //if there are any dependent resources. @@ -454,6 +467,36 @@ 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 urisForNewResources, Map> urisFromForm, + List requiredAsserts, List optionalAsserts, + List uRLToReturnTo) { + Map> newUris = new HashMap>(); + //Check if any values from the submission have the "force new uri" value + //TODO: Check how to handle multiple new resource values + Iterator 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 newUrisForKey = new ArrayList(); + newUrisForKey.add(newUri); + newUris.put(key, newUrisForKey); + } + } + if(newUris.size() > 0) { + substituteInMultiURIs(newUris, requiredAsserts, optionalAsserts, uRLToReturnTo); + } + + } + private static Log log = LogFactory.getLog(ProcessRdfForm.class); } \ No newline at end of file diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/EditConfigurationConstants.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/EditConfigurationConstants.java new file mode 100644 index 000000000..7990bd220 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/EditConfigurationConstants.java @@ -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 exportConstants() { + Map constants = new HashMap(); + 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); + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java index 5129d2b80..4c6665172 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/StandardModelSelector.java @@ -5,6 +5,9 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration; import javax.servlet.ServletContext; 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 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 { + private static final Log log = LogFactory.getLog(StandardModelSelector.class); + public OntModel getModel(HttpServletRequest request, ServletContext context) { VitroRequest vreq = new VitroRequest( request ); @@ -23,11 +28,17 @@ public class StandardModelSelector implements ModelSelector { sessionOntModel = oms.getABoxModel(); } } - if(sessionOntModel != null && sessionOntModel instanceof OntModel ) + if(sessionOntModel != null && sessionOntModel instanceof OntModel ) { + log.info("++++++++++ using OntModelSelector from session"); 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 - .getAttribute("unionOntModelSelector")).getABoxModel(); + .getAttribute("unionOntModelSelector")).getABoxModel(); + } } public static final ModelSelector selector = new StandardModelSelector(); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java index 7319f148a..80adcecd0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/BaseEditConfigurationGenerator.java @@ -66,7 +66,7 @@ public abstract class BaseEditConfigurationGenerator implements EditConfiguratio //setup the model selectors for query, write and display models on editConfig setupModelSelectorsFromVitroRequest(vreq, editConfig); - OntModel queryModel = (OntModel)vreq.getAttribute("jenaOntModel"); + OntModel queryModel = vreq.getJenaOntModel(); // (OntModel)vreq.getAttribute("jenaOntModel"); if( editConfig.getSubjectUri() == null) editConfig.setSubjectUri( EditConfigurationUtils.getSubjectUri(vreq)); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/ProcessRdfFormController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/ProcessRdfFormController.java index 3aedff039..3c8c0a717 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/ProcessRdfFormController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/controller/ProcessRdfFormController.java @@ -49,6 +49,8 @@ import edu.cornell.mannlib.vitro.webapp.edit.n3editing.processEdit.RdfLiteralHas public class ProcessRdfFormController extends FreemarkerHttpServlet{ private Log log = LogFactory.getLog(ProcessRdfFormController.class); + + @Override protected Actions requiredActions(VitroRequest vreq) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/AllThumbsAdjuster.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/AllThumbsAdjuster.java deleted file mode 100644 index 129213c5f..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/AllThumbsAdjuster.java +++ /dev/null @@ -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. - *

    - *
  • Figure a name for the main image.
  • - *
  • Copy the thumbnail image file into the main image file.
  • - *
  • Set that file as an image (old-style) on the individual.
  • - *
- */ - 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); - } - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/DeadEndPropertyRemover.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/DeadEndPropertyRemover.java deleted file mode 100644 index f81a1c0e3..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/DeadEndPropertyRemover.java +++ /dev/null @@ -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); - } - } - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSUController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSUController.java deleted file mode 100644 index bc45ad247..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSUController.java +++ /dev/null @@ -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(); - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSULog.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSULog.java deleted file mode 100644 index 33a0e9915..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FSULog.java +++ /dev/null @@ -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"; - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageAliasAdder.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageAliasAdder.java deleted file mode 100644 index 1329e2f65..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageAliasAdder.java +++ /dev/null @@ -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: \n" - + "PREFIX 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: \n" - + "PREFIX 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 bytestreamUrisWithoutAliases; - private Map 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 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 listVariables(QuerySolution result) { - List list = new ArrayList(); - for (Iterator 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 uris = new HashSet(); - - @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 getUris() { - return uris; - } - } - - private class FilenameUnpacker implements QueryResultUnpacker { - private final Map filenameMap = new HashMap(); - - @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 getFilenameMap() { - return filenameMap; - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageUpdater.java deleted file mode 100644 index b31ae17e4..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileStorageUpdater.java +++ /dev/null @@ -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; - -/** - *

- * Clean up any files that are stored in the old directory structure and - * referenced by old-style image properties. - *

- *

- * Besides converting the files to the new framework, this process will produce - * these artifacts: - *

    - *
  • A log file in the uploaded files directory, with a timestamped name, such - * as upgrade/upgradeLog2010-06-20T14-55-00.txt, for example. If - * for any reason, the upgrade process must run again, the log will not be - * overwritten.
  • - *
  • A directory of "deleted" files - these were extra thumbnail files or - * extra main image files -- see the details below.
  • - *
  • A directory of "unreferenced" files - these were in the image directory, - * but not connected to any entity.
  • - *
- *

- *

- * We consider some special cases: - *

    - *
  • An individual may refer to an image file that does not actually exist. If - * so, that reference will be deleted.
  • - *
  • There may be more than one reference to the same image file. If so, all - * but the first such reference will be deleted.
  • - *
  • - * 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.
  • - *
  • - * 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.
  • - *
  • - * 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).
  • - *
- *

- *

- * Aside from these special cases, we will: - *

    - *
  • Translate the main image. - *
      - *
    • Store the image in the new file system.
    • - *
    • Delete the image from the old images directory.
    • - *
    • Create a ByteStream individual for the main image.
    • - *
    • Create a Surrogate individual for the main image.
    • - *
    • Tie these together and attach to the entity that owns the image.
    • - *
    - *
  • - *
  • Translate the thumbnail. - *
      - *
    • Store the thumbnail in the new file system.
    • - *
    • Create a ByteStream individual for the thumbnail.
    • - *
    • Create a Surrogate individual for the thumbnail.
    • - *
    • Tie these together and attach to the Surrogate for the main image.
    • - *
    - *
  • - *
- *

- *

- * 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. - *

- */ -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); - } - - /** - *

- * Go through all of the individuals who have image files or thumbnail - * files, adjusting them to the new way. - *

- *

- * 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. If that's true, clean out the - * old images directory. - *

- */ - 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 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"); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileUtil.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileUtil.java deleted file mode 100644 index 95b40eba1..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FileUtil.java +++ /dev/null @@ -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. - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FsuScanner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FsuScanner.java deleted file mode 100644 index e0549d66e..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/FsuScanner.java +++ /dev/null @@ -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 getValues(Resource resource, Property property) { - List list = new ArrayList(); - 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 getStatements(Resource resource, Property property) { - List list = new ArrayList(); - - 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; - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageDirectoryCleaner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageDirectoryCleaner.java deleted file mode 100644 index 06084ec08..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageDirectoryCleaner.java +++ /dev/null @@ -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 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 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; - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageDirectoryWithBackup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageDirectoryWithBackup.java deleted file mode 100644 index 4ddb5c49f..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageDirectoryWithBackup.java +++ /dev/null @@ -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; - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageSchemaTranslater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageSchemaTranslater.java deleted file mode 100644 index 39409487b..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ImageSchemaTranslater.java +++ /dev/null @@ -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 translate() { - updateLog.section("Copying images into the new file storage, " - + "and adding them to the new model."); - - SortedSet translated = new TreeSet(); - 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. - *
    - *
  • Translate the first main image into the new system.
  • - *
  • Translate the first thumbnail into the new system.
  • - *
  • Remove all old-style main image properties.
  • - *
  • Remove all old-style thumbnail properties.
  • - *
- */ - private void translateImages(Resource resource, - Collection translated) { - List mainImages = getValues(resource, imageProperty); - if (mainImages.size() != 1) { - updateLog.error(resource, "has " + mainImages.size() - + " main images: " + mainImages); - return; - } - - List 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 - *
    - *
  • Attempt to infer MIME type.
  • - *
  • Copy into the File system.
  • - *
  • Create the File and Bytestream individuals in the model.
  • - *
- */ - 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"; - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ModelWrapper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ModelWrapper.java deleted file mode 100644 index d6aa95956..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ModelWrapper.java +++ /dev/null @@ -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 listResourcesWithProperty(Model model, - Property property) { - List list = new ArrayList(); - 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(); - } - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/MultiplePropertyRemover.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/MultiplePropertyRemover.java deleted file mode 100644 index 4148943fa..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/MultiplePropertyRemover.java +++ /dev/null @@ -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 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); - } - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/NoThumbsAdjuster.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/NoThumbsAdjuster.java deleted file mode 100644 index 7166aece1..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/NoThumbsAdjuster.java +++ /dev/null @@ -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. - *
    - *
  • Figure a name for the thumbnail image.
  • - *
  • Make a scaled copy of the main image into the thumbnail.
  • - *
  • Set that file as a thumbnail (old-style) on the individual.
  • - *
- */ - 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(); - } - } - } - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/NonLiteralPropertyRemover.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/NonLiteralPropertyRemover.java deleted file mode 100644 index 6b78468e8..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/NonLiteralPropertyRemover.java +++ /dev/null @@ -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 bogusValues = new ArrayList(); - 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(); - } - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ResourceWrapper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ResourceWrapper.java deleted file mode 100644 index 4253d4d18..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filestorage/updater/ResourceWrapper.java +++ /dev/null @@ -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 listProperties(Resource resource, - Property prop) { - List list = new ArrayList(); - StmtIterator stmts = resource.listProperties(prop); - try { - while (stmts.hasNext()) { - list.add(stmts.next()); - } - return list; - } finally { - stmts.close(); - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java index 30351715d..1791f605d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/filters/WebappDaoFactorySDBPrep.java @@ -5,6 +5,10 @@ package edu.cornell.mannlib.vitro.webapp.filters; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -21,18 +25,27 @@ import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import com.hp.hpl.jena.graph.Graph; +import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; +import com.hp.hpl.jena.query.DataSource; import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.query.DatasetFactory; +import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.sdb.SDBFactory; import com.hp.hpl.jena.sdb.Store; import com.hp.hpl.jena.sdb.StoreDesc; import com.hp.hpl.jena.sdb.sql.SDBConnection; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; +import edu.cornell.mannlib.vitro.webapp.dao.jena.SingleContentOntModelSelector; +import edu.cornell.mannlib.vitro.webapp.dao.jena.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.servlet.setup.JenaDataSourceSetupBase; @@ -89,6 +102,15 @@ public class WebappDaoFactorySDBPrep implements Filter { Dataset dataset = 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 { if (bds == null || storeDesc == null || oms == null) { throw new RuntimeException("SDB store not property set up"); @@ -139,6 +161,56 @@ public class WebappDaoFactorySDBPrep implements Filter { } } + + private void filterSparql(ServletRequest request, OntModelSelector oms, String defaultNamespace) { + log.info("---------"); + + VitroRequest vreq = new VitroRequest((HttpServletRequest) request); + + Enumeration headStrs = vreq.getHeaderNames(); + while (headStrs.hasMoreElements()) { + String head = headStrs.nextElement(); + log.info(head + " : " + vreq.getHeader(head)); + } + + List langs = new ArrayList(); + + log.info("Accept-Language: " + vreq.getHeader("Accept-Language")); + Enumeration locs = vreq.getLocales(); + while (locs.hasMoreElements()) { + Locale locale = locs.nextElement(); + langs.add(locale.toString().replace("_", "-")); + log.info(locale.toString() + " / " + locale.getLanguage() + " + " + locale.getCountry() + " : " + locale.getDisplayCountry() + " | " + locale.getLanguage() + " : " + locale.getDisplayLanguage()); + } + WebappDaoFactoryConfig config = new WebappDaoFactoryConfig(); + config.setDefaultNamespace(defaultNamespace); + config.setPreferredLanguages(langs); + + //okay let's make a graph-backed model + String endpointURI = ConfigurationProperties.getBean( + request).getProperty("VitroConnection.DataSource.endpointURI"); + + Graph g = new SparqlGraphMultilingual(endpointURI, langs); + //Graph g = new SparqlGraph(endpointURI); + + Model m = ModelFactory.createModelForGraph(g); + OntModel om = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, m); + oms = new SingleContentOntModelSelector(om, oms.getDisplayModel(), oms.getUserAccountsModel()); + + 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 public void init(FilterConfig filterConfig) throws ServletException { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java index dd82a95f7..6cb8e322c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasoner.java @@ -43,12 +43,12 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent; * Allows for real-time incremental materialization or retraction of RDFS- * style class and property subsumption based ABox inferences as statements * are added to or removed from the (ABox or TBox) knowledge base. + * @author sjm222 */ public class SimpleReasoner extends StatementListener { 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 aboxModel; // ABox assertions @@ -120,9 +120,9 @@ public class SimpleReasoner extends StatementListener { } /* - * Performs selected incremental ABox reasoning based - * on the addition of a new statement (aka assertion) - * to the ABox. + * Performs incremental ABox reasoning based + * on the addition of a new statement + * (aka assertion) to the ABox. */ @Override 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) * 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) { 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. * * 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. * * Handles rdfs:subclassOf, owl:equivalentClass, @@ -281,10 +286,10 @@ public class SimpleReasoner extends StatementListener { } } - /* - * - */ - public void addedABoxTypeAssertion(Resource individual, Model inferenceModel, HashSet unknownTypes) { + /* + * This signature used when recomputing the whole ABox + */ + protected void addedABoxTypeAssertion(Resource individual, Model inferenceModel, HashSet unknownTypes) { StmtIterator iter = null; @@ -302,6 +307,7 @@ public class SimpleReasoner extends StatementListener { aboxModel.leaveCriticalSection(); } } + /* * Performs incremental reasoning based on a new type assertion * 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 * A assert that B is of that type. - * */ - public void addedABoxTypeAssertion(Statement stmt, Model inferenceModel, HashSet unknownTypes) { + protected void addedABoxTypeAssertion(Statement stmt, Model inferenceModel, HashSet unknownTypes) { tboxModel.enterCriticalSection(Lock.READ); @@ -377,13 +382,10 @@ public class SimpleReasoner extends StatementListener { * that B is of that type. * */ - public void removedABoxTypeAssertion(Statement stmt, Model inferenceModel) { + protected void removedABoxTypeAssertion(Statement stmt, Model inferenceModel) { 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 { OntClass cls = null; @@ -431,7 +433,6 @@ public class SimpleReasoner extends StatementListener { inferenceModel.enterCriticalSection(Lock.WRITE); try { if (inferenceModel.contains(infStmt)) { - //log.debug("Removing this inferred statement: " + infStmt.toString() + " - " + infStmt.getSubject().toString() + " - " + infStmt.getPredicate().toString() + " - " + infStmt.getObject().toString()); inferenceModel.remove(infStmt); } } finally { @@ -454,7 +455,7 @@ public class SimpleReasoner extends StatementListener { // Returns true if it is entailed by class subsumption that // 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); 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 * 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()); OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM); unionModel.addSubModel(aboxModel); @@ -530,7 +531,7 @@ public class SimpleReasoner extends StatementListener { * UNLESS the individual is of some type C that is a subClass * 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); unionModel.addSubModel(aboxModel); unionModel.addSubModel(inferenceModel); @@ -567,10 +568,10 @@ public class SimpleReasoner extends StatementListener { /* * 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. */ - public void setMostSpecificTypes(Resource individual, Model inferenceModel, HashSet unknownTypes) { + protected void setMostSpecificTypes(Resource individual, Model inferenceModel, HashSet unknownTypes) { tboxModel.enterCriticalSection(Lock.READ); aboxModel.enterCriticalSection(Lock.READ); @@ -665,13 +666,13 @@ public class SimpleReasoner extends StatementListener { return; } - public void setMostSpecificTypes(Resource individual, HashSet typeURIs, Model inferenceModel) { + protected void setMostSpecificTypes(Resource individual, HashSet typeURIs, Model inferenceModel) { inferenceModel.enterCriticalSection(Lock.WRITE); try { Model retractions = ModelFactory.createDefaultModel(); - // remove obsolete most-specific-type assertions + // remove obsolete mostSpecificType assertions StmtIterator iter = inferenceModel.listStatements(individual, mostSpecificType, (RDFNode) null); while (iter.hasNext()) { @@ -689,7 +690,7 @@ public class SimpleReasoner extends StatementListener { inferenceModel.remove(retractions); - // add new most-specific-type assertions + // add new mostSpecificType assertions Iterator typeIter = typeURIs.iterator(); while (typeIter.hasNext()) { @@ -706,13 +707,13 @@ public class SimpleReasoner extends StatementListener { return; } - - private boolean recomputing = false; - + /** * Returns true if the reasoner is in the process of recomputing all * inferences. */ + private boolean recomputing = false; + public boolean isRecomputing() { return recomputing; } @@ -731,14 +732,14 @@ public class SimpleReasoner extends StatementListener { /* * Recompute the entire ABox inference graph. The new - * inference graph is built up in a separate model and - * then reconciled with the inference graph used by the - * application. The model reconciliation must be done + * inference graph is built in a separate model and + * then reconciled with the inference graph in active + * use. The model reconciliation must be done * without reading the whole inference models into * memory in order to support very large ABox * inference models. */ - public synchronized void recomputeABox() { + protected synchronized void recomputeABox() { HashSet unknownTypes = new HashSet(); @@ -799,8 +800,8 @@ public class SimpleReasoner extends StatementListener { log.info("Finished computing class-based ABox inferences"); - // reflect the recomputed inferences into the application inference - // model. + // reflect the recomputed inferences into the application + // inference model. log.info("Updating ABox inference model"); StmtIterator iter = null; @@ -912,24 +913,17 @@ public class SimpleReasoner extends StatementListener { log.info("ABox inference model updated"); } - - public synchronized boolean isABoxReasoningAsynchronous() { - if (batchMode1 || batchMode2) { - return true; - } else { - return false; - } - } - - - - public ArrayList getAllIndividualURIs() { + + /* + * Get the URIs for all individuals in the system + */ + protected ArrayList getAllIndividualURIs() { String queryString = "select distinct ?subject where {?subject ?type}"; return getIndividualURIs(queryString); } - public ArrayList getIndividualURIs(String queryString) { + protected ArrayList getIndividualURIs(String queryString) { ArrayList individuals = new ArrayList(); aboxModel.enterCriticalSection(Lock.READ); @@ -960,6 +954,19 @@ public class SimpleReasoner extends StatementListener { 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) { for (ReasonerPlugin plugin : getPluginList()) { @@ -982,36 +989,37 @@ 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() { this.stopRequested = true; } - + + /* + * Utility method for logging + */ public static String stmtString(Statement statement) { return " [subject = " + statement.getSubject().getURI() + "] [property = " + statement.getPredicate().getURI() + "] [object = " + (statement.getObject().isLiteral() ? ((Literal)statement.getObject()).getLexicalForm() + " (Literal)" : ((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 int eventCount = 0; @@ -1083,7 +1091,7 @@ public class SimpleReasoner extends StatementListener { } } } 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; } @@ -1174,5 +1182,5 @@ public class SimpleReasoner extends StatementListener { log.info("ending DeltaComputer.run. batchMode1 = " + batchMode1 + ", batchMode2 = " + batchMode2); } - } + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerTBoxListener.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerTBoxListener.java index e71c98a8c..f3ab12423 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerTBoxListener.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/reasoner/SimpleReasonerTBoxListener.java @@ -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.utils.threads.VitroBackgroundThread; - /** * Route notification of changes to TBox to the incremental ABox reasoner. - * The incremental ABox reasoner handles only subclass, superclass - * and equivalent class axioms. - * + * The incremental ABox reasoner handles only subClass and + * equivalentClass class axioms. Reasoning dones as a result of TBox + * changes is always done in a separate thread. */ public class SimpleReasonerTBoxListener extends StatementListener { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java index 8a33f5979..fd877c6d6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/FileGraphSetup.java @@ -20,7 +20,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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.OntModelSpec; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.sdb.SDBFactory; @@ -48,6 +50,8 @@ public class FileGraphSetup implements ServletContextListener { OntModelSelector baseOms = null; try { + + OntDocumentManager.getInstance().setProcessImports(true); baseOms = ModelContext.getBaseOntModelSelector(sce.getServletContext()); 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()); log.error(t); t.printStackTrace(); + } finally { + OntDocumentManager.getInstance().setProcessImports(false); } if (isUpdateRequired(sce.getServletContext())) { @@ -114,7 +120,7 @@ public class FileGraphSetup implements ServletContextListener { try { FileInputStream fis = new FileInputStream( file ); 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") ) { 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") ) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetup.java index e89770f1e..56376a937 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetup.java @@ -68,6 +68,14 @@ public class JenaDataSourceSetup extends JenaDataSourceSetupBase ServletContext ctx = sce.getServletContext(); 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 { long startTime = System.currentTimeMillis(); setUpJenaDataSource(ctx); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java index 0f02dd12c..8d8c3405d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java @@ -2,9 +2,9 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; +import java.io.File; import java.io.FileInputStream; import java.io.InputStream; -import java.io.File; import java.sql.SQLException; import java.util.Set; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java index 653392e1f..ebba991b6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/PropertyMaskingSetup.java @@ -2,10 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; -import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java index eb8c4fce9..bf0e3d63d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/SimpleReasonerSetup.java @@ -16,7 +16,6 @@ import javax.servlet.ServletContextListener; import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.mindswap.pellet.PelletOptions; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.vocabulary.OWL; @@ -45,6 +44,14 @@ public class SimpleReasonerSetup implements ServletContextListener { @Override 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 { // 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. - PelletOptions.DL_SAFE_RULES = true; - PelletOptions.USE_COMPLETION_QUEUE = true; - PelletOptions.USE_TRACING = true; - PelletOptions.TRACK_BRANCH_EFFECTS = true; - PelletOptions.USE_INCREMENTAL_CONSISTENCY = true; - PelletOptions.USE_INCREMENTAL_DELETION = true; + //PelletOptions.DL_SAFE_RULES = true; + //PelletOptions.USE_COMPLETION_QUEUE = true; + //PelletOptions.USE_TRACING = true; + //PelletOptions.TRACK_BRANCH_EFFECTS = true; + //PelletOptions.USE_INCREMENTAL_CONSISTENCY = true; + //PelletOptions.USE_INCREMENTAL_DELETION = true; PelletListener pelletListener = new PelletListener(unionOms.getTBoxModel(),assertionsOms.getTBoxModel(),inferencesOms.getTBoxModel(),ReasonerConfiguration.DEFAULT); sce.getServletContext().setAttribute("pelletListener",pelletListener); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index 72d011a81..59a99fe8b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -20,16 +20,8 @@ import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModelSpec; -import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.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.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater; diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateUploadedFiles.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateUploadedFiles.java deleted file mode 100644 index 079dfdac0..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateUploadedFiles.java +++ /dev/null @@ -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); - } - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateUserAccounts.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateUserAccounts.java deleted file mode 100644 index df5fbb814..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateUserAccounts.java +++ /dev/null @@ -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 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: "); - w.println("PREFIX rdfs: "); - w.println("PREFIX xsd: "); - w.println("PREFIX vitro: "); - 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 getAllUsers() { - List allUsersList = new ArrayList(); - model.enterCriticalSection(Lock.READ); - try { - ClosableIterator 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); - } - - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ImageUtil.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ImageUtil.java deleted file mode 100644 index 54ee2d4da..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/ImageUtil.java +++ /dev/null @@ -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 DEFAULT_IMAGE_PATHS_BY_TYPE = initImagePaths(); - - private static Map initImagePaths() { - Map map = new HashMap(); - // 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 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 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 - } -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupPageData.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupPageData.java index 70f2200e3..cda39ef69 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupPageData.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/utils/dataGetter/ClassGroupPageData.java @@ -97,7 +97,7 @@ public class ClassGroupPageData extends DataGetterBase implements DataGetter{ setAllClassCountsToZero(group); } }else{ - log.error("classgroup " + classGroupUri + " does not exist in the system"); + throw new RuntimeException("classgroup " + classGroupUri + " does not exist in the system"); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/images/PlaceholderUtil.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/images/PlaceholderUtil.java new file mode 100644 index 000000000..d0c03dad3 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/images/PlaceholderUtil.java @@ -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 mapUrlsByClass; + + private PlaceholderUtil(Map map) { + this.mapUrlsByClass = Collections + .unmodifiableMap(new HashMap(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 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 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 map = new HashMap(); + for (Enumeration 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 map) throws SetupException { + Set imageUrls = new HashSet(); + 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); + } + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/methods/IndividualPlaceholderImageUrlMethod.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/methods/IndividualPlaceholderImageUrlMethod.java new file mode 100644 index 000000000..39692fd11 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/methods/IndividualPlaceholderImageUrlMethod.java @@ -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 help(String name) { + Map map = new LinkedHashMap(); + + map.put("return value", "The URL of the placeholder image for this individual, " + + "based on the VClasses that the individual belongs to."); + + Listparams = new ArrayList(); + params.add("Uri of individual"); + map.put("parameters", params); + + List examples = new ArrayList(); + examples.add(name + "(individual.uri)"); + map.put("examples", examples); + + return map; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseIndividualTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseIndividualTemplateModel.java index de7e00178..b01efe97c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseIndividualTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/BaseIndividualTemplateModel.java @@ -76,15 +76,11 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel { 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() { String imageUrl = individual.getImageUrl(); 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() { String thumbUrl = individual.getThumbUrl(); return thumbUrl == null ? null : getUrl(thumbUrl); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java index 61bbe0e6e..a080cde0b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/GroupedPropertyList.java @@ -207,7 +207,7 @@ public class GroupedPropertyList extends BaseTemplateModel { ObjectPropertyDao opDao = wdf.getObjectPropertyDao(); ObjectProperty op = opDao.getObjectPropertyByURI(propertyUri); 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) { log.error("ObjectProperty op returned with null propertyURI from opDao.getObjectPropertyByURI()"); } else { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java index 9d8eb4638..6569e28d0 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/PropertyTemplateModel.java @@ -111,7 +111,8 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel { } public String getAddUrl() { - return addUrl; + //log.info("addUrl=" + addUrl); + return (addUrl != null) ? addUrl : ""; } public Map getVerboseDisplay() { diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/filtering/IndividualFilteringByStatementTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/filtering/IndividualFilteringByStatementTest.java index 0e9dbda57..b1a765f38 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/filtering/IndividualFilteringByStatementTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/dao/filtering/IndividualFilteringByStatementTest.java @@ -638,18 +638,6 @@ public class IndividualFilteringByStatementTest extends AbstractTestClass { // 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 public void setSubjectURI(String subjectURI) { throw new RuntimeException( diff --git a/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/ProcessRdfFormTest.java b/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/ProcessRdfFormTest.java index 7d992e620..47f61d2fa 100644 --- a/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/ProcessRdfFormTest.java +++ b/webapp/test/edu/cornell/mannlib/vitro/webapp/edit/n3editing/VTwo/ProcessRdfFormTest.java @@ -9,12 +9,16 @@ import java.util.Map; import static org.junit.Assert.*; 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.ModelFactory; 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.webapp.dao.InsertException; +import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfigurationConstants; public class ProcessRdfFormTest extends AbstractTestClass{ @@ -242,6 +246,137 @@ public class ProcessRdfFormTest extends AbstractTestClass{ ResourceFactory.createProperty("http://test.com/uri2"), 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("")); + config.addNewResource("newRes", null); + config.setEntityToReturnTo("?newRes"); + + Map values = new HashMap(); + //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 */ + Listreq = config.getN3Required(); + Listopt = config.getN3Optional(); + processor.subInValuesToN3( config , submission, req, opt, null , null); + assertNotNull(req); + assertTrue( req.size() > 0); + assertNotNull(req.get(0)); + assertEquals("<"+NEWURI_STRING + "0> .", 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 values = new HashMap(); + 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"; diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDaoStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDaoStub.java index 4efba076e..cd24fcc47 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDaoStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/ObjectPropertyStatementDaoStub.java @@ -55,16 +55,6 @@ public class ObjectPropertyStatementDaoStub implements .getObjectURI()); } - @Override - public boolean isSubjectOriented() { - return false; - } - - @Override - public void setSubjectOriented(boolean subjectOriented) { - throw new UnsupportedOperationException(); - } - @Override public String getSubjectURI() { return s; diff --git a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryStub.java b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryStub.java index 6e5a52028..c0aaa9d77 100644 --- a/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryStub.java +++ b/webapp/test/stubs/edu/cornell/mannlib/vitro/webapp/dao/WebappDaoFactoryStub.java @@ -7,7 +7,6 @@ import java.util.Map; import java.util.Set; 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.DataPropertyStatementDao; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; @@ -144,12 +143,6 @@ return this.objectPropertyStatementDao; } // Un-implemented methods // ---------------------------------------------------------------------- - @Override - public Map getProperties() { - throw new RuntimeException( - "WebappDaoFactory.getProperties() not implemented."); - } - @Override public String checkURI(String uriStr) { throw new RuntimeException( @@ -169,7 +162,7 @@ return this.objectPropertyStatementDao; } } @Override - public String[] getPreferredLanguages() { + public List getPreferredLanguages() { throw new RuntimeException( "WebappDaoFactory.getPreferredLanguages() not implemented."); } @@ -192,12 +185,6 @@ return this.objectPropertyStatementDao; } "WebappDaoFactory.getUserURI() not implemented."); } - @Override - public Classes2ClassesDao getClasses2ClassesDao() { - throw new RuntimeException( - "WebappDaoFactory.getClasses2ClassesDao() not implemented."); - } - @Override public DatatypeDao getDatatypeDao() { throw new RuntimeException( diff --git a/webapp/web/WEB-INF/ontologies/app/menu.n3 b/webapp/web/WEB-INF/ontologies/app/menu.n3 index 098fc8a74..1dc16b9cb 100644 --- a/webapp/web/WEB-INF/ontologies/app/menu.n3 +++ b/webapp/web/WEB-INF/ontologies/app/menu.n3 @@ -32,4 +32,4 @@ display:Home ########## Data Getter ############ - a . \ No newline at end of file + a . \ No newline at end of file diff --git a/webapp/web/WEB-INF/resources/permission_config.n3 b/webapp/web/WEB-INF/resources/permission_config.n3 index 8c076e094..f9378222e 100644 --- a/webapp/web/WEB-INF/resources/permission_config.n3 +++ b/webapp/web/WEB-INF/resources/permission_config.n3 @@ -22,6 +22,7 @@ auth:ADMIN auth:hasPermission simplePermission:SeeStartupStatus ; auth:hasPermission simplePermission:UseAdvancedDataToolsPages ; auth:hasPermission simplePermission:UseMiscellaneousAdminPages ; + auth:hasPermission simplePermission:UseSparqlQueryPage ; # permissions for CURATOR and above. auth:hasPermission simplePermission:EditOntology ; diff --git a/webapp/web/WEB-INF/resources/startup_listeners.txt b/webapp/web/WEB-INF/resources/startup_listeners.txt index 034242f09..eb004d336 100644 --- a/webapp/web/WEB-INF/resources/startup_listeners.txt +++ b/webapp/web/WEB-INF/resources/startup_listeners.txt @@ -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.web.images.PlaceholderUtil$Setup + # Update the URIs on Permission Sets on UserAccounts from model (1.4) to 1.5. edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdatePermissionSetUris diff --git a/webapp/web/admin/sparqlquery/sparqlForm.jsp b/webapp/web/admin/sparqlquery/sparqlForm.jsp index b66e3ff98..37968697c 100644 --- a/webapp/web/admin/sparqlquery/sparqlForm.jsp +++ b/webapp/web/admin/sparqlquery/sparqlForm.jsp @@ -7,7 +7,7 @@ <%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %> <%@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); %> diff --git a/webapp/web/css/jquery_plugins/jquery.realperson.css b/webapp/web/css/jquery_plugins/jquery.realperson.css new file mode 100644 index 000000000..1efee66b4 --- /dev/null +++ b/webapp/web/css/jquery_plugins/jquery.realperson.css @@ -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; +} diff --git a/webapp/web/images/placeholders/person.thumbnail.jpg b/webapp/web/images/placeholders/person.thumbnail.jpg deleted file mode 100644 index ddcfe9c61..000000000 Binary files a/webapp/web/images/placeholders/person.thumbnail.jpg and /dev/null differ diff --git a/webapp/web/images/placeholders/placeholders.properties b/webapp/web/images/placeholders/placeholders.properties new file mode 100644 index 000000000..7ebaffd73 --- /dev/null +++ b/webapp/web/images/placeholders/placeholders.properties @@ -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. + diff --git a/webapp/web/js/account/accountProxyCommon.js b/webapp/web/js/account/accountProxyCommon.js index 06af6469f..1e1d09e20 100644 --- a/webapp/web/js/account/accountProxyCommon.js +++ b/webapp/web/js/account/accountProxyCommon.js @@ -44,7 +44,7 @@ function itemElement(template, uri, label, classLabel, imageUrl, removeInfo) { this.uri = uri; this.label = label; this.classLabel = classLabel; - this.imageUrl = (imageUrl) ? imageUrl : imageUrl="../images/placeholders/person.thumbnail.jpg"; + this.imageUrl = imageUrl; this.removeInfo = removeInfo; this.toString = function() { diff --git a/webapp/web/js/commentForm.js b/webapp/web/js/commentForm.js index e3c3400bc..182cf9b27 100644 --- a/webapp/web/js/commentForm.js +++ b/webapp/web/js/commentForm.js @@ -6,41 +6,9 @@ function ValidateForm(formName) { errors = false; 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 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 emailStr = document.forms[formName].EmailFields.value; emailFields = emailStr.split(','); diff --git a/webapp/web/js/jquery_plugins/jquery.realperson.js b/webapp/web/js/jquery_plugins/jquery.realperson.js new file mode 100644 index 000000000..9f0c715f8 --- /dev/null +++ b/webapp/web/js/jquery_plugins/jquery.realperson.js @@ -0,0 +1,183 @@ +/* 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. */ + +(function($) { // Hide scope, no $ conflict + +var PROP_NAME = 'realPerson'; + +/* Real person manager. */ +function RealPerson() { + this._defaults = { + length: 6, // Number of characters to use + includeNumbers: false, // True to use numbers as well as letters + regenerate: 'Click to change', // Instruction text to regenerate + hashName: '{n}Hash' // Name of the hash value field to compare with, + // use {n} to substitute with the original field name + }; +} + +var CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; +var DOTS = [ + [' * ', ' * * ', ' * * ', ' * * ', ' ***** ', '* *', '* *'], + ['****** ', '* *', '* *', '****** ', '* *', '* *', '****** '], + [' ***** ', '* *', '* ', '* ', '* ', '* *', ' ***** '], + ['****** ', '* *', '* *', '* *', '* *', '* *', '****** '], + ['*******', '* ', '* ', '**** ', '* ', '* ', '*******'], + ['*******', '* ', '* ', '**** ', '* ', '* ', '* '], + [' ***** ', '* *', '* ', '* ', '* ***', '* *', ' ***** '], + ['* *', '* *', '* *', '*******', '* *', '* *', '* *'], + ['*******', ' * ', ' * ', ' * ', ' * ', ' * ', '*******'], + [' *', ' *', ' *', ' *', ' *', '* *', ' ***** '], + ['* *', '* ** ', '* ** ', '** ', '* ** ', '* ** ', '* *'], + ['* ', '* ', '* ', '* ', '* ', '* ', '*******'], + ['* *', '** **', '* * * *', '* * *', '* *', '* *', '* *'], + ['* *', '** *', '* * *', '* * *', '* * *', '* **', '* *'], + [' ***** ', '* *', '* *', '* *', '* *', '* *', ' ***** '], + ['****** ', '* *', '* *', '****** ', '* ', '* ', '* '], + [' ***** ', '* *', '* *', '* *', '* * *', '* * ', ' **** *'], + ['****** ', '* *', '* *', '****** ', '* * ', '* * ', '* *'], + [' ***** ', '* *', '* ', ' ***** ', ' *', '* *', ' ***** '], + ['*******', ' * ', ' * ', ' * ', ' * ', ' * ', ' * '], + ['* *', '* *', '* *', '* *', '* *', '* *', ' ***** '], + ['* *', '* *', ' * * ', ' * * ', ' * * ', ' * * ', ' * '], + ['* *', '* *', '* *', '* * *', '* * * *', '** **', '* *'], + ['* *', ' * * ', ' * * ', ' * ', ' * * ', ' * * ', '* *'], + ['* *', ' * * ', ' * * ', ' * ', ' * ', ' * ', ' * '], + ['*******', ' * ', ' * ', ' * ', ' * ', ' * ', '*******'], + [' *** ', ' * * ', '* *', '* *', '* *', ' * * ', ' *** '], + [' * ', ' ** ', ' * * ', ' * ', ' * ', ' * ', '*******'], + [' ***** ', '* *', ' *', ' * ', ' ** ', ' ** ', '*******'], + [' ***** ', '* *', ' *', ' ** ', ' *', '* *', ' ***** '], + [' * ', ' ** ', ' * * ', ' * * ', '*******', ' * ', ' * '], + ['*******', '* ', '****** ', ' *', ' *', '* *', ' ***** '], + [' **** ', ' * ', '* ', '****** ', '* *', '* *', ' ***** '], + ['*******', ' * ', ' * ', ' * ', ' * ', ' * ', '* '], + [' ***** ', '* *', '* *', ' ***** ', '* *', '* *', ' ***** '], + [' ***** ', '* *', '* *', ' ******', ' *', ' * ', ' **** ']]; + +$.extend(RealPerson.prototype, { + /* Class name added to elements to indicate already configured with real person. */ + markerClassName: 'hasRealPerson', + + /* Override the default settings for all real person instances. + @param settings (object) the new settings to use as defaults + @return (RealPerson) this object */ + setDefaults: function(settings) { + $.extend(this._defaults, settings || {}); + return this; + }, + + /* Attach the real person functionality to an input field. + @param target (element) the control to affect + @param settings (object) the custom options for this instance */ + _attachRealPerson: function(target, settings) { + target = $(target); + if (target.hasClass(this.markerClassName)) { + return; + } + target.addClass(this.markerClassName); + var inst = {settings: $.extend({}, this._defaults)}; + $.data(target[0], PROP_NAME, inst); + this._changeRealPerson(target, settings); + }, + + /* Reconfigure the settings for a real person control. + @param target (element) the control to affect + @param settings (object) the new options for this instance or + (string) an individual property name + @param value (any) the individual property value (omit if settings is an object) */ + _changeRealPerson: function(target, settings, value) { + target = $(target); + if (!target.hasClass(this.markerClassName)) { + return; + } + settings = settings || {}; + if (typeof settings == 'string') { + var name = settings; + settings = {}; + settings[name] = value; + } + var inst = $.data(target[0], PROP_NAME); + $.extend(inst.settings, settings); + target.prevAll('.realperson-challenge,.realperson-hash').remove().end(). + before(this._generateHTML(target, inst)); + }, + + /* Generate the additional content for this control. + @param target (jQuery) the input field + @param inst (object) the current instance settings + @return (string) the additional content */ + _generateHTML: function(target, inst) { + var text = ''; + for (var i = 0; i < inst.settings.length; i++) { + text += CHARS.charAt(Math.floor(Math.random() * + (inst.settings.includeNumbers ? 36 : 26))); + } + var html = '
'; + for (var i = 0; i < DOTS[0].length; i++) { + for (var j = 0; j < text.length; j++) { + html += DOTS[CHARS.indexOf(text.charAt(j))][i].replace(/ /g, ' ') + + '  '; + } + html += '
'; + } + html += '
' + inst.settings.regenerate + + '
'; + return html; + }, + + /* Remove the real person functionality from a control. + @param target (element) the control to affect */ + _destroyRealPerson: function(target) { + target = $(target); + if (!target.hasClass(this.markerClassName)) { + return; + } + target.removeClass(this.markerClassName). + prevAll('.realperson-challenge,.realperson-hash').remove(); + $.removeData(target[0], PROP_NAME); + }, + + /* Compute a hash value for the given text. + @param value (string) the text to hash + @return the corresponding hash value */ + _hash: function(value) { + var hash = 5381; + for (var i = 0; i < value.length; i++) { + hash = ((hash << 5) + hash) + value.charCodeAt(i); + } + return hash; + } +}); + +/* Attach the real person functionality to a jQuery selection. + @param command (string) the command to run (optional, default 'attach') + @param options (object) the new settings to use for these instances (optional) + @return (jQuery) for chaining further calls */ +$.fn.realperson = function(options) { + var otherArgs = Array.prototype.slice.call(arguments, 1); + return this.each(function() { + if (typeof options == 'string') { + $.realperson['_' + options + 'RealPerson']. + apply($.realperson, [this].concat(otherArgs)); + } + else { + $.realperson._attachRealPerson(this, options || {}); + } + }); +}; + +/* Initialise the real person functionality. */ +$.realperson = new RealPerson(); // singleton instance + +$('.realperson-challenge').live('click', function() { + $(this).next().next().realperson('change'); +}); + +})(jQuery); diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedEmail.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedEmail.ftl index ec2bb70e4..35bb89956 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedEmail.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-acctCreatedEmail.ftl @@ -19,7 +19,7 @@

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

@@ -51,8 +51,8 @@ ${userAccount.firstName} ${userAccount.lastName} Congratulations! -We have created your new VIVO account associated with -${userAccount.emailAddress}. +We have created your new account on ${siteName}, +associated with ${userAccount.emailAddress}. If you did not request this new account you can safely ignore this email. This request will expire if not acted upon for 30 days. diff --git a/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl b/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl index afc68e1ed..f2dce4cab 100644 --- a/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl +++ b/webapp/web/templates/freemarker/body/accounts/userAccounts-edit.ftl @@ -62,9 +62,12 @@ - <#include "userAccounts-associateProfilePanel.ftl"> + <#if externalAuthPermitted??> + <#include "userAccounts-associateProfilePanel.ftl"> + +

checked />Externally Authenticated Only

+ -

checked />Externally Authenticated Only

<#if roles?has_content>

Roles *

<#list roles as role> diff --git a/webapp/web/templates/freemarker/body/contactForm/contactForm-form.ftl b/webapp/web/templates/freemarker/body/contactForm/contactForm-form.ftl index db4501468..7c36a3676 100644 --- a/webapp/web/templates/freemarker/body/contactForm/contactForm-form.ftl +++ b/webapp/web/templates/freemarker/body/contactForm/contactForm-form.ftl @@ -5,11 +5,17 @@

${title}

+ <#if errorMessage?has_content> +
+

${errorMessage}

+
+ +

Thank you for your interest in ${siteName}. Please submit this form with questions, comments, or feedback about the content of this site.

-
+ @@ -17,21 +23,34 @@ - + - + - + + + +

+ +

- -
+

* required fields

-${stylesheets.add('')} -${scripts.add('')} +${stylesheets.add('', + '')} +${scripts.add('', + '', + '')} + diff --git a/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl b/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl index fced9a10d..007acbf6e 100644 --- a/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl +++ b/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl @@ -9,8 +9,7 @@ propertyGroups=propertyGroups namespaces=namespaces editable=editable - showPlaceholder="with_add_link" - placeholder="${urls.images}/placeholders/thumbnail.jpg" /> + showPlaceholder="with_add_link" /> <#if ( individualImage?contains(' diff --git a/webapp/web/templates/freemarker/body/search/search-error.ftl b/webapp/web/templates/freemarker/body/search/search-error.ftl index 381aa382f..3ede65822 100644 --- a/webapp/web/templates/freemarker/body/search/search-error.ftl +++ b/webapp/web/templates/freemarker/body/search/search-error.ftl @@ -3,7 +3,9 @@ <#-- Template for displaying search error message --> <#if title??> -

${title}

+

${title?html}

-

${message}

\ No newline at end of file +

+${message?html} +

\ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/search/search-pagedResults.ftl b/webapp/web/templates/freemarker/body/search/search-pagedResults.ftl index ba09df254..5401b0940 100644 --- a/webapp/web/templates/freemarker/body/search/search-pagedResults.ftl +++ b/webapp/web/templates/freemarker/body/search/search-pagedResults.ftl @@ -3,9 +3,11 @@ <#-- Template for displaying paged search results -->

+<#escape x as x?html> Search results for '${querytext}' <#if classGroupName?has_content>limited to type '${classGroupName}' <#if typeName?has_content>limited to type '${typeName}' +

diff --git a/webapp/web/templates/freemarker/body/siteAdmin/siteAdmin-advancedDataTools.ftl b/webapp/web/templates/freemarker/body/siteAdmin/siteAdmin-advancedDataTools.ftl index 807ce50fd..ed95a2f4e 100644 --- a/webapp/web/templates/freemarker/body/siteAdmin/siteAdmin-advancedDataTools.ftl +++ b/webapp/web/templates/freemarker/body/siteAdmin/siteAdmin-advancedDataTools.ftl @@ -7,11 +7,21 @@

Advanced Data Tools

\ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/siteAdmin/siteAdmin-indexCacheRebuild.ftl b/webapp/web/templates/freemarker/body/siteAdmin/siteAdmin-indexCacheRebuild.ftl index 97d72da42..cfe3d7554 100644 --- a/webapp/web/templates/freemarker/body/siteAdmin/siteAdmin-indexCacheRebuild.ftl +++ b/webapp/web/templates/freemarker/body/siteAdmin/siteAdmin-indexCacheRebuild.ftl @@ -6,11 +6,7 @@

Refresh Content

-
    - <#if indexCacheRebuild.rebuildClassGroupCache?has_content> -
  • Rebuild class group cache
  • - - +
      <#if indexCacheRebuild.rebuildSearchIndex?has_content>
    • Rebuild search index
    • diff --git a/webapp/web/templates/freemarker/lib/lib-properties.ftl b/webapp/web/templates/freemarker/lib/lib-properties.ftl index e6b0643d2..271473ff8 100644 --- a/webapp/web/templates/freemarker/lib/lib-properties.ftl +++ b/webapp/web/templates/freemarker/lib/lib-properties.ftl @@ -89,8 +89,8 @@ Assumes property is non-null. --> <#-- Some properties usually display without a label. But if there's an add link, we need to also show the property label. If no label is specified, the property name will be used as the label. --> -<#macro addLinkWithLabel property editable label="${property.name?capitalize}" extraParams=""> - <#local addLink><@addLink property editable label extraParams /> +<#macro addLinkWithLabel property editable label="${property.name?capitalize}"> + <#local addLink><@addLink property editable label /> <#local verboseDisplay><@verboseDisplay property /> <#-- Changed to display the label when user is in edit mode, even if there's no add link (due to displayLimitAnnot, for example). Otherwise the display looks odd, since neighboring @@ -104,24 +104,15 @@ name will be used as the label. --> -<#macro addLink property editable label="${property.name}" extraParams=""> +<#macro addLink property editable label="${property.name}"> <#if editable> <#local url = property.addUrl> <#if url?has_content> - <@showAddLink property.localName label addParamsToEditUrl(url, extraParams) /> + <@showAddLink property.localName label url /> -<#function addParamsToEditUrl url extraParams=""> - <#if extraParams?is_hash_ex> - <#list extraParams?keys as key> - <#local url = "${url}&${key}=${extraParams[key]?url}"> - - - <#return url> - - <#macro showAddLink propertyLocalName label url> add @@ -138,18 +129,18 @@ name will be used as the label. --> -<#macro editingLinks propertyLocalName statement editable extraParams=""> +<#macro editingLinks propertyLocalName statement editable> <#if editable> - <@editLink propertyLocalName statement extraParams /> - <@deleteLink propertyLocalName statement extraParams /> + <@editLink propertyLocalName statement /> + <@deleteLink propertyLocalName statement /> -<#macro editLink propertyLocalName statement extraParams=""> +<#macro editLink propertyLocalName statement> <#local url = statement.editUrl> <#if url?has_content> - <@showEditLink propertyLocalName addParamsToEditUrl(url, extraParams) /> + <@showEditLink propertyLocalName url /> @@ -157,10 +148,10 @@ name will be used as the label. --> edit -<#macro deleteLink propertyLocalName statement extraParams=""> +<#macro deleteLink propertyLocalName statement> <#local url = statement.deleteUrl> <#if url?has_content> - <@showDeleteLink propertyLocalName addParamsToEditUrl(url, extraParams) /> + <@showDeleteLink propertyLocalName url /> @@ -191,25 +182,21 @@ name will be used as the label. --> Note that this macro has a side-effect in the call to propertyGroups.pullProperty(). --> -<#macro image individual propertyGroups namespaces editable showPlaceholder="never" placeholder=""> +<#macro image individual propertyGroups namespaces editable showPlaceholder="never"> <#local mainImage = propertyGroups.pullProperty("${namespaces.vitroPublic}mainImage")!> - <#local extraParams = ""> - <#if placeholder?has_content> - <#local extraParams = { "placeholder" : placeholder } > - <#local thumbUrl = individual.thumbUrl!> <#-- Don't assume that if the mainImage property is populated, there is a thumbnail image (though that is the general case). If there's a mainImage statement but no thumbnail image, treat it as if there is no image. --> <#if (mainImage.statements)?has_content && thumbUrl?has_content> - ${individual.name} - <@editingLinks "${mainImage.localName}" mainImage.first() editable extraParams /> + + ${individual.name} + + <@editingLinks "${mainImage.localName}" mainImage.first() editable /> <#else> - <#local imageLabel><@addLinkWithLabel mainImage editable "Photo" extraParams /> + <#local imageLabel><@addLinkWithLabel mainImage editable "Photo" /> ${imageLabel} - <#if placeholder?has_content> - <#if showPlaceholder == "always" || (showPlaceholder="with_add_link" && imageLabel?has_content)> - placeholder image - + <#if showPlaceholder == "always" || (showPlaceholder="with_add_link" && imageLabel?has_content)> + placeholder image