various dev work on language filtering and querying from a generic endpoint
This commit is contained in:
commit
376c7be7c3
110 changed files with 2372 additions and 3963 deletions
|
@ -116,6 +116,16 @@ deploy - Deploy the application directly into the Tomcat webapps directory.
|
||||||
</condition>
|
</condition>
|
||||||
</fail>
|
</fail>
|
||||||
|
|
||||||
|
<fail message="The vitro.home.directory "${vitro.home.directory}" is not writable.">
|
||||||
|
<condition>
|
||||||
|
<not>
|
||||||
|
<isfileselected file="${vitro.home.directory}" >
|
||||||
|
<writable/>
|
||||||
|
</isfileselected>
|
||||||
|
</not>
|
||||||
|
</condition>
|
||||||
|
</fail>
|
||||||
|
|
||||||
<property name="solr.home.dir" location="${vitro.home.directory}/solr" />
|
<property name="solr.home.dir" location="${vitro.home.directory}/solr" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,9 @@ webapp/web/WEB-INF/tlds/taglibs-string.tld
|
||||||
webapp/web/themes/enhanced/css/blueprint/grid.css
|
webapp/web/themes/enhanced/css/blueprint/grid.css
|
||||||
webapp/web/themes/enhanced/css/blueprint/ie.css
|
webapp/web/themes/enhanced/css/blueprint/ie.css
|
||||||
|
|
||||||
|
# See /doc/3rd-party-licenses.txt for LICENSE file
|
||||||
|
webapp/web/css/jquery_plugins/jquery.realperson.css
|
||||||
|
|
||||||
# PROBLEM: Can't find any info on licensing.
|
# PROBLEM: Can't find any info on licensing.
|
||||||
webapp/web/themes/enhanced/css/blueprint/liquid.css
|
webapp/web/themes/enhanced/css/blueprint/liquid.css
|
||||||
|
|
||||||
|
|
|
@ -441,14 +441,14 @@ public class OperationController extends BaseEditController {
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
log.error(this.getClass().getName()+" encountered exception performing two-stage update");
|
log.error(this.getClass().getName()+" encountered exception performing two-stage update");
|
||||||
Throwable innerE = e.getTargetException();
|
Throwable innerE = e.getTargetException();
|
||||||
log.error(innerE);
|
log.error(innerE, innerE);
|
||||||
if (innerE.getMessage()!=null) {
|
if (innerE.getMessage()!=null) {
|
||||||
log.error(innerE.getMessage());
|
//log.error(innerE.getMessage());
|
||||||
epo.setAttribute("globalErrorMsg",innerE.getMessage());
|
epo.setAttribute("globalErrorMsg",innerE.getMessage());
|
||||||
}
|
}
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
} catch (IllegalAccessException iae) {
|
} catch (IllegalAccessException iae) {
|
||||||
log.error(iae);
|
log.error(iae, iae);
|
||||||
epo.setAttribute("globalErrorMessage", "Illegal access - see error logs.");
|
epo.setAttribute("globalErrorMessage", "Illegal access - see error logs.");
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -459,15 +459,15 @@ public class OperationController extends BaseEditController {
|
||||||
log.error(this.getClass().getName()+" encountered exception performing edit action");
|
log.error(this.getClass().getName()+" encountered exception performing edit action");
|
||||||
Throwable innerE = e.getTargetException();
|
Throwable innerE = e.getTargetException();
|
||||||
//innerE.printStackTrace();
|
//innerE.printStackTrace();
|
||||||
log.error(innerE);
|
log.error(innerE, innerE);
|
||||||
if (innerE.getMessage()!=null) {
|
if (innerE.getMessage()!=null) {
|
||||||
//System.out.println(innerE.getMessage());
|
//System.out.println(innerE.getMessage());
|
||||||
log.error(innerE.getMessage());
|
//log.error(innerE.getMessage());
|
||||||
epo.setAttribute("globalErrorMsg",innerE.getMessage());
|
epo.setAttribute("globalErrorMsg",innerE.getMessage());
|
||||||
}
|
}
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
} catch (IllegalAccessException iae) {
|
} catch (IllegalAccessException iae) {
|
||||||
log.error(iae);
|
log.error(iae, iae);
|
||||||
epo.setAttribute("globalErrorMessage", "Illegal access - see error logs.");
|
epo.setAttribute("globalErrorMessage", "Illegal access - see error logs.");
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,8 @@ public class SimplePermission extends Permission {
|
||||||
"UseMiscellaneousEditorPages");
|
"UseMiscellaneousEditorPages");
|
||||||
public static final SimplePermission USE_MISCELLANEOUS_PAGES = new SimplePermission(
|
public static final SimplePermission USE_MISCELLANEOUS_PAGES = new SimplePermission(
|
||||||
"UseMiscellaneousPages");
|
"UseMiscellaneousPages");
|
||||||
|
public static final SimplePermission USE_SPARQL_QUERY_PAGE = new SimplePermission(
|
||||||
|
"UseSparqlQueryPage");
|
||||||
|
|
||||||
public static List<SimplePermission> getAllInstances() {
|
public static List<SimplePermission> getAllInstances() {
|
||||||
return new ArrayList<SimplePermission>(allInstances.values());
|
return new ArrayList<SimplePermission>(allInstances.values());
|
||||||
|
|
|
@ -7,10 +7,6 @@ public interface ObjectPropertyStatement {
|
||||||
|
|
||||||
public String toString();
|
public String toString();
|
||||||
|
|
||||||
public boolean isSubjectOriented();
|
|
||||||
|
|
||||||
public void setSubjectOriented(boolean subjectOriented);
|
|
||||||
|
|
||||||
public String getSubjectURI();
|
public String getSubjectURI();
|
||||||
|
|
||||||
public void setSubjectURI(String subjectURI);
|
public void setSubjectURI(String subjectURI);
|
||||||
|
|
|
@ -18,9 +18,7 @@ public class ObjectPropertyStatementImpl implements ObjectPropertyStatement
|
||||||
|
|
||||||
private String propertyURI = null;
|
private String propertyURI = null;
|
||||||
private ObjectProperty property = null;
|
private ObjectProperty property = null;
|
||||||
private String qualifier = null;
|
|
||||||
private boolean subjectOriented = true; //is the range the item of interest?
|
private boolean subjectOriented = true; //is the range the item of interest?
|
||||||
private String description = null; //generated desc based on subjectOriented during sql query.
|
|
||||||
|
|
||||||
public ObjectPropertyStatementImpl() { }
|
public ObjectPropertyStatementImpl() { }
|
||||||
|
|
||||||
|
@ -37,23 +35,7 @@ public class ObjectPropertyStatementImpl implements ObjectPropertyStatement
|
||||||
String prop = (getProperty()!=null)?getProperty().getDomainPublic():"by propURI"+getPropertyURI();
|
String prop = (getProperty()!=null)?getProperty().getDomainPublic():"by propURI"+getPropertyURI();
|
||||||
String ran = (getObject()!= null)?getObject().getName():"objectURI:"+getObjectURI();
|
String ran = (getObject()!= null)?getObject().getName():"objectURI:"+getObjectURI();
|
||||||
String dom = (getSubject()!= null)?getSubject().getName():"subjectURI:"+getSubjectURI();
|
String dom = (getSubject()!= null)?getSubject().getName():"subjectURI:"+getSubjectURI();
|
||||||
String orent = (isSubjectOriented() )?"subject oriented":"object oriented";
|
return "Object Property Statements: "+dom+" "+prop+" to "+ran+" ";
|
||||||
return "Object Property Statements: "+dom+" "+prop+" to "+ran+" "+orent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement#isSubjectOriented()
|
|
||||||
*/
|
|
||||||
public boolean isSubjectOriented() {
|
|
||||||
return subjectOriented;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement#setSubjectOriented(boolean)
|
|
||||||
*/
|
|
||||||
public void setSubjectOriented(boolean subjectOriented) {
|
|
||||||
this.subjectOriented = subjectOriented;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -100,6 +82,11 @@ public class ObjectPropertyStatementImpl implements ObjectPropertyStatement
|
||||||
*/
|
*/
|
||||||
public void setSubject(Individual subject) {
|
public void setSubject(Individual subject) {
|
||||||
this.subject = subject;
|
this.subject = subject;
|
||||||
|
if (subject == null || subject.isAnonymous()) {
|
||||||
|
setSubjectURI(null);
|
||||||
|
} else {
|
||||||
|
setSubjectURI(subject.getURI());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -136,6 +123,11 @@ public class ObjectPropertyStatementImpl implements ObjectPropertyStatement
|
||||||
*/
|
*/
|
||||||
public void setObject(Individual object) {
|
public void setObject(Individual object) {
|
||||||
this.object = object;
|
this.object = object;
|
||||||
|
if (object == null || object.isAnonymous()) {
|
||||||
|
setObjectURI(null);
|
||||||
|
} else {
|
||||||
|
setObjectURI(object.getURI());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -133,8 +133,14 @@ public class VClass extends BaseResourceBean implements Comparable<VClass>
|
||||||
* Sorts alphabetically by name
|
* Sorts alphabetically by name
|
||||||
*/
|
*/
|
||||||
public int compareTo (VClass o1) {
|
public int compareTo (VClass o1) {
|
||||||
Collator collator = Collator.getInstance();
|
if (this.getName() == null) {
|
||||||
return collator.compare(this.getName(),o1.getName());
|
return 1;
|
||||||
|
} else if (o1.getName() == null) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
Collator collator = Collator.getInstance();
|
||||||
|
return collator.compare(this.getName(),o1.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -128,8 +128,6 @@ public class MailUsersServlet extends VitroHttpServlet {
|
||||||
msgBuf.append("</html>" + lineSeparator );
|
msgBuf.append("</html>" + lineSeparator );
|
||||||
|
|
||||||
String msgText = msgBuf.toString();
|
String msgText = msgBuf.toString();
|
||||||
// debugging
|
|
||||||
//PrintWriter outFile = new PrintWriter (new FileWriter(request.getSession().getServletContext().getRealPath("/WEB-INF/LatestMessage.html"),true)); //autoflush
|
|
||||||
|
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ public class SparqlQueryServlet extends BaseEditController {
|
||||||
throws ServletException, IOException
|
throws ServletException, IOException
|
||||||
{
|
{
|
||||||
if (!isAuthorizedToDisplayPage(request, response,
|
if (!isAuthorizedToDisplayPage(request, response,
|
||||||
SimplePermission.USE_ADVANCED_DATA_TOOLS_PAGES.ACTIONS)) {
|
SimplePermission.USE_SPARQL_QUERY_PAGE.ACTIONS)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import com.hp.hpl.jena.query.Dataset;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
|
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDao;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource.ModelName;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroModelSource.ModelName;
|
||||||
|
|
||||||
public class VitroRequest extends HttpServletRequestWrapper {
|
public class VitroRequest extends HttpServletRequestWrapper {
|
||||||
|
@ -78,6 +79,10 @@ public class VitroRequest extends HttpServletRequestWrapper {
|
||||||
setAttribute("jenaOntModel", ontModel);
|
setAttribute("jenaOntModel", ontModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOntModelSelector(OntModelSelector oms) {
|
||||||
|
setAttribute("ontModelSelector", oms);
|
||||||
|
}
|
||||||
|
|
||||||
/** gets assertions + inferences WebappDaoFactory with no filtering **/
|
/** gets assertions + inferences WebappDaoFactory with no filtering **/
|
||||||
public WebappDaoFactory getFullWebappDaoFactory() {
|
public WebappDaoFactory getFullWebappDaoFactory() {
|
||||||
Object webappDaoFactoryAttr = _req.getAttribute("fullWebappDaoFactory");
|
Object webappDaoFactoryAttr = _req.getAttribute("fullWebappDaoFactory");
|
||||||
|
@ -97,12 +102,26 @@ public class VitroRequest extends HttpServletRequestWrapper {
|
||||||
public WebappDaoFactory getAssertionsWebappDaoFactory() {
|
public WebappDaoFactory getAssertionsWebappDaoFactory() {
|
||||||
Object webappDaoFactoryAttr = _req.getSession().getAttribute("assertionsWebappDaoFactory");
|
Object webappDaoFactoryAttr = _req.getSession().getAttribute("assertionsWebappDaoFactory");
|
||||||
if (webappDaoFactoryAttr instanceof WebappDaoFactory) {
|
if (webappDaoFactoryAttr instanceof WebappDaoFactory) {
|
||||||
|
log.info("Returning assertionsWebappDaoFactory from session");
|
||||||
return (WebappDaoFactory) webappDaoFactoryAttr;
|
return (WebappDaoFactory) webappDaoFactoryAttr;
|
||||||
} else {
|
} else {
|
||||||
return (WebappDaoFactory) _req.getSession().getServletContext().getAttribute("assertionsWebappDaoFactory");
|
webappDaoFactoryAttr = getAttribute("assertionsWebappDaoFactory");
|
||||||
|
if (webappDaoFactoryAttr instanceof WebappDaoFactory) {
|
||||||
|
log.info("returning assertionsWebappDaoFactory from request attribute");
|
||||||
|
return (WebappDaoFactory) webappDaoFactoryAttr;
|
||||||
|
} else {
|
||||||
|
log.info("Returning assertionsWebappDaoFactory from context");
|
||||||
|
return (WebappDaoFactory) _req.getSession().getServletContext().getAttribute("assertionsWebappDaoFactory");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** gets assertions-only WebappDaoFactory with no filtering */
|
||||||
|
public void setAssertionsWebappDaoFactory(WebappDaoFactory wadf) {
|
||||||
|
setAttribute("assertionsWebappDaoFactory", wadf);
|
||||||
|
}
|
||||||
|
|
||||||
/** gets inferences-only WebappDaoFactory with no filtering */
|
/** gets inferences-only WebappDaoFactory with no filtering */
|
||||||
public WebappDaoFactory getDeductionsWebappDaoFactory() {
|
public WebappDaoFactory getDeductionsWebappDaoFactory() {
|
||||||
Object webappDaoFactoryAttr = _req.getSession().getAttribute("deductionsWebappDaoFactory");
|
Object webappDaoFactoryAttr = _req.getSession().getAttribute("deductionsWebappDaoFactory");
|
||||||
|
@ -137,6 +156,16 @@ public class VitroRequest extends HttpServletRequestWrapper {
|
||||||
return jenaOntModel;
|
return jenaOntModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OntModelSelector getOntModelSelector() {
|
||||||
|
Object o = this.getAttribute("ontModelSelector");
|
||||||
|
if (o instanceof OntModelSelector) {
|
||||||
|
return (OntModelSelector) o;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public OntModel getAssertionsOntModel() {
|
public OntModel getAssertionsOntModel() {
|
||||||
OntModel jenaOntModel = (OntModel)_req.getSession().getAttribute( JenaBaseDao.ASSERTIONS_ONT_MODEL_ATTRIBUTE_NAME );
|
OntModel jenaOntModel = (OntModel)_req.getSession().getAttribute( JenaBaseDao.ASSERTIONS_ONT_MODEL_ATTRIBUTE_NAME );
|
||||||
if ( jenaOntModel == null ) {
|
if ( jenaOntModel == null ) {
|
||||||
|
|
|
@ -35,9 +35,6 @@ public abstract class UserAccountsPage extends AbstractPageHandler {
|
||||||
|
|
||||||
private static final String PERSON_CLASS_URI = "http://xmlns.com/foaf/0.1/Person";
|
private static final String PERSON_CLASS_URI = "http://xmlns.com/foaf/0.1/Person";
|
||||||
|
|
||||||
private static final String DEFAULT_IMAGE_URL = UrlBuilder
|
|
||||||
.getUrl("/images/placeholders/person.thumbnail.jpg");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After the account is created, or the password is reset, the user has this
|
* After the account is created, or the password is reset, the user has this
|
||||||
* many days to repond to the email.
|
* many days to repond to the email.
|
||||||
|
@ -109,7 +106,6 @@ public abstract class UserAccountsPage extends AbstractPageHandler {
|
||||||
UrlBuilder.getUrl("/accounts/firstTimeExternal"));
|
UrlBuilder.getUrl("/accounts/firstTimeExternal"));
|
||||||
map.put("accountsAjax", UrlBuilder.getUrl("/accountsAjax"));
|
map.put("accountsAjax", UrlBuilder.getUrl("/accountsAjax"));
|
||||||
map.put("proxyAjax", UrlBuilder.getUrl("/proxiesAjax"));
|
map.put("proxyAjax", UrlBuilder.getUrl("/proxiesAjax"));
|
||||||
map.put("defaultImageUrl", DEFAULT_IMAGE_URL);
|
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,6 +237,7 @@ public class UserAccountsEditPage extends UserAccountsPage {
|
||||||
|
|
||||||
if (!isRootUser()) {
|
if (!isRootUser()) {
|
||||||
body.put("roles", buildListOfSelectableRoles());
|
body.put("roles", buildListOfSelectableRoles());
|
||||||
|
body.put("externalAuthPermitted", Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.put("profileTypes", buildProfileTypesList());
|
body.put("profileTypes", buildProfileTypesList());
|
||||||
|
|
|
@ -24,7 +24,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.ImageUtil;
|
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* TODO
|
||||||
|
@ -134,8 +134,8 @@ public class ManageProxiesListPage extends AbstractPageHandler {
|
||||||
private ProxyItemInfo wrapProxyItem(ProxyItemInfo item) {
|
private ProxyItemInfo wrapProxyItem(ProxyItemInfo item) {
|
||||||
String imagePath = item.getImageUrl();
|
String imagePath = item.getImageUrl();
|
||||||
if (imagePath.isEmpty()) {
|
if (imagePath.isEmpty()) {
|
||||||
imagePath = ImageUtil
|
imagePath = PlaceholderUtil.getPlaceholderImagePathForType(vreq,
|
||||||
.getPlaceholderImagePathForType(VitroVocabulary.USERACCOUNT);
|
VitroVocabulary.USERACCOUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserAccount ua = userAccountsDao.getUserAccountByUri(item.getUri());
|
UserAccount ua = userAccountsDao.getUserAccountByUri(item.getUri());
|
||||||
|
@ -151,8 +151,8 @@ public class ManageProxiesListPage extends AbstractPageHandler {
|
||||||
private ProxyItemInfo wrapProfileItem(ProxyItemInfo item) {
|
private ProxyItemInfo wrapProfileItem(ProxyItemInfo item) {
|
||||||
String imagePath = item.getImageUrl();
|
String imagePath = item.getImageUrl();
|
||||||
if (imagePath.isEmpty()) {
|
if (imagePath.isEmpty()) {
|
||||||
imagePath = ImageUtil.getPlaceholderImagePathForIndividual(vreq,
|
imagePath = PlaceholderUtil.getPlaceholderImagePathForIndividual(
|
||||||
item.getUri());
|
vreq, item.getUri());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ProfileItemWrapper(item.getUri(), item.getLabel(),
|
return new ProfileItemWrapper(item.getUri(), item.getLabel(),
|
||||||
|
|
|
@ -24,9 +24,9 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.ImageUtil;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
|
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the basic auto-complete info for the proxy selection.
|
* Get the basic auto-complete info for the proxy selection.
|
||||||
|
@ -64,8 +64,9 @@ public class BasicProxiesGetter extends AbstractAjaxResponder {
|
||||||
OntModelSelector oms = ModelContext.getUnionOntModelSelector(ctx);
|
OntModelSelector oms = ModelContext.getUnionOntModelSelector(ctx);
|
||||||
userAccountsModel = oms.getUserAccountsModel();
|
userAccountsModel = oms.getUserAccountsModel();
|
||||||
|
|
||||||
placeholderImageUrl = UrlBuilder.getUrl(ImageUtil
|
placeholderImageUrl = UrlBuilder.getUrl(PlaceholderUtil
|
||||||
.getPlaceholderImagePathForType(VitroVocabulary.USERACCOUNT));
|
.getPlaceholderImagePathForType(vreq,
|
||||||
|
VitroVocabulary.USERACCOUNT));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,7 +19,7 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.ajax.AbstractAjaxResponder;
|
import edu.cornell.mannlib.vitro.webapp.controller.ajax.AbstractAjaxResponder;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.ImageUtil;
|
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get more information (class label and image URL) about a selected proxy.
|
* Get more information (class label and image URL) about a selected proxy.
|
||||||
|
@ -79,7 +79,7 @@ public class MoreProfileInfo extends AbstractAjaxResponder {
|
||||||
private String getFullImageUrl(Individual ind) {
|
private String getFullImageUrl(Individual ind) {
|
||||||
String path = ind.getThumbUrl();
|
String path = ind.getThumbUrl();
|
||||||
if ((path == null) || path.isEmpty()) {
|
if ((path == null) || path.isEmpty()) {
|
||||||
path = ImageUtil.getPlaceholderImagePathForIndividual(vreq,
|
path = PlaceholderUtil.getPlaceholderImagePathForIndividual(vreq,
|
||||||
ind.getURI());
|
ind.getURI());
|
||||||
}
|
}
|
||||||
return UrlBuilder.getUrl(path);
|
return UrlBuilder.getUrl(path);
|
||||||
|
|
|
@ -26,6 +26,8 @@ import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the "My Account" form display and submission.
|
* Handle the "My Account" form display and submission.
|
||||||
|
@ -268,7 +270,9 @@ public class UserAccountsMyAccountPage extends UserAccountsPage {
|
||||||
String userUri = proxyUser.getUri();
|
String userUri = proxyUser.getUri();
|
||||||
String label = assembleUserAccountLabel(proxyUser);
|
String label = assembleUserAccountLabel(proxyUser);
|
||||||
String classLabel = "";
|
String classLabel = "";
|
||||||
String imageUrl = "";
|
String imageUrl = UrlBuilder.getUrl(PlaceholderUtil
|
||||||
|
.getPlaceholderImagePathForType(vreq,
|
||||||
|
VitroVocabulary.USERACCOUNT));
|
||||||
|
|
||||||
// Does this user have a profile? Can we get better info?
|
// Does this user have a profile? Can we get better info?
|
||||||
Individual proxyProfilePage = getProfilePage(proxyUser);
|
Individual proxyProfilePage = getProfilePage(proxyUser);
|
||||||
|
|
|
@ -16,7 +16,6 @@ import edu.cornell.mannlib.vedit.controller.BaseEditController;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
|
import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
||||||
|
|
||||||
public class Classes2ClassesOperationController extends BaseEditController {
|
public class Classes2ClassesOperationController extends BaseEditController {
|
||||||
|
@ -58,7 +57,6 @@ public class Classes2ClassesOperationController extends BaseEditController {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Classes2ClassesDao dao = request.getFullWebappDaoFactory().getClasses2ClassesDao();
|
|
||||||
VClassDao vcDao = request.getFullWebappDaoFactory().getVClassDao();
|
VClassDao vcDao = request.getFullWebappDaoFactory().getVClassDao();
|
||||||
|
|
||||||
String modeStr = request.getParameter("opMode");
|
String modeStr = request.getParameter("opMode");
|
||||||
|
@ -81,7 +79,7 @@ public class Classes2ClassesOperationController extends BaseEditController {
|
||||||
Classes2Classes c2c = new Classes2Classes();
|
Classes2Classes c2c = new Classes2Classes();
|
||||||
c2c.setSubclassURI(subclassURIstrs[i]);
|
c2c.setSubclassURI(subclassURIstrs[i]);
|
||||||
c2c.setSuperclassURI(superclassURIstr);
|
c2c.setSuperclassURI(superclassURIstr);
|
||||||
dao.deleteClasses2Classes(c2c);
|
vcDao.deleteClasses2Classes(c2c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +96,7 @@ public class Classes2ClassesOperationController extends BaseEditController {
|
||||||
Classes2Classes c2c = new Classes2Classes();
|
Classes2Classes c2c = new Classes2Classes();
|
||||||
c2c.setSuperclassURI(superclassURIstrs[i]);
|
c2c.setSuperclassURI(superclassURIstrs[i]);
|
||||||
c2c.setSubclassURI(subclassURIstr);
|
c2c.setSubclassURI(subclassURIstr);
|
||||||
dao.deleteClasses2Classes(c2c);
|
vcDao.deleteClasses2Classes(c2c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +110,7 @@ public class Classes2ClassesOperationController extends BaseEditController {
|
||||||
Classes2Classes c2c = new Classes2Classes();
|
Classes2Classes c2c = new Classes2Classes();
|
||||||
c2c.setSuperclassURI(request.getParameter("SuperclassURI"));
|
c2c.setSuperclassURI(request.getParameter("SuperclassURI"));
|
||||||
c2c.setSubclassURI(request.getParameter("SubclassURI"));
|
c2c.setSubclassURI(request.getParameter("SubclassURI"));
|
||||||
dao.insertNewClasses2Classes(c2c);
|
vcDao.insertNewClasses2Classes(c2c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -19,7 +19,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
|
import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
||||||
|
|
||||||
public class Classes2ClassesRetryController extends BaseEditController {
|
public class Classes2ClassesRetryController extends BaseEditController {
|
||||||
|
@ -44,9 +43,8 @@ public class Classes2ClassesRetryController extends BaseEditController {
|
||||||
action = epo.getAction();
|
action = epo.getAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
Classes2ClassesDao c2cDao = request.getFullWebappDaoFactory().getClasses2ClassesDao();
|
|
||||||
VClassDao vcDao = request.getFullWebappDaoFactory().getVClassDao();
|
VClassDao vcDao = request.getFullWebappDaoFactory().getVClassDao();
|
||||||
epo.setDataAccessObject(c2cDao);
|
epo.setDataAccessObject(vcDao);
|
||||||
Classes2Classes objectForEditing = new Classes2Classes();
|
Classes2Classes objectForEditing = new Classes2Classes();
|
||||||
|
|
||||||
String superclassURIstr = request.getParameter("SuperclassURI");
|
String superclassURIstr = request.getParameter("SuperclassURI");
|
||||||
|
|
|
@ -48,6 +48,7 @@ public class EntityEditController extends BaseEditController {
|
||||||
VitroRequest vreq = (new VitroRequest(request));
|
VitroRequest vreq = (new VitroRequest(request));
|
||||||
ApplicationBean application = vreq.getAppBean();
|
ApplicationBean application = vreq.getAppBean();
|
||||||
|
|
||||||
|
//Individual ent = vreq.getWebappDaoFactory().getIndividualDao().getIndividualByURI(entURI);
|
||||||
Individual ent = vreq.getAssertionsWebappDaoFactory().getIndividualDao().getIndividualByURI(entURI);
|
Individual ent = vreq.getAssertionsWebappDaoFactory().getIndividualDao().getIndividualByURI(entURI);
|
||||||
if (ent == null) {
|
if (ent == null) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -78,7 +78,11 @@ public class EntityRetryController extends BaseEditController {
|
||||||
action = epo.getAction();
|
action = epo.getAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
WebappDaoFactory wadf = (vreq.getAssertionsWebappDaoFactory()!=null) ? vreq.getAssertionsWebappDaoFactory() : vreq.getFullWebappDaoFactory();
|
WebappDaoFactory wadf = vreq.getAssertionsWebappDaoFactory();
|
||||||
|
if (wadf == null) {
|
||||||
|
log.info("Using vreq.getFullWebappDaoFactory()");
|
||||||
|
vreq.getFullWebappDaoFactory();
|
||||||
|
}
|
||||||
|
|
||||||
LoginStatusBean loginBean = LoginStatusBean.getBean(request);
|
LoginStatusBean loginBean = LoginStatusBean.getBean(request);
|
||||||
WebappDaoFactory myWebappDaoFactory = wadf.getUserAwareDaoFactory(loginBean.getUserURI());
|
WebappDaoFactory myWebappDaoFactory = wadf.getUserAwareDaoFactory(loginBean.getUserURI());
|
||||||
|
|
|
@ -197,7 +197,7 @@ public class VclassRetryController extends BaseEditController {
|
||||||
Classes2Classes c2c = new Classes2Classes();
|
Classes2Classes c2c = new Classes2Classes();
|
||||||
c2c.setSubclassURI(((VClass)newObj).getURI());
|
c2c.setSubclassURI(((VClass)newObj).getURI());
|
||||||
c2c.setSuperclassURI(superclassURI);
|
c2c.setSuperclassURI(superclassURI);
|
||||||
daoFactory.getClasses2ClassesDao().insertNewClasses2Classes(c2c);
|
daoFactory.getVClassDao().insertNewClasses2Classes(c2c);
|
||||||
}
|
}
|
||||||
public void doUpdated(Object oldObj, Object newObj, EditProcessObject epo) {
|
public void doUpdated(Object oldObj, Object newObj, EditProcessObject epo) {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
|
|
|
@ -198,9 +198,11 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet {
|
||||||
urls.put("ingest", UrlBuilder.getUrl("/ingest"));
|
urls.put("ingest", UrlBuilder.getUrl("/ingest"));
|
||||||
urls.put("rdfData", UrlBuilder.getUrl("/uploadRDFForm"));
|
urls.put("rdfData", UrlBuilder.getUrl("/uploadRDFForm"));
|
||||||
urls.put("rdfExport", UrlBuilder.getUrl("/export"));
|
urls.put("rdfExport", UrlBuilder.getUrl("/export"));
|
||||||
urls.put("sparqlQuery", UrlBuilder.getUrl("/admin/sparqlquery"));
|
|
||||||
urls.put("sparqlQueryBuilder", UrlBuilder.getUrl("/admin/sparqlquerybuilder"));
|
urls.put("sparqlQueryBuilder", UrlBuilder.getUrl("/admin/sparqlquerybuilder"));
|
||||||
}
|
}
|
||||||
|
if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.USE_SPARQL_QUERY_PAGE.ACTIONS)) {
|
||||||
|
urls.put("sparqlQuery", UrlBuilder.getUrl("/admin/sparqlquery"));
|
||||||
|
}
|
||||||
|
|
||||||
return urls;
|
return urls;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
|
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
@ -25,6 +26,7 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
|
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||||
|
@ -38,7 +40,6 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final static String SPAM_MESSAGE = "Your message was flagged as spam.";
|
private final static String SPAM_MESSAGE = "Your message was flagged as spam.";
|
||||||
private final static String EMAIL_BACKUP_FILE_PATH = "/WEB-INF/LatestMessage.html";
|
|
||||||
|
|
||||||
private final static String WEB_USERNAME_PARAM = "webusername";
|
private final static String WEB_USERNAME_PARAM = "webusername";
|
||||||
private final static String WEB_USEREMAIL_PARAM = "webuseremail";
|
private final static String WEB_USEREMAIL_PARAM = "webuseremail";
|
||||||
|
@ -48,6 +49,11 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
private final static String TEMPLATE_EMAIL = "contactForm-email.ftl";
|
private final static String TEMPLATE_EMAIL = "contactForm-email.ftl";
|
||||||
private final static String TEMPLATE_BACKUP = "contactForm-backup.ftl";
|
private final static String TEMPLATE_BACKUP = "contactForm-backup.ftl";
|
||||||
private final static String TEMPLATE_ERROR = "contactForm-error.ftl";
|
private final static String TEMPLATE_ERROR = "contactForm-error.ftl";
|
||||||
|
private final static String TEMPLATE_FORM = "contactForm-form.ftl";
|
||||||
|
|
||||||
|
private static final String PROPERTY_VITRO_HOME_DIR = "vitro.home.directory";
|
||||||
|
private static final String EMAIL_JOURNAL_FILE_DIR = "emailJournal";
|
||||||
|
private static final String EMAIL_JOURNAL_FILE_NAME = "contactFormEmails.html";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getTitle(String siteName, VitroRequest vreq) {
|
protected String getTitle(String siteName, VitroRequest vreq) {
|
||||||
|
@ -70,9 +76,13 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
String webuseremail = nonNullAndTrim(vreq, WEB_USEREMAIL_PARAM);
|
String webuseremail = nonNullAndTrim(vreq, WEB_USEREMAIL_PARAM);
|
||||||
String comments = nonNullAndTrim(vreq, COMMENTS_PARAM);
|
String comments = nonNullAndTrim(vreq, COMMENTS_PARAM);
|
||||||
String formType = nonNullAndTrim(vreq, "DeliveryType");
|
String formType = nonNullAndTrim(vreq, "DeliveryType");
|
||||||
|
String captchaInput = nonNullAndTrim(vreq, "defaultReal");
|
||||||
|
String captchaDisplay = nonNullAndTrim(vreq, "defaultRealHash");
|
||||||
|
|
||||||
if (validateInput(webusername, webuseremail, comments) != null) {
|
String errorMsg = validateInput(webusername, webuseremail, comments, captchaInput, captchaDisplay);
|
||||||
return errorParametersNotValid();
|
|
||||||
|
if ( errorMsg != null) {
|
||||||
|
return errorParametersNotValid(errorMsg, webusername, webuseremail, comments);
|
||||||
}
|
}
|
||||||
|
|
||||||
String spamReason = checkForSpam(comments, formType);
|
String spamReason = checkForSpam(comments, formType);
|
||||||
|
@ -107,14 +117,14 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
deliveryfrom, originalReferer, vreq.getRemoteAddr(), config, vreq);
|
deliveryfrom, originalReferer, vreq.getRemoteAddr(), config, vreq);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Write the email to a backup file
|
// Write the message to the journal file
|
||||||
FileWriter fw = new FileWriter(getServletContext().getRealPath(EMAIL_BACKUP_FILE_PATH),true);
|
FileWriter fw = new FileWriter(locateTheJournalFile(vreq),true);
|
||||||
PrintWriter outFile = new PrintWriter(fw);
|
PrintWriter outFile = new PrintWriter(fw);
|
||||||
writeBackupCopy(outFile, msgText, config, vreq);
|
writeBackupCopy(outFile, msgText, config, vreq);
|
||||||
|
|
||||||
Session s = FreemarkerEmailFactory.getEmailSession(vreq);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Send the message
|
||||||
|
Session s = FreemarkerEmailFactory.getEmailSession(vreq);
|
||||||
sendMessage(s, webuseremail, webusername, recipients, deliveryfrom, msgText);
|
sendMessage(s, webuseremail, webusername, recipients, deliveryfrom, msgText);
|
||||||
} catch (AddressException e) {
|
} catch (AddressException e) {
|
||||||
statusMsg = "Please supply a valid email address.";
|
statusMsg = "Please supply a valid email address.";
|
||||||
|
@ -147,6 +157,40 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The journal file belongs in a sub-directory of the Vitro home directory.
|
||||||
|
* If the sub-directory doesn't exist, create it.
|
||||||
|
*/
|
||||||
|
private File locateTheJournalFile(VitroRequest vreq) {
|
||||||
|
String homeDirPath = ConfigurationProperties.getBean(vreq).getProperty(
|
||||||
|
PROPERTY_VITRO_HOME_DIR);
|
||||||
|
if (homeDirPath == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Configuration properties must contain a value for '"
|
||||||
|
+ PROPERTY_VITRO_HOME_DIR + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
File homeDir = new File(homeDirPath);
|
||||||
|
if (!homeDir.exists()) {
|
||||||
|
throw new IllegalStateException("Vitro home directory '"
|
||||||
|
+ homeDir.getAbsolutePath() + "' does not exist.");
|
||||||
|
}
|
||||||
|
|
||||||
|
File journalDir = new File(homeDir, EMAIL_JOURNAL_FILE_DIR);
|
||||||
|
if (!journalDir.exists()) {
|
||||||
|
boolean created = journalDir.mkdir();
|
||||||
|
if (!created) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Unable to create email journal directory at '"
|
||||||
|
+ journalDir + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File journalFile = new File(journalDir, EMAIL_JOURNAL_FILE_NAME);
|
||||||
|
return journalFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private String getOriginalRefererFromSession(VitroRequest vreq) {
|
private String getOriginalRefererFromSession(VitroRequest vreq) {
|
||||||
String originalReferer = (String) vreq.getSession().getAttribute("contactFormReferer");
|
String originalReferer = (String) vreq.getSession().getAttribute("contactFormReferer");
|
||||||
if (originalReferer != null) {
|
if (originalReferer != null) {
|
||||||
|
@ -263,20 +307,28 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String validateInput(String webusername, String webuseremail,
|
private String validateInput(String webusername, String webuseremail,
|
||||||
String comments) {
|
String comments, String captchaInput, String captchaDisplay) {
|
||||||
|
|
||||||
if( webusername.isEmpty() ){
|
if( webusername.isEmpty() ){
|
||||||
return "A proper webusername field was not found in the form submitted.";
|
return "Please enter a value in the Full name field.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if( webuseremail.isEmpty() ){
|
if( webuseremail.isEmpty() ){
|
||||||
return "A proper webuser email field was not found in the form submitted.";
|
return "Please enter a valid email address.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comments.isEmpty()) {
|
if (comments.isEmpty()) {
|
||||||
return "The proper comments field was not found in the form submitted.";
|
return "Please enter your comments or questions in the space provided.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (captchaInput.isEmpty()) {
|
||||||
|
return "Please enter the contents of the gray box in the security field provided.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !captchaHash(captchaInput).equals(captchaDisplay) ) {
|
||||||
|
return "The value you entered in the security field did not match the letters displayed in the gray box.";
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,6 +360,15 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String captchaHash(String value) {
|
||||||
|
int hash = 5381;
|
||||||
|
value = value.toUpperCase();
|
||||||
|
for(int i = 0; i < value.length(); i++) {
|
||||||
|
hash = ((hash << 5) + hash) + value.charAt(i);
|
||||||
|
}
|
||||||
|
return String.valueOf(hash);
|
||||||
|
}
|
||||||
|
|
||||||
private ResponseValues errorNoSmtpServer() {
|
private ResponseValues errorNoSmtpServer() {
|
||||||
Map<String, Object> body = new HashMap<String, Object>();
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
body.put("errorMessage",
|
body.put("errorMessage",
|
||||||
|
@ -324,11 +385,14 @@ public class ContactMailController extends FreemarkerHttpServlet {
|
||||||
return new TemplateResponseValues(TEMPLATE_ERROR, body);
|
return new TemplateResponseValues(TEMPLATE_ERROR, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseValues errorParametersNotValid() {
|
private ResponseValues errorParametersNotValid(String errorMsg, String webusername, String webuseremail, String comments) {
|
||||||
// rjy7 We should reload the form, not go to the error page!
|
|
||||||
Map<String, Object> body = new HashMap<String, Object>();
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
body.put("errorMessage", "Invalid submission");
|
body.put("errorMessage", errorMsg);
|
||||||
return new TemplateResponseValues(TEMPLATE_ERROR, body);
|
body.put("formAction", "submitFeedback");
|
||||||
|
body.put("webusername", webusername);
|
||||||
|
body.put("webuseremail", webuseremail);
|
||||||
|
body.put("comments", comments);
|
||||||
|
return new TemplateResponseValues(TEMPLATE_FORM, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseValues errorSpam() {
|
private ResponseValues errorSpam() {
|
||||||
|
|
|
@ -19,6 +19,10 @@ import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean;
|
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfigurationConstants;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualLocalNameMethod;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualPlaceholderImageUrlMethod;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.methods.IndividualProfileUrlMethod;
|
||||||
import freemarker.cache.ClassTemplateLoader;
|
import freemarker.cache.ClassTemplateLoader;
|
||||||
import freemarker.cache.FileTemplateLoader;
|
import freemarker.cache.FileTemplateLoader;
|
||||||
import freemarker.cache.MultiTemplateLoader;
|
import freemarker.cache.MultiTemplateLoader;
|
||||||
|
@ -108,6 +112,9 @@ public class FreemarkerConfiguration extends Configuration {
|
||||||
sharedVariables.putAll(getMethods());
|
sharedVariables.putAll(getMethods());
|
||||||
sharedVariables.put("siteTagline", appBean.getShortHand());
|
sharedVariables.put("siteTagline", appBean.getShortHand());
|
||||||
|
|
||||||
|
//Put in edit configuration constants - useful for freemarker templates/editing
|
||||||
|
sharedVariables.put("editConfigurationConstants", EditConfigurationConstants.exportConstants());
|
||||||
|
|
||||||
for ( Map.Entry<String, Object> variable : sharedVariables.entrySet() ) {
|
for ( Map.Entry<String, Object> variable : sharedVariables.entrySet() ) {
|
||||||
try {
|
try {
|
||||||
setSharedVariable(variable.getKey(), variable.getValue());
|
setSharedVariable(variable.getKey(), variable.getValue());
|
||||||
|
@ -156,8 +163,9 @@ public class FreemarkerConfiguration extends Configuration {
|
||||||
|
|
||||||
public static Map<String, Object> getMethods() {
|
public static Map<String, Object> getMethods() {
|
||||||
Map<String, Object> map = new HashMap<String, Object>();
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
map.put("profileUrl", new edu.cornell.mannlib.vitro.webapp.web.methods.IndividualProfileUrlMethod());
|
map.put("profileUrl", new IndividualProfileUrlMethod());
|
||||||
map.put("localName", new edu.cornell.mannlib.vitro.webapp.web.methods.IndividualLocalNameMethod());
|
map.put("localName", new IndividualLocalNameMethod());
|
||||||
|
map.put("placeholderImageUrl", new IndividualPlaceholderImageUrlMethod());
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -338,42 +338,38 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
||||||
return appBean.getThemeDir().replaceAll("/$", "");
|
return appBean.getThemeDir().replaceAll("/$", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define the request-specific URLs that are accessible to the templates.
|
* Define the request-specific URLs that are accessible to the templates.
|
||||||
* @param VitroRequest vreq
|
* Merge it with the context-specific URLs from the configuration, because
|
||||||
*/
|
* this map will mask that one.
|
||||||
private void setRequestUrls(VitroRequest vreq) {
|
*/
|
||||||
|
private Map<String, Object> buildRequestUrls(VitroRequest vreq) {
|
||||||
|
Map<String, Object> requestUrls = new HashMap<String, Object>();
|
||||||
|
|
||||||
FreemarkerConfiguration config = (FreemarkerConfiguration)vreq.getAttribute("freemarkerConfig");
|
FreemarkerConfiguration config = (FreemarkerConfiguration)vreq.getAttribute("freemarkerConfig");
|
||||||
TemplateModel urlModel = config.getSharedVariable("urls");
|
TemplateModel urlModel = config.getSharedVariable("urls");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Map<String, Object> urls = (Map<String, Object>) DeepUnwrap.permissiveUnwrap(urlModel);
|
Map<String, Object> configUrls = (Map<String, Object>) DeepUnwrap.permissiveUnwrap(urlModel);
|
||||||
|
requestUrls.putAll(configUrls);
|
||||||
|
|
||||||
// This is request-specific because email can be configured
|
// This is request-specific because email can be configured
|
||||||
// and de-configured in the application interface.
|
// and de-configured in the application interface.
|
||||||
if (FreemarkerEmailFactory.isConfigured(vreq)) {
|
if (FreemarkerEmailFactory.isConfigured(vreq)) {
|
||||||
urls.put("contact", UrlBuilder.getUrl(Route.CONTACT));
|
requestUrls.put("contact", UrlBuilder.getUrl(Route.CONTACT));
|
||||||
} else {
|
|
||||||
urls.remove("contact"); // clear value from a previous request
|
|
||||||
}
|
}
|
||||||
|
|
||||||
urls.put("currentPage", getCurrentPageUrl(vreq));
|
requestUrls.put("currentPage", getCurrentPageUrl(vreq));
|
||||||
urls.put("referringPage", getReferringPageUrl(vreq));
|
requestUrls.put("referringPage", getReferringPageUrl(vreq));
|
||||||
|
|
||||||
if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.EDIT_OWN_ACCOUNT.ACTIONS)) {
|
if (PolicyHelper.isAuthorizedForActions(vreq, SimplePermission.EDIT_OWN_ACCOUNT.ACTIONS)) {
|
||||||
urls.put("myAccount", UrlBuilder.getUrl("/accounts/myAccount"));
|
requestUrls.put("myAccount", UrlBuilder.getUrl("/accounts/myAccount"));
|
||||||
} else {
|
|
||||||
urls.remove("myAccount"); // clear value from a previous request
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.setSharedVariable("urls", urls);
|
|
||||||
|
|
||||||
} catch (TemplateModelException e) {
|
} catch (TemplateModelException e) {
|
||||||
log.error(e, e);
|
log.error(e, e);
|
||||||
}
|
}
|
||||||
|
return requestUrls;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCurrentPageUrl(HttpServletRequest request) {
|
private String getCurrentPageUrl(HttpServletRequest request) {
|
||||||
|
@ -424,7 +420,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
||||||
// This may be overridden by the body data model received from the subcontroller.
|
// This may be overridden by the body data model received from the subcontroller.
|
||||||
map.put("title", getTitle(vreq.getAppBean().getApplicationName(), vreq));
|
map.put("title", getTitle(vreq.getAppBean().getApplicationName(), vreq));
|
||||||
|
|
||||||
setRequestUrls(vreq);
|
map.put("urls", buildRequestUrls(vreq));
|
||||||
|
|
||||||
map.put("menu", getDisplayModelMenu(vreq));
|
map.put("menu", getDisplayModelMenu(vreq));
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo;
|
import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo;
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest;
|
import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle adding, replacing or deleting the main image on an Individual.
|
* Handle adding, replacing or deleting the main image on an Individual.
|
||||||
|
@ -63,12 +64,6 @@ public class ImageUploadController extends FreemarkerHttpServlet {
|
||||||
/** The form field of the uploaded file; use as a key to the FileItem map. */
|
/** The form field of the uploaded file; use as a key to the FileItem map. */
|
||||||
public static final String PARAMETER_UPLOADED_FILE = "datafile";
|
public static final String PARAMETER_UPLOADED_FILE = "datafile";
|
||||||
|
|
||||||
/**
|
|
||||||
* The image to use as a placeholder when the individual has no image.
|
|
||||||
* Determined by the template.
|
|
||||||
*/
|
|
||||||
public static final String PARAMETER_PLACEHOLDER_URL = "placeholder";
|
|
||||||
|
|
||||||
/** Here is the main image file. Hold on to it. */
|
/** Here is the main image file. Hold on to it. */
|
||||||
public static final String ACTION_UPLOAD = "upload";
|
public static final String ACTION_UPLOAD = "upload";
|
||||||
|
|
||||||
|
@ -141,7 +136,8 @@ public class ImageUploadController extends FreemarkerHttpServlet {
|
||||||
String imageUri = entity.getMainImageUri();
|
String imageUri = entity.getMainImageUri();
|
||||||
|
|
||||||
RequestedAction ra;
|
RequestedAction ra;
|
||||||
if (ACTION_DELETE.equals(action) || ACTION_DELETE_EDIT.equals(action)) {
|
if (ACTION_DELETE.equals(action)
|
||||||
|
|| ACTION_DELETE_EDIT.equals(action)) {
|
||||||
ra = new DropObjectPropStmt(entity.getURI(),
|
ra = new DropObjectPropStmt(entity.getURI(),
|
||||||
VitroVocabulary.IND_MAIN_IMAGE, imageUri);
|
VitroVocabulary.IND_MAIN_IMAGE, imageUri);
|
||||||
} else if (imageUri != null) {
|
} else if (imageUri != null) {
|
||||||
|
@ -405,12 +401,13 @@ public class ImageUploadController extends FreemarkerHttpServlet {
|
||||||
private TemplateResponseValues showAddImagePage(VitroRequest vreq,
|
private TemplateResponseValues showAddImagePage(VitroRequest vreq,
|
||||||
Individual entity) {
|
Individual entity) {
|
||||||
|
|
||||||
String placeholderUrl = vreq.getParameter(PARAMETER_PLACEHOLDER_URL);
|
|
||||||
|
|
||||||
String formAction = (entity == null) ? "" : formAction(entity.getURI(),
|
String formAction = (entity == null) ? "" : formAction(entity.getURI(),
|
||||||
ACTION_UPLOAD, placeholderUrl);
|
ACTION_UPLOAD);
|
||||||
String cancelUrl = (entity == null) ? "" : exitPageUrl(vreq,
|
String cancelUrl = (entity == null) ? "" : exitPageUrl(vreq,
|
||||||
entity.getURI());
|
entity.getURI());
|
||||||
|
String placeholderUrl = (entity == null) ? "" : UrlBuilder
|
||||||
|
.getUrl(PlaceholderUtil.getPlaceholderImagePathForIndividual(
|
||||||
|
vreq, entity.getURI()));
|
||||||
|
|
||||||
TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_NEW);
|
TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_NEW);
|
||||||
|
|
||||||
|
@ -437,12 +434,11 @@ public class ImageUploadController extends FreemarkerHttpServlet {
|
||||||
*/
|
*/
|
||||||
private TemplateResponseValues showReplaceImagePage(VitroRequest vreq,
|
private TemplateResponseValues showReplaceImagePage(VitroRequest vreq,
|
||||||
Individual entity, ImageInfo imageInfo) {
|
Individual entity, ImageInfo imageInfo) {
|
||||||
String placeholderUrl = vreq.getParameter(PARAMETER_PLACEHOLDER_URL);
|
|
||||||
TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_REPLACE);
|
TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_REPLACE);
|
||||||
rv.put(BODY_THUMBNAIL_URL, UrlBuilder.getUrl(imageInfo.getThumbnail()
|
rv.put(BODY_THUMBNAIL_URL, UrlBuilder.getUrl(imageInfo.getThumbnail()
|
||||||
.getBytestreamAliasUrl()));
|
.getBytestreamAliasUrl()));
|
||||||
rv.put(BODY_DELETE_URL, formAction(entity.getURI(), ACTION_DELETE_EDIT, placeholderUrl));
|
rv.put(BODY_DELETE_URL, formAction(entity.getURI(), ACTION_DELETE_EDIT));
|
||||||
rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_UPLOAD, placeholderUrl));
|
rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_UPLOAD));
|
||||||
rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI()));
|
rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI()));
|
||||||
rv.put(BODY_TITLE, "Replace image" + forName(entity));
|
rv.put(BODY_TITLE, "Replace image" + forName(entity));
|
||||||
rv.put(BODY_MAX_FILE_SIZE, MAXIMUM_FILE_SIZE / (1024 * 1024));
|
rv.put(BODY_MAX_FILE_SIZE, MAXIMUM_FILE_SIZE / (1024 * 1024));
|
||||||
|
@ -468,12 +464,11 @@ public class ImageUploadController extends FreemarkerHttpServlet {
|
||||||
*/
|
*/
|
||||||
private TemplateResponseValues showCropImagePage(VitroRequest vreq,
|
private TemplateResponseValues showCropImagePage(VitroRequest vreq,
|
||||||
Individual entity, String imageUrl, Dimensions dimensions) {
|
Individual entity, String imageUrl, Dimensions dimensions) {
|
||||||
String placeholderUrl = vreq.getParameter(PARAMETER_PLACEHOLDER_URL);
|
|
||||||
TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_CROP);
|
TemplateResponseValues rv = new TemplateResponseValues(TEMPLATE_CROP);
|
||||||
rv.put(BODY_MAIN_IMAGE_URL, UrlBuilder.getUrl(imageUrl));
|
rv.put(BODY_MAIN_IMAGE_URL, UrlBuilder.getUrl(imageUrl));
|
||||||
rv.put(BODY_MAIN_IMAGE_HEIGHT, dimensions.height);
|
rv.put(BODY_MAIN_IMAGE_HEIGHT, dimensions.height);
|
||||||
rv.put(BODY_MAIN_IMAGE_WIDTH, dimensions.width);
|
rv.put(BODY_MAIN_IMAGE_WIDTH, dimensions.width);
|
||||||
rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_SAVE, placeholderUrl));
|
rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_SAVE));
|
||||||
rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI()));
|
rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI()));
|
||||||
rv.put(BODY_TITLE, "Crop Photo" + forName(entity));
|
rv.put(BODY_TITLE, "Crop Photo" + forName(entity));
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -518,11 +513,9 @@ public class ImageUploadController extends FreemarkerHttpServlet {
|
||||||
* back to this controller, along with the desired action and the Entity
|
* back to this controller, along with the desired action and the Entity
|
||||||
* URI.
|
* URI.
|
||||||
*/
|
*/
|
||||||
private String formAction(String entityUri, String action,
|
private String formAction(String entityUri, String action) {
|
||||||
String placeholderUrl) {
|
ParamMap params = new ParamMap(PARAMETER_ENTITY_URI, entityUri,
|
||||||
ParamMap params = new ParamMap(
|
PARAMETER_ACTION, action);
|
||||||
PARAMETER_ENTITY_URI, entityUri, PARAMETER_ACTION, action,
|
|
||||||
PARAMETER_PLACEHOLDER_URL, placeholderUrl);
|
|
||||||
return UrlBuilder.getPath(URL_HERE, params);
|
return UrlBuilder.getPath(URL_HERE, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
||||||
}
|
|
|
@ -4,6 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.dao;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
|
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
|
||||||
|
|
||||||
|
@ -67,6 +68,10 @@ public interface VClassDao {
|
||||||
|
|
||||||
void addVClassesToGroup(VClassGroup group);
|
void addVClassesToGroup(VClassGroup group);
|
||||||
|
|
||||||
|
void insertNewClasses2Classes(Classes2Classes c2c);
|
||||||
|
|
||||||
|
void deleteClasses2Classes(Classes2Classes c2c);
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedClasses);/* (non-Javadoc)
|
void addVClassesToGroup(VClassGroup group, boolean includeUninstantiatedClasses);/* (non-Javadoc)
|
||||||
* @see edu.cornell.mannlib.vitro.webapp.dao.db.VClassDao#addVClassesToGroups(java.util.List)
|
* @see edu.cornell.mannlib.vitro.webapp.dao.db.VClassDao#addVClassesToGroups(java.util.List)
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
package edu.cornell.mannlib.vitro.webapp.dao;
|
package edu.cornell.mannlib.vitro.webapp.dao;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public interface WebappDaoFactory {
|
public interface WebappDaoFactory {
|
||||||
|
@ -13,12 +12,6 @@ public interface WebappDaoFactory {
|
||||||
*/
|
*/
|
||||||
public void close();
|
public void close();
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a map containing arbitrary key-value pairs describing this
|
|
||||||
* WebappDaoFactory
|
|
||||||
*/
|
|
||||||
public Map<String,String> getProperties();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks a URI String for two things: well-formedness and uniqueness in the
|
* Checks a URI String for two things: well-formedness and uniqueness in the
|
||||||
* model. Ill-formed strings or those matching URIs already in use will
|
* model. Ill-formed strings or those matching URIs already in use will
|
||||||
|
@ -39,7 +32,7 @@ public interface WebappDaoFactory {
|
||||||
|
|
||||||
public Set<String> getNonuserNamespaces();
|
public Set<String> getNonuserNamespaces();
|
||||||
|
|
||||||
public String[] getPreferredLanguages();
|
public List<String> getPreferredLanguages();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BJL23 2008-05-20: Putting this here for lack of a more logical place.
|
* BJL23 2008-05-20: Putting this here for lack of a more logical place.
|
||||||
|
@ -66,11 +59,6 @@ public interface WebappDaoFactory {
|
||||||
|
|
||||||
/* =============== DAOs for ontology (TBox) manipulation =============== */
|
/* =============== DAOs for ontology (TBox) manipulation =============== */
|
||||||
|
|
||||||
/**
|
|
||||||
* returns a Data Access Object for working with class subsumption axioms
|
|
||||||
*/
|
|
||||||
public Classes2ClassesDao getClasses2ClassesDao();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns a Data Access Object for working with DataProperties
|
* returns a Data Access Object for working with DataProperties
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,30 +2,29 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.dao;
|
package edu.cornell.mannlib.vitro.webapp.dao;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class WebappDaoFactoryConfig {
|
public class WebappDaoFactoryConfig {
|
||||||
|
|
||||||
private String[] preferredLanguages;
|
private List<String> preferredLanguages;
|
||||||
private String defaultNamespace;
|
private String defaultNamespace;
|
||||||
private Set<String> nonUserNamespaces;
|
private Set<String> nonUserNamespaces;
|
||||||
|
|
||||||
public WebappDaoFactoryConfig() {
|
public WebappDaoFactoryConfig() {
|
||||||
preferredLanguages = new String[3];
|
preferredLanguages = Arrays.asList("en-US", "en", "EN");
|
||||||
preferredLanguages[0] = "en-US";
|
|
||||||
preferredLanguages[1] = "en";
|
|
||||||
preferredLanguages[2] = "EN";
|
|
||||||
defaultNamespace = "http://vitro.mannlib.cornell.edu/ns/default#";
|
defaultNamespace = "http://vitro.mannlib.cornell.edu/ns/default#";
|
||||||
nonUserNamespaces = new HashSet<String>();
|
nonUserNamespaces = new HashSet<String>();
|
||||||
nonUserNamespaces.add(VitroVocabulary.vitroURI);
|
nonUserNamespaces.add(VitroVocabulary.vitroURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getPreferredLanguages() {
|
public List<String> getPreferredLanguages() {
|
||||||
return this.preferredLanguages;
|
return this.preferredLanguages;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPreferredLanguages(String[] pl) {
|
public void setPreferredLanguages(List<String> pl) {
|
||||||
this.preferredLanguages = pl;
|
this.preferredLanguages = pl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,10 +56,6 @@ public class ObjectPropertyStatementFiltering implements ObjectPropertyStatement
|
||||||
return innerStmt.getSubjectURI();
|
return innerStmt.getSubjectURI();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSubjectOriented() {
|
|
||||||
return innerStmt.isSubjectOriented();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setObject(Individual object) {
|
public void setObject(Individual object) {
|
||||||
innerStmt.setObject(object);
|
innerStmt.setObject(object);
|
||||||
}
|
}
|
||||||
|
@ -80,10 +76,6 @@ public class ObjectPropertyStatementFiltering implements ObjectPropertyStatement
|
||||||
innerStmt.setSubject(subject);
|
innerStmt.setSubject(subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSubjectOriented(boolean subjectOriented) {
|
|
||||||
innerStmt.setSubjectOriented(subjectOriented);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSubjectURI(String subjectURI) {
|
public void setSubjectURI(String subjectURI) {
|
||||||
innerStmt.setSubjectURI(subjectURI);
|
innerStmt.setSubjectURI(subjectURI);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
||||||
import net.sf.jga.algorithms.Filter;
|
import net.sf.jga.algorithms.Filter;
|
||||||
import net.sf.jga.fn.UnaryFunctor;
|
import net.sf.jga.fn.UnaryFunctor;
|
||||||
import net.sf.jga.fn.property.GetProperty;
|
import net.sf.jga.fn.property.GetProperty;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Classes2Classes;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
|
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
|
||||||
|
@ -240,6 +241,14 @@ public class VClassDaoFiltering extends BaseFiltering implements VClassDao{
|
||||||
return innerVClassDao.getBottomConcept();
|
return innerVClassDao.getBottomConcept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void insertNewClasses2Classes(Classes2Classes c2c) {
|
||||||
|
innerVClassDao.insertNewClasses2Classes(c2c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteClasses2Classes(Classes2Classes c2c) {
|
||||||
|
innerVClassDao.deleteClasses2Classes(c2c);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isSubClassOf(VClass vc1, VClass vc2) {
|
public boolean isSubClassOf(VClass vc1, VClass vc2) {
|
||||||
return innerVClassDao.isSubClassOf(vc1, vc2);
|
return innerVClassDao.isSubClassOf(vc1, vc2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
|
||||||
|
@ -76,10 +75,6 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory {
|
||||||
|
|
||||||
/* ******************* filtering *********************** */
|
/* ******************* filtering *********************** */
|
||||||
|
|
||||||
public Map<String,String> getProperties() {
|
|
||||||
return innerWebappDaoFactory.getProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String checkURI(String uriStr) {
|
public String checkURI(String uriStr) {
|
||||||
return innerWebappDaoFactory.checkURI(uriStr);
|
return innerWebappDaoFactory.checkURI(uriStr);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +96,7 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory {
|
||||||
return innerWebappDaoFactory.getNonuserNamespaces();
|
return innerWebappDaoFactory.getNonuserNamespaces();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getPreferredLanguages() {
|
public List<String> getPreferredLanguages() {
|
||||||
return innerWebappDaoFactory.getPreferredLanguages();
|
return innerWebappDaoFactory.getPreferredLanguages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,10 +163,6 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory {
|
||||||
|
|
||||||
/* ******************* non-filtering DAOs *************************** */
|
/* ******************* non-filtering DAOs *************************** */
|
||||||
|
|
||||||
public Classes2ClassesDao getClasses2ClassesDao() {
|
|
||||||
return innerWebappDaoFactory.getClasses2ClassesDao();
|
|
||||||
}
|
|
||||||
|
|
||||||
public DatatypeDao getDatatypeDao() {
|
public DatatypeDao getDatatypeDao() {
|
||||||
return innerWebappDaoFactory.getDatatypeDao();
|
return innerWebappDaoFactory.getDatatypeDao();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -43,17 +43,17 @@ public class EmptyReifier implements Reifier {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExtendedIterator<Triple> find(TripleMatch arg0) {
|
public ExtendedIterator<Triple> find(TripleMatch arg0) {
|
||||||
return WrappedIterator.create(Collections.EMPTY_LIST.iterator());
|
return g.find(arg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExtendedIterator<Triple> findEither(TripleMatch arg0, boolean arg1) {
|
public ExtendedIterator<Triple> findEither(TripleMatch arg0, boolean arg1) {
|
||||||
return WrappedIterator.create(Collections.EMPTY_LIST.iterator());
|
return find(arg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExtendedIterator<Triple> findExposed(TripleMatch arg0) {
|
public ExtendedIterator<Triple> findExposed(TripleMatch arg0) {
|
||||||
return WrappedIterator.create(Collections.EMPTY_LIST.iterator());
|
return find(arg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -68,14 +68,14 @@ public class EmptyReifier implements Reifier {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handledAdd(Triple arg0) {
|
public boolean handledAdd(Triple arg0) {
|
||||||
// TODO Auto-generated method stub
|
g.add(arg0);
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handledRemove(Triple arg0) {
|
public boolean handledRemove(Triple arg0) {
|
||||||
// TODO Auto-generated method stub
|
g.delete(arg0);
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -98,20 +98,17 @@ public class EmptyReifier implements Reifier {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(Triple arg0) {
|
public void remove(Triple arg0) {
|
||||||
// TODO Auto-generated method stub
|
g.delete(arg0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(Node arg0, Triple arg1) {
|
public void remove(Node arg0, Triple arg1) {
|
||||||
// TODO Auto-generated method stub
|
g.delete(arg1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
// TODO Auto-generated method stub
|
return g.size();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,9 +187,10 @@ public class IndividualDaoSDB extends IndividualDaoJena {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (uri != null && !uri.equals(currRes.getURI())) {
|
if (uri != null && !uri.equals(currRes.getURI())) {
|
||||||
Individual ent = makeIndividual(uri, label);
|
try {
|
||||||
if (ent != null) {
|
ents.add(makeIndividual(uri, label));
|
||||||
ents.add(ent);
|
} catch (IndividualNotFoundException e) {
|
||||||
|
// don't add
|
||||||
}
|
}
|
||||||
uri = currRes.getURI();
|
uri = currRes.getURI();
|
||||||
label = null;
|
label = null;
|
||||||
|
@ -201,9 +202,10 @@ public class IndividualDaoSDB extends IndividualDaoJena {
|
||||||
label = labelLit.getLexicalForm();
|
label = labelLit.getLexicalForm();
|
||||||
}
|
}
|
||||||
if (!rs.hasNext()) {
|
if (!rs.hasNext()) {
|
||||||
Individual ent = makeIndividual(uri, label);
|
try {
|
||||||
if (ent != null) {
|
ents.add(makeIndividual(uri, label));
|
||||||
ents.add(ent);
|
} catch (IndividualNotFoundException e) {
|
||||||
|
// don't add
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,8 +239,12 @@ public class IndividualDaoSDB extends IndividualDaoJena {
|
||||||
if (currRes.isAnon()) {
|
if (currRes.isAnon()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
filteredIndividualList.add(
|
try {
|
||||||
makeIndividual(currRes.getURI(), null));
|
filteredIndividualList.add(
|
||||||
|
makeIndividual(currRes.getURI(), null));
|
||||||
|
} catch (IndividualNotFoundException e) {
|
||||||
|
// don't add
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
dataset.getLock().leaveCriticalSection();
|
dataset.getLock().leaveCriticalSection();
|
||||||
|
@ -247,7 +253,7 @@ public class IndividualDaoSDB extends IndividualDaoJena {
|
||||||
return filteredIndividualList;
|
return filteredIndividualList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Individual makeIndividual(String uri, String label) {
|
private Individual makeIndividual(String uri, String label) throws IndividualNotFoundException {
|
||||||
Individual ent = new IndividualSDB(uri,
|
Individual ent = new IndividualSDB(uri,
|
||||||
this.dwf, datasetMode, getWebappDaoFactory(),
|
this.dwf, datasetMode, getWebappDaoFactory(),
|
||||||
SKIP_INITIALIZATION);
|
SKIP_INITIALIZATION);
|
||||||
|
|
|
@ -109,7 +109,7 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
DatasetWrapperFactory datasetWrapperFactory,
|
DatasetWrapperFactory datasetWrapperFactory,
|
||||||
SDBDatasetMode datasetMode,
|
SDBDatasetMode datasetMode,
|
||||||
WebappDaoFactoryJena wadf,
|
WebappDaoFactoryJena wadf,
|
||||||
boolean skipInitialization) {
|
boolean skipInitialization) throws IndividualNotFoundException {
|
||||||
this.individualURI = individualURI;
|
this.individualURI = individualURI;
|
||||||
this.datasetMode = datasetMode;
|
this.datasetMode = datasetMode;
|
||||||
this.dwf = datasetWrapperFactory;
|
this.dwf = datasetWrapperFactory;
|
||||||
|
@ -176,7 +176,7 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
public IndividualSDB(String individualURI,
|
public IndividualSDB(String individualURI,
|
||||||
DatasetWrapperFactory datasetWrapperFactory,
|
DatasetWrapperFactory datasetWrapperFactory,
|
||||||
SDBDatasetMode datasetMode,
|
SDBDatasetMode datasetMode,
|
||||||
WebappDaoFactoryJena wadf) {
|
WebappDaoFactoryJena wadf) throws IndividualNotFoundException {
|
||||||
this(individualURI,
|
this(individualURI,
|
||||||
datasetWrapperFactory,
|
datasetWrapperFactory,
|
||||||
datasetMode,
|
datasetMode,
|
||||||
|
@ -184,7 +184,7 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
!SKIP_INITIALIZATION);
|
!SKIP_INITIALIZATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IndividualNotFoundException extends RuntimeException {}
|
public class IndividualNotFoundException extends Exception {}
|
||||||
|
|
||||||
private void setUpURIParts(OntResource ind) {
|
private void setUpURIParts(OntResource ind) {
|
||||||
if (ind != null) {
|
if (ind != null) {
|
||||||
|
@ -464,8 +464,24 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
if (!s.getSubject().canAs(OntResource.class) || !s.getObject().canAs(OntResource.class)) {
|
if (!s.getSubject().canAs(OntResource.class) || !s.getObject().canAs(OntResource.class)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Individual subj = new IndividualSDB(((OntResource) s.getSubject().as(OntResource.class)).getURI(), this.dwf, datasetMode, webappDaoFactory);
|
Individual subj = null;
|
||||||
Individual obj = new IndividualSDB(((OntResource) s.getObject().as(OntResource.class)).getURI(), this.dwf, datasetMode, webappDaoFactory);
|
try {
|
||||||
|
subj = new IndividualSDB(
|
||||||
|
((OntResource) s.getSubject().as(OntResource.class))
|
||||||
|
.getURI(),
|
||||||
|
this.dwf, datasetMode, webappDaoFactory);
|
||||||
|
} catch (IndividualNotFoundException e) {
|
||||||
|
// leave null subject
|
||||||
|
}
|
||||||
|
Individual obj = null;
|
||||||
|
try {
|
||||||
|
obj = new IndividualSDB(
|
||||||
|
((OntResource) s.getObject().as(OntResource.class))
|
||||||
|
.getURI(),
|
||||||
|
this.dwf, datasetMode, webappDaoFactory);
|
||||||
|
} catch (IndividualNotFoundException e) {
|
||||||
|
// leave null object
|
||||||
|
}
|
||||||
ObjectProperty op = webappDaoFactory.getObjectPropertyDao().getObjectPropertyByURI(s.getPredicate().getURI());
|
ObjectProperty op = webappDaoFactory.getObjectPropertyDao().getObjectPropertyByURI(s.getPredicate().getURI());
|
||||||
// We don't want to filter out statements simply because we
|
// We don't want to filter out statements simply because we
|
||||||
// can't find a type for the property, so we'll just make a
|
// can't find a type for the property, so we'll just make a
|
||||||
|
@ -517,15 +533,19 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
while (values.hasNext()) {
|
while (values.hasNext()) {
|
||||||
result = values.next();
|
result = values.next();
|
||||||
RDFNode value = result.get("object");
|
RDFNode value = result.get("object");
|
||||||
if (value.canAs(OntResource.class)) {
|
try {
|
||||||
relatedIndividuals.add(
|
if (value.canAs(OntResource.class)) {
|
||||||
new IndividualSDB(
|
relatedIndividuals.add(
|
||||||
((OntResource) value.as(OntResource.class))
|
new IndividualSDB(
|
||||||
.getURI(),
|
((OntResource) value.as(OntResource.class))
|
||||||
this.dwf,
|
.getURI(),
|
||||||
datasetMode,
|
this.dwf,
|
||||||
webappDaoFactory) );
|
datasetMode,
|
||||||
}
|
webappDaoFactory) );
|
||||||
|
}
|
||||||
|
} catch (IndividualNotFoundException e) {
|
||||||
|
// don't add to the list
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
dataset.getLock().leaveCriticalSection();
|
dataset.getLock().leaveCriticalSection();
|
||||||
|
@ -555,9 +575,13 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
||||||
QuerySolution result = results.next();
|
QuerySolution result = results.next();
|
||||||
RDFNode value = result.get("object");
|
RDFNode value = result.get("object");
|
||||||
if (value != null && value.canAs(OntResource.class)) {
|
if (value != null && value.canAs(OntResource.class)) {
|
||||||
return new IndividualSDB(
|
try {
|
||||||
((OntResource) value.as(OntResource.class)).getURI(),
|
return new IndividualSDB(
|
||||||
dwf, datasetMode, webappDaoFactory);
|
((OntResource) value.as(OntResource.class)).getURI(),
|
||||||
|
dwf, datasetMode, webappDaoFactory);
|
||||||
|
} catch (IndividualNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class JenaBaseDao extends JenaBaseDaoCon {
|
||||||
|
|
||||||
protected String DEFAULT_NAMESPACE;
|
protected String DEFAULT_NAMESPACE;
|
||||||
protected Set<String> NONUSER_NAMESPACES;
|
protected Set<String> NONUSER_NAMESPACES;
|
||||||
protected String[] PREFERRED_LANGUAGES;
|
protected List<String> PREFERRED_LANGUAGES;
|
||||||
|
|
||||||
/* ******************* constructor ************************* */
|
/* ******************* constructor ************************* */
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ public class JenaBaseDao extends JenaBaseDaoCon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Error in updatePropertyDateValue");
|
log.error("Error in updatePropertyDateValue", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,8 +552,7 @@ public class JenaBaseDao extends JenaBaseDaoCon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Error in updatePropertyDateTimeValue");
|
log.error("Error in updatePropertyDateTimeValue", e);
|
||||||
log.error(e, e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,7 +766,7 @@ public class JenaBaseDao extends JenaBaseDaoCon {
|
||||||
if (label.isLiteral()) {
|
if (label.isLiteral()) {
|
||||||
Literal labelLit = ((Literal)label);
|
Literal labelLit = ((Literal)label);
|
||||||
String labelLanguage = labelLit.getLanguage();
|
String labelLanguage = labelLit.getLanguage();
|
||||||
if ( (labelLanguage==null) && (lang==null) ) {
|
if ( (labelLanguage == null) && (lang == null || lang.isEmpty()) ) {
|
||||||
return labelLit;
|
return labelLit;
|
||||||
}
|
}
|
||||||
if ( (lang != null) && (lang.equals(labelLanguage)) ) {
|
if ( (lang != null) && (lang.equals(labelLanguage)) ) {
|
||||||
|
@ -857,6 +856,10 @@ public class JenaBaseDao extends JenaBaseDaoCon {
|
||||||
Literal label = null;
|
Literal label = null;
|
||||||
List<RDFNode> labels = r.listPropertyValues(p).toList();
|
List<RDFNode> labels = r.listPropertyValues(p).toList();
|
||||||
|
|
||||||
|
if (labels.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Sort by lexical value to guarantee consistent results
|
// Sort by lexical value to guarantee consistent results
|
||||||
Collections.sort(labels, new Comparator<RDFNode>() {
|
Collections.sort(labels, new Comparator<RDFNode>() {
|
||||||
public int compare(RDFNode left, RDFNode right) {
|
public int compare(RDFNode left, RDFNode right) {
|
||||||
|
@ -871,8 +874,7 @@ public class JenaBaseDao extends JenaBaseDaoCon {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (int i=0; i<PREFERRED_LANGUAGES.length; i++) {
|
for (String lang : PREFERRED_LANGUAGES) {
|
||||||
String lang = PREFERRED_LANGUAGES[i];
|
|
||||||
label = getLabel(lang,labels);
|
label = getLabel(lang,labels);
|
||||||
if (label != null) {
|
if (label != null) {
|
||||||
break;
|
break;
|
||||||
|
@ -880,12 +882,21 @@ public class JenaBaseDao extends JenaBaseDaoCon {
|
||||||
}
|
}
|
||||||
if ( label == null && alsoTryNoLang ) {
|
if ( label == null && alsoTryNoLang ) {
|
||||||
label = getLabel("", labels);
|
label = getLabel("", labels);
|
||||||
|
// accept any label as a last resort
|
||||||
|
if (label == null) {
|
||||||
|
for (RDFNode labelNode : labels) {
|
||||||
|
if (labelNode instanceof Literal) {
|
||||||
|
label = ((Literal) labelNode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getDefaultLanguage() {
|
protected String getDefaultLanguage() {
|
||||||
return PREFERRED_LANGUAGES[0];
|
return PREFERRED_LANGUAGES.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -404,6 +404,17 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
|
||||||
/**
|
/**
|
||||||
* Finds all mostSpecificTypes of an individual that are members of a classgroup.
|
* Finds all mostSpecificTypes of an individual that are members of a classgroup.
|
||||||
* Returns a list of type labels.
|
* Returns a list of type labels.
|
||||||
|
*
|
||||||
|
* Note that the Map returned is a LinkedHashMap, which means that an iterator
|
||||||
|
* will return the entries in the order in which the keys were inserted in the map.
|
||||||
|
* Since the SPARQL query included an "ORDER BY ?label" clause, and since an
|
||||||
|
* iterator through that ResultSet was used to add entries to the map, an iterator
|
||||||
|
* on the map will return entries that are sorted by label (value, not key).
|
||||||
|
*
|
||||||
|
* While this sorting order is not specified as a requirement (maybe it should be?),
|
||||||
|
* it is certainly useful that the types are returned in some order that is
|
||||||
|
* replicable, so an individual with multiple mostSpecificTypes, will always see
|
||||||
|
* the same list in the same order. (See https://issues.library.cornell.edu/browse/NIHVIVO-568)
|
||||||
* **/
|
* **/
|
||||||
public Map<String, String> getMostSpecificTypesInClassgroupsForIndividual(String subjectUri) {
|
public Map<String, String> getMostSpecificTypesInClassgroupsForIndividual(String subjectUri) {
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ public class OntologyDaoJena extends JenaBaseDao implements OntologyDao {
|
||||||
try {
|
try {
|
||||||
com.hp.hpl.jena.ontology.Ontology o = ontModel.createOntology(adjustOntologyURI(ontology.getURI()));
|
com.hp.hpl.jena.ontology.Ontology o = ontModel.createOntology(adjustOntologyURI(ontology.getURI()));
|
||||||
if (ontology.getName() != null && ontology.getName().length()>0) {
|
if (ontology.getName() != null && ontology.getName().length()>0) {
|
||||||
o.setLabel(ontology.getName(), PREFERRED_LANGUAGES[0]);
|
o.setLabel(ontology.getName(), getDefaultLanguage());
|
||||||
}
|
}
|
||||||
if (ontology.getPrefix() != null && ontology.getPrefix().length()>0) {
|
if (ontology.getPrefix() != null && ontology.getPrefix().length()>0) {
|
||||||
addPropertyStringValue(o,ONTOLOGY_PREFIX_ANNOT,ontology.getPrefix(),ontModel);
|
addPropertyStringValue(o,ONTOLOGY_PREFIX_ANNOT,ontology.getPrefix(),ontModel);
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
package edu.cornell.mannlib.vitro.webapp.dao.jena;
|
package edu.cornell.mannlib.vitro.webapp.dao.jena;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -35,6 +34,7 @@ import com.hp.hpl.jena.rdf.model.Statement;
|
||||||
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
||||||
import com.hp.hpl.jena.shared.Lock;
|
import com.hp.hpl.jena.shared.Lock;
|
||||||
import com.hp.hpl.jena.sparql.resultset.ResultSetMem;
|
import com.hp.hpl.jena.sparql.resultset.ResultSetMem;
|
||||||
|
import com.hp.hpl.jena.util.iterator.ClosableIterator;
|
||||||
import com.hp.hpl.jena.vocabulary.OWL;
|
import com.hp.hpl.jena.vocabulary.OWL;
|
||||||
import com.hp.hpl.jena.vocabulary.RDFS;
|
import com.hp.hpl.jena.vocabulary.RDFS;
|
||||||
|
|
||||||
|
@ -596,6 +596,31 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<OntClass> listSuperClasses(OntClass ontClass) {
|
||||||
|
return relatedClasses(ontClass, RDFS.subClassOf);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<OntClass> listEquivalentClasses(OntClass ontClass) {
|
||||||
|
return relatedClasses(ontClass, OWL.equivalentClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<OntClass> relatedClasses(OntClass ontClass,
|
||||||
|
com.hp.hpl.jena.rdf.model.Property property) {
|
||||||
|
List<OntClass> classes = new ArrayList<OntClass>();
|
||||||
|
StmtIterator closeIt = ontClass.listProperties(property);
|
||||||
|
try {
|
||||||
|
while (closeIt.hasNext()) {
|
||||||
|
Statement stmt = closeIt.nextStatement();
|
||||||
|
if (stmt.getObject().canAs(OntClass.class)) {
|
||||||
|
classes.add(stmt.getObject().as(OntClass.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
closeIt.close();
|
||||||
|
}
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
|
||||||
public List<PropertyInstance> getAllPropInstByVClasses(List<VClass> vclasses) {
|
public List<PropertyInstance> getAllPropInstByVClasses(List<VClass> vclasses) {
|
||||||
|
|
||||||
List<PropertyInstance> propInsts = new ArrayList<PropertyInstance>();
|
List<PropertyInstance> propInsts = new ArrayList<PropertyInstance>();
|
||||||
|
@ -628,8 +653,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
|
||||||
OntClass ontClass = getOntClass(ontModel,VClassURI);
|
OntClass ontClass = getOntClass(ontModel,VClassURI);
|
||||||
if (ontClass != null) {
|
if (ontClass != null) {
|
||||||
List<OntClass> relatedClasses = new ArrayList<OntClass>();
|
List<OntClass> relatedClasses = new ArrayList<OntClass>();
|
||||||
relatedClasses.addAll(ontClass.listEquivalentClasses().toList());
|
relatedClasses.addAll(listEquivalentClasses(ontClass));
|
||||||
relatedClasses.addAll(ontClass.listSuperClasses().toList());
|
relatedClasses.addAll(listSuperClasses(ontClass));
|
||||||
for (OntClass relatedClass : relatedClasses) {
|
for (OntClass relatedClass : relatedClasses) {
|
||||||
// find properties in restrictions
|
// find properties in restrictions
|
||||||
if (relatedClass.isRestriction()) {
|
if (relatedClass.isRestriction()) {
|
||||||
|
|
|
@ -14,14 +14,14 @@ import com.hp.hpl.jena.shared.Lock;
|
||||||
*/
|
*/
|
||||||
public class SimpleOntModelSelector implements OntModelSelector {
|
public class SimpleOntModelSelector implements OntModelSelector {
|
||||||
|
|
||||||
private OntModel fullModel;
|
protected OntModel fullModel;
|
||||||
private OntModel aboxModel;
|
protected OntModel aboxModel;
|
||||||
private OntModel applicationMetadataModel;
|
protected OntModel applicationMetadataModel;
|
||||||
private OntModel tboxModel;
|
protected OntModel tboxModel;
|
||||||
private OntModel userAccountsModel;
|
protected OntModel userAccountsModel;
|
||||||
|
|
||||||
private OntModelSpec DEFAULT_ONT_MODEL_SPEC = OntModelSpec.OWL_MEM;
|
protected OntModelSpec DEFAULT_ONT_MODEL_SPEC = OntModelSpec.OWL_MEM;
|
||||||
private OntModel displayModel;
|
protected OntModel displayModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct an OntModelSelector with a bunch of empty models
|
* Construct an OntModelSelector with a bunch of empty models
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -82,11 +82,25 @@ public class SparqlGraph implements GraphWithPerform {
|
||||||
@Override
|
@Override
|
||||||
public void performAdd(Triple t) {
|
public void performAdd(Triple t) {
|
||||||
|
|
||||||
String updateString = "INSERT DATA { "
|
//log.info("adding " + t);
|
||||||
|
|
||||||
|
String updateString = "INSERT DATA { GRAPH <junk:junk> { "
|
||||||
+ sparqlNode(t.getSubject(), "") + " "
|
+ sparqlNode(t.getSubject(), "") + " "
|
||||||
+ sparqlNode(t.getPredicate(), "") + " "
|
+ sparqlNode(t.getPredicate(), "") + " "
|
||||||
+ sparqlNode(t.getObject(), "") +
|
+ sparqlNode(t.getObject(), "") +
|
||||||
"}";
|
" } }";
|
||||||
|
|
||||||
|
if (false) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
throw new RuntimeException("Breakpoint");
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
log.error(e, e);
|
||||||
|
//throw(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//log.info(updateString);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
RepositoryConnection conn = getConnection();
|
RepositoryConnection conn = getConnection();
|
||||||
|
@ -108,11 +122,15 @@ public class SparqlGraph implements GraphWithPerform {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void performDelete(Triple t) {
|
public void performDelete(Triple t) {
|
||||||
String updateString = "DELETE DATA { "
|
log.info ("************** DELETE!!!!! ********************");
|
||||||
|
|
||||||
|
String updateString = "DELETE DATA { GRAPH <junk:junk> { "
|
||||||
+ sparqlNode(t.getSubject(), "") + " "
|
+ sparqlNode(t.getSubject(), "") + " "
|
||||||
+ sparqlNode(t.getPredicate(), "") + " "
|
+ sparqlNode(t.getPredicate(), "") + " "
|
||||||
+ sparqlNode(t.getObject(), "") +
|
+ sparqlNode(t.getObject(), "") +
|
||||||
"}";
|
" } }";
|
||||||
|
|
||||||
|
log.info(updateString);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
RepositoryConnection conn = getConnection();
|
RepositoryConnection conn = getConnection();
|
||||||
|
@ -158,6 +176,7 @@ public class SparqlGraph implements GraphWithPerform {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete(Triple arg0) throws DeleteDeniedException {
|
public void delete(Triple arg0) throws DeleteDeniedException {
|
||||||
|
log.info("********************** DELETE!!!!!! ************************");
|
||||||
performDelete(arg0);
|
performDelete(arg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +231,7 @@ public class SparqlGraph implements GraphWithPerform {
|
||||||
.append(sparqlNode(object, "?o"))
|
.append(sparqlNode(object, "?o"))
|
||||||
.append("\n}");
|
.append("\n}");
|
||||||
|
|
||||||
log.info(findQuery.toString());
|
//log.info(findQuery.toString());
|
||||||
ResultSet rs = execSelect(findQuery.toString());
|
ResultSet rs = execSelect(findQuery.toString());
|
||||||
//rs = execSelect(findQuery.toString());
|
//rs = execSelect(findQuery.toString());
|
||||||
//rs = execSelect(findQuery.toString());
|
//rs = execSelect(findQuery.toString());
|
||||||
|
@ -226,6 +245,7 @@ public class SparqlGraph implements GraphWithPerform {
|
||||||
//log.info(t);
|
//log.info(t);
|
||||||
triplist.add(t);
|
triplist.add(t);
|
||||||
}
|
}
|
||||||
|
//log.info(triplist.size() + " results");
|
||||||
return WrappedIterator.create(triplist.iterator());
|
return WrappedIterator.create(triplist.iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +256,7 @@ public class SparqlGraph implements GraphWithPerform {
|
||||||
@Override
|
@Override
|
||||||
public BulkUpdateHandler getBulkUpdateHandler() {
|
public BulkUpdateHandler getBulkUpdateHandler() {
|
||||||
if (this.bulkUpdateHandler == null) {
|
if (this.bulkUpdateHandler == null) {
|
||||||
this.bulkUpdateHandler = new SimpleBulkUpdateHandler(this);
|
this.bulkUpdateHandler = new SparqlGraphBulkUpdater(this);
|
||||||
}
|
}
|
||||||
return this.bulkUpdateHandler;
|
return this.bulkUpdateHandler;
|
||||||
}
|
}
|
||||||
|
@ -383,7 +403,7 @@ public class SparqlGraph implements GraphWithPerform {
|
||||||
try {
|
try {
|
||||||
return new ResultSetMem(qe.execSelect());
|
return new ResultSetMem(qe.execSelect());
|
||||||
} finally {
|
} finally {
|
||||||
log.info((System.currentTimeMillis() - startTime) + " to execute via Jena");
|
//log.info((System.currentTimeMillis() - startTime) + " to execute via Jena");
|
||||||
qe.close();
|
qe.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.dao.jena;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.graph.Node;
|
||||||
|
import com.hp.hpl.jena.graph.Triple;
|
||||||
|
import com.hp.hpl.jena.graph.TripleMatch;
|
||||||
|
import com.hp.hpl.jena.graph.impl.GraphWithPerform;
|
||||||
|
import com.hp.hpl.jena.shared.AddDeniedException;
|
||||||
|
import com.hp.hpl.jena.sparql.util.NodeFactory;
|
||||||
|
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
|
||||||
|
import com.hp.hpl.jena.util.iterator.WrappedIterator;
|
||||||
|
|
||||||
|
public class SparqlGraphMultilingual extends SparqlGraph implements GraphWithPerform {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(SparqlGraphMultilingual.class);
|
||||||
|
|
||||||
|
protected List<String> langs;
|
||||||
|
|
||||||
|
|
||||||
|
public SparqlGraphMultilingual(String endpointURI, List<String> languages) {
|
||||||
|
super(endpointURI);
|
||||||
|
this.langs = languages;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(Triple arg0) throws AddDeniedException {
|
||||||
|
performAdd(arg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void performAdd(Triple t) {
|
||||||
|
if (true) {
|
||||||
|
super.performAdd(t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (langs == null || langs.size() == 0) {
|
||||||
|
log.info("No language configured - adding original triple " + t);
|
||||||
|
super.performAdd(t);
|
||||||
|
} else if (t.getObject().isLiteral()
|
||||||
|
&& t.getObject().getLiteral().getDatatypeURI() == null) {
|
||||||
|
log.info("adding language tag");
|
||||||
|
super.performAdd(Triple.create(t.getSubject(),
|
||||||
|
t.getPredicate(), NodeFactory.createLiteralNode(
|
||||||
|
t.getObject().getLiteralLexicalForm(), langs.get(0), null)));
|
||||||
|
} else {
|
||||||
|
log.info("adding original triple " + t);
|
||||||
|
super.performAdd(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExtendedIterator<Triple> find(TripleMatch arg0) {
|
||||||
|
//log.info("find(TripleMatch) " + arg0);
|
||||||
|
Triple t = arg0.asTriple();
|
||||||
|
return find(t.getSubject(), t.getPredicate(), t.getObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExtendedIterator<Triple> find(Node subject, Node predicate, Node object) {
|
||||||
|
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
ExtendedIterator<Triple> rawResults = super.find(subject, predicate, object);
|
||||||
|
long rawTime = System.currentTimeMillis() - startTime;
|
||||||
|
|
||||||
|
List<Triple> tripList = new ArrayList<Triple>();
|
||||||
|
while (rawResults.hasNext()) {
|
||||||
|
tripList.add(rawResults.next());
|
||||||
|
}
|
||||||
|
if (tripList.size() == 0) {
|
||||||
|
return WrappedIterator.create(tripList.iterator());
|
||||||
|
}
|
||||||
|
if (subject.isConcrete() && predicate.isConcrete() && !object.isConcrete()) {
|
||||||
|
Collections.sort(tripList, new TripleSortByLang());
|
||||||
|
LinkedList<Triple> tripl = new LinkedList<Triple>();
|
||||||
|
if (!tripList.get(0).getObject().isLiteral()) {
|
||||||
|
tripl.addAll(tripList);
|
||||||
|
} else if (StringUtils.isEmpty(tripList.get(0).getObject().getLiteralLanguage())) {
|
||||||
|
tripl.addAll(tripList); // is this right?
|
||||||
|
} else {
|
||||||
|
String lang = tripList.get(0).getObject().getLiteralLanguage();
|
||||||
|
for (Triple t : tripList) {
|
||||||
|
if (lang.equals(t.getObject().getLiteralLanguage())) {
|
||||||
|
tripl.add(t);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long filterTime = System.currentTimeMillis() - rawTime - startTime;
|
||||||
|
if (filterTime > 1) {
|
||||||
|
log.info("raw time " + rawTime + " ; filter time " + filterTime);
|
||||||
|
}
|
||||||
|
return WrappedIterator.create(tripl.iterator());
|
||||||
|
} else {
|
||||||
|
long filterTime = System.currentTimeMillis() - rawTime - startTime;
|
||||||
|
if (rawTime > 9) {
|
||||||
|
log.info("raw time " + rawTime + " ; filter time " + filterTime);
|
||||||
|
log.info("^ " + subject + " : " + predicate + " : " + object);
|
||||||
|
}
|
||||||
|
return WrappedIterator.create(tripList.iterator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TripleSortByLang implements Comparator<Triple> {
|
||||||
|
|
||||||
|
public int compare(Triple t1, Triple t2) {
|
||||||
|
if (t1 == null || t2 == null) {
|
||||||
|
return 0;
|
||||||
|
} else if (!t1.getObject().isLiteral() || !t2.getObject().isLiteral()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
String t1lang = t1.getObject().getLiteral().language();
|
||||||
|
String t2lang = t2.getObject().getLiteral().language();
|
||||||
|
|
||||||
|
if ( t1lang == null && t2lang == null) {
|
||||||
|
return 0;
|
||||||
|
} else if (t1lang == null) {
|
||||||
|
return 1;
|
||||||
|
} else if (t2lang == null) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
int t1langPref = langs.indexOf(t1.getObject().getLiteral().language());
|
||||||
|
if (t1langPref == -1) {
|
||||||
|
t1langPref = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
int t2langPref = langs.indexOf(t2.getObject().getLiteral().language());
|
||||||
|
if (t2langPref == -1) {
|
||||||
|
t2langPref = Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
return t1langPref - t2langPref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -30,7 +30,6 @@ import com.hp.hpl.jena.shared.Lock;
|
||||||
import com.hp.hpl.jena.util.iterator.ClosableIterator;
|
import com.hp.hpl.jena.util.iterator.ClosableIterator;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
|
||||||
|
@ -233,7 +232,7 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
|
||||||
return config.getDefaultNamespace();
|
return config.getDefaultNamespace();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getPreferredLanguages() {
|
public List<String> getPreferredLanguages() {
|
||||||
return config.getPreferredLanguages();
|
return config.getPreferredLanguages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,13 +311,6 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
|
||||||
return userAccountsDao = new UserAccountsDaoJena(this);
|
return userAccountsDao = new UserAccountsDaoJena(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Classes2ClassesDao classes2ClassesDao = null;
|
|
||||||
public Classes2ClassesDao getClasses2ClassesDao() {
|
|
||||||
if(classes2ClassesDao == null )
|
|
||||||
classes2ClassesDao = new Classes2ClassesDaoJena(this);
|
|
||||||
return classes2ClassesDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataPropertyStatementDao dataPropertyStatementDao = null;
|
DataPropertyStatementDao dataPropertyStatementDao = null;
|
||||||
public DataPropertyStatementDao getDataPropertyStatementDao() {
|
public DataPropertyStatementDao getDataPropertyStatementDao() {
|
||||||
if( dataPropertyStatementDao == null )
|
if( dataPropertyStatementDao == null )
|
||||||
|
|
|
@ -163,7 +163,9 @@ public class PelletListener implements ModelChangedListener {
|
||||||
this.deletedDataProperties = ModelFactory.createDefaultModel();
|
this.deletedDataProperties = ModelFactory.createDefaultModel();
|
||||||
this.mainModel.enterCriticalSection(Lock.READ);
|
this.mainModel.enterCriticalSection(Lock.READ);
|
||||||
try {
|
try {
|
||||||
addedStatements(mainModel);
|
for (ObjectPropertyStatementPattern pat : this.inferenceDrivingPatternAllowSet) {
|
||||||
|
addedStatements(mainModel.listStatements((Resource) null, pat.getPredicate(), (RDFNode) null));
|
||||||
|
}
|
||||||
if (!skipReasoningUponInitialization) {
|
if (!skipReasoningUponInitialization) {
|
||||||
this.foreground = foreground;
|
this.foreground = foreground;
|
||||||
notifyEvent(null,new EditEvent(null,false));
|
notifyEvent(null,new EditEvent(null,false));
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
@ -23,6 +24,7 @@ import com.hp.hpl.jena.shared.Lock;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
|
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.DependentResourceDeleteJena;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.DependentResourceDeleteJena;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfigurationConstants;
|
||||||
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.controller.ProcessRdfFormController.Utilities;
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.controller.ProcessRdfFormController.Utilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,8 +43,7 @@ public class ProcessRdfForm {
|
||||||
private EditN3GeneratorVTwo populator;
|
private EditN3GeneratorVTwo populator;
|
||||||
|
|
||||||
private Map<String,String> urisForNewResources = null;
|
private Map<String,String> urisForNewResources = null;
|
||||||
|
/**
|
||||||
/**
|
|
||||||
* Construct the ProcessRdfForm object.
|
* Construct the ProcessRdfForm object.
|
||||||
*/
|
*/
|
||||||
public ProcessRdfForm( EditConfigurationVTwo config, NewURIMaker newURIMaker){
|
public ProcessRdfForm( EditConfigurationVTwo config, NewURIMaker newURIMaker){
|
||||||
|
@ -172,6 +173,12 @@ public class ProcessRdfForm {
|
||||||
//need to substitute into the return to URL becase it may need new resource URIs
|
//need to substitute into the return to URL becase it may need new resource URIs
|
||||||
List<String> URLToReturnTo = Arrays.asList(submission.getEntityToReturnTo());
|
List<String> URLToReturnTo = Arrays.asList(submission.getEntityToReturnTo());
|
||||||
|
|
||||||
|
/* *********** Check if new resource needs to be forcibly created ******** */
|
||||||
|
urisForNewResources = URIsForNewRsources(editConfig, newURIMaker);
|
||||||
|
substituteInForcedNewURIs(urisForNewResources, submission.getUrisFromForm(), requiredAsserts, optionalAsserts, URLToReturnTo);
|
||||||
|
logSubstitue( "Added form URIs that required new URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
|
||||||
|
|
||||||
|
|
||||||
/* ********** Form submission URIs ********* */
|
/* ********** Form submission URIs ********* */
|
||||||
substituteInMultiURIs(submission.getUrisFromForm(), requiredAsserts, optionalAsserts, URLToReturnTo);
|
substituteInMultiURIs(submission.getUrisFromForm(), requiredAsserts, optionalAsserts, URLToReturnTo);
|
||||||
logSubstitue( "Added form URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
|
logSubstitue( "Added form URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
|
||||||
|
@ -182,10 +189,13 @@ public class ProcessRdfForm {
|
||||||
logSubstitue( "Added form Literals", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
|
logSubstitue( "Added form Literals", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
|
||||||
//Retractions does NOT get values from form.
|
//Retractions does NOT get values from form.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *********** Add subject, object and predicate ******** */
|
/* *********** Add subject, object and predicate ******** */
|
||||||
substituteInSubPredObjURIs(editConfig, requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts, URLToReturnTo);
|
substituteInSubPredObjURIs(editConfig, requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts, URLToReturnTo);
|
||||||
logSubstitue( "Added sub, pred and obj URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
|
logSubstitue( "Added sub, pred and obj URIs", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
|
||||||
|
|
||||||
|
|
||||||
/* ********* Existing URIs and Literals ********** */
|
/* ********* Existing URIs and Literals ********** */
|
||||||
substituteInMultiURIs(editConfig.getUrisInScope(),
|
substituteInMultiURIs(editConfig.getUrisInScope(),
|
||||||
requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts, URLToReturnTo);
|
requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts, URLToReturnTo);
|
||||||
|
@ -197,7 +207,8 @@ public class ProcessRdfForm {
|
||||||
//Both Assertions and Retractions get existing values.
|
//Both Assertions and Retractions get existing values.
|
||||||
|
|
||||||
/* ************ Edits may need new resources *********** */
|
/* ************ Edits may need new resources *********** */
|
||||||
urisForNewResources = URIsForNewRsources(editConfig, newURIMaker);
|
//moved this up?
|
||||||
|
//urisForNewResources = URIsForNewRsources(editConfig, newURIMaker);
|
||||||
substituteInURIs( urisForNewResources, requiredAsserts, optionalAsserts, URLToReturnTo);
|
substituteInURIs( urisForNewResources, requiredAsserts, optionalAsserts, URLToReturnTo);
|
||||||
logSubstitue( "Added URIs for new Resources", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
|
logSubstitue( "Added URIs for new Resources", requiredAsserts, optionalAsserts, requiredRetracts, optionalRetracts);
|
||||||
// Only Assertions get new resources.
|
// Only Assertions get new resources.
|
||||||
|
@ -205,7 +216,9 @@ public class ProcessRdfForm {
|
||||||
submission.setEntityToReturnTo(URLToReturnTo.get(0));
|
submission.setEntityToReturnTo(URLToReturnTo.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: maybe move this to utils or contorller?
|
|
||||||
|
|
||||||
|
//TODO: maybe move this to utils or contorller?
|
||||||
public static AdditionsAndRetractions addDependentDeletes( AdditionsAndRetractions changes, Model queryModel){
|
public static AdditionsAndRetractions addDependentDeletes( AdditionsAndRetractions changes, Model queryModel){
|
||||||
//Add retractions for dependent resource delete if that is configured and
|
//Add retractions for dependent resource delete if that is configured and
|
||||||
//if there are any dependent resources.
|
//if there are any dependent resources.
|
||||||
|
@ -455,5 +468,35 @@ public class ProcessRdfForm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In some situations, an object may have an existing URI but be left blank
|
||||||
|
* when the desired behavior is that a new object be created to replace the existing URI
|
||||||
|
* E.g. autocomplete forms that allow editing of autocomplete fields
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void substituteInForcedNewURIs(
|
||||||
|
Map<String, String> urisForNewResources, Map<String, List<String>> urisFromForm,
|
||||||
|
List<String> requiredAsserts, List<String> optionalAsserts,
|
||||||
|
List<String> uRLToReturnTo) {
|
||||||
|
Map<String, List<String>> newUris = new HashMap<String, List<String>>();
|
||||||
|
//Check if any values from the submission have the "force new uri" value
|
||||||
|
//TODO: Check how to handle multiple new resource values
|
||||||
|
Iterator<String> keyIterator = urisFromForm.keySet().iterator();
|
||||||
|
while(keyIterator.hasNext()) {
|
||||||
|
String key = keyIterator.next().toString();
|
||||||
|
if(urisFromForm.get(key).contains(EditConfigurationConstants.NEW_URI_SENTINEL)) {
|
||||||
|
String newUri = urisForNewResources.get(key);
|
||||||
|
List<String> newUrisForKey = new ArrayList<String>();
|
||||||
|
newUrisForKey.add(newUri);
|
||||||
|
newUris.put(key, newUrisForKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(newUris.size() > 0) {
|
||||||
|
substituteInMultiURIs(newUris, requiredAsserts, optionalAsserts, uRLToReturnTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static Log log = LogFactory.getLog(ProcessRdfForm.class);
|
private static Log log = LogFactory.getLog(ProcessRdfForm.class);
|
||||||
}
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration;
|
||||||
|
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.ProcessRdfForm;
|
||||||
|
|
||||||
|
|
||||||
|
public class EditConfigurationConstants {
|
||||||
|
/** Constants used by edit configuration */
|
||||||
|
//forces creation of new uri if present
|
||||||
|
public static final String NEW_URI_SENTINEL = ">NEW URI REQUIRED<";
|
||||||
|
public static final String BLANK_SENTINEL = ">SUBMITTED VALUE WAS BLANK<";
|
||||||
|
|
||||||
|
//For freemarker configuration
|
||||||
|
public static Map<String, String> exportConstants() {
|
||||||
|
Map<String, String> constants = new HashMap<String, String>();
|
||||||
|
java.lang.reflect.Field[] fields = EditConfigurationConstants.class.getDeclaredFields();
|
||||||
|
for(java.lang.reflect.Field f: fields) {
|
||||||
|
if(Modifier.isStatic(f.getModifiers()) &&
|
||||||
|
Modifier.isPublic(f.getModifiers())) {
|
||||||
|
try {
|
||||||
|
constants.put(f.getName(), f.get(null).toString());
|
||||||
|
} catch(Exception ex) {
|
||||||
|
log.error("An exception occurred in trying to retrieve this field ", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return constants;
|
||||||
|
}
|
||||||
|
private static Log log = LogFactory.getLog(EditConfigurationConstants.class);
|
||||||
|
|
||||||
|
}
|
|
@ -5,6 +5,9 @@ package edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
@ -12,6 +15,8 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
||||||
|
|
||||||
public class StandardModelSelector implements ModelSelector {
|
public class StandardModelSelector implements ModelSelector {
|
||||||
|
|
||||||
|
private static final Log log = LogFactory.getLog(StandardModelSelector.class);
|
||||||
|
|
||||||
public OntModel getModel(HttpServletRequest request, ServletContext context) {
|
public OntModel getModel(HttpServletRequest request, ServletContext context) {
|
||||||
VitroRequest vreq = new VitroRequest( request );
|
VitroRequest vreq = new VitroRequest( request );
|
||||||
|
|
||||||
|
@ -23,11 +28,17 @@ public class StandardModelSelector implements ModelSelector {
|
||||||
sessionOntModel = oms.getABoxModel();
|
sessionOntModel = oms.getABoxModel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(sessionOntModel != null && sessionOntModel instanceof OntModel )
|
if(sessionOntModel != null && sessionOntModel instanceof OntModel ) {
|
||||||
|
log.info("++++++++++ using OntModelSelector from session");
|
||||||
return (OntModel)sessionOntModel;
|
return (OntModel)sessionOntModel;
|
||||||
else
|
} else if (vreq.getOntModelSelector() != null) {
|
||||||
|
log.info("++++++++++ using OntModelSelector from request");
|
||||||
|
return vreq.getOntModelSelector().getABoxModel();
|
||||||
|
} else {
|
||||||
|
log.info("++++++++++ using OntModelSelector from context");
|
||||||
return ((OntModelSelector) context
|
return ((OntModelSelector) context
|
||||||
.getAttribute("unionOntModelSelector")).getABoxModel();
|
.getAttribute("unionOntModelSelector")).getABoxModel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final ModelSelector selector = new StandardModelSelector();
|
public static final ModelSelector selector = new StandardModelSelector();
|
||||||
|
|
|
@ -66,7 +66,7 @@ public abstract class BaseEditConfigurationGenerator implements EditConfiguratio
|
||||||
//setup the model selectors for query, write and display models on editConfig
|
//setup the model selectors for query, write and display models on editConfig
|
||||||
setupModelSelectorsFromVitroRequest(vreq, editConfig);
|
setupModelSelectorsFromVitroRequest(vreq, editConfig);
|
||||||
|
|
||||||
OntModel queryModel = (OntModel)vreq.getAttribute("jenaOntModel");
|
OntModel queryModel = vreq.getJenaOntModel(); // (OntModel)vreq.getAttribute("jenaOntModel");
|
||||||
|
|
||||||
if( editConfig.getSubjectUri() == null)
|
if( editConfig.getSubjectUri() == null)
|
||||||
editConfig.setSubjectUri( EditConfigurationUtils.getSubjectUri(vreq));
|
editConfig.setSubjectUri( EditConfigurationUtils.getSubjectUri(vreq));
|
||||||
|
|
|
@ -50,6 +50,8 @@ public class ProcessRdfFormController extends FreemarkerHttpServlet{
|
||||||
|
|
||||||
private Log log = LogFactory.getLog(ProcessRdfFormController.class);
|
private Log log = LogFactory.getLog(ProcessRdfFormController.class);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Actions requiredActions(VitroRequest vreq) {
|
protected Actions requiredActions(VitroRequest vreq) {
|
||||||
return SimplePermission.DO_FRONT_END_EDITING.ACTIONS;
|
return SimplePermission.DO_FRONT_END_EDITING.ACTIONS;
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adjust any individual that has a thumbnail with no main image.
|
|
||||||
*/
|
|
||||||
public class AllThumbsAdjuster extends FsuScanner {
|
|
||||||
private ImageDirectoryWithBackup imageDirectoryWithBackup;
|
|
||||||
|
|
||||||
public AllThumbsAdjuster(FSUController controller) {
|
|
||||||
super(controller);
|
|
||||||
this.imageDirectoryWithBackup = controller
|
|
||||||
.getImageDirectoryWithBackup();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For every individual with thumbnails but no main images, create a main
|
|
||||||
* image from the first thumbnail.
|
|
||||||
*/
|
|
||||||
public void adjust() {
|
|
||||||
updateLog.section("Creating main images for thumbnails "
|
|
||||||
+ "that have none.");
|
|
||||||
|
|
||||||
for (Resource resource : ModelWrapper.listResourcesWithProperty(model,
|
|
||||||
thumbProperty)) {
|
|
||||||
if (ResourceWrapper.getProperty(resource, imageProperty) == null) {
|
|
||||||
createMainImageFromThumbnail(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This individual has a thumbnail but no main image. Create one.
|
|
||||||
* <ul>
|
|
||||||
* <li>Figure a name for the main image.</li>
|
|
||||||
* <li>Copy the thumbnail image file into the main image file.</li>
|
|
||||||
* <li>Set that file as an image (old-style) on the individual.</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
private void createMainImageFromThumbnail(Resource resource) {
|
|
||||||
String thumbFilename = getValues(resource, thumbProperty).get(0);
|
|
||||||
String mainFilename = addFilenamePrefix("_main_image_", thumbFilename);
|
|
||||||
updateLog.log(resource, "creating a main file at '" + mainFilename
|
|
||||||
+ "' to match the thumbnail at '" + thumbFilename + "'");
|
|
||||||
|
|
||||||
try {
|
|
||||||
File thumbFile = imageDirectoryWithBackup
|
|
||||||
.getExistingFile(thumbFilename);
|
|
||||||
File mainFile = imageDirectoryWithBackup.getNewfile(mainFilename);
|
|
||||||
mainFile = checkNameConflicts(mainFile);
|
|
||||||
FileUtil.copyFile(thumbFile, mainFile);
|
|
||||||
ResourceWrapper.addProperty(resource, imageProperty, mainFilename);
|
|
||||||
} catch (IOException e) {
|
|
||||||
updateLog.error(resource, "failed to create main file '"
|
|
||||||
+ mainFilename + "'", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
|
|
||||||
}
|
|
|
@ -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";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,352 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.query.Query;
|
|
||||||
import com.hp.hpl.jena.query.QueryExecution;
|
|
||||||
import com.hp.hpl.jena.query.QueryExecutionFactory;
|
|
||||||
import com.hp.hpl.jena.query.QueryFactory;
|
|
||||||
import com.hp.hpl.jena.query.QuerySolution;
|
|
||||||
import com.hp.hpl.jena.query.ResultSet;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Literal;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Property;
|
|
||||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check all of the FileByteStream objects. If there are any that don't have
|
|
||||||
* alias URLs, fix them.
|
|
||||||
*/
|
|
||||||
public class FileStorageAliasAdder {
|
|
||||||
private static final Log log = LogFactory
|
|
||||||
.getLog(FileStorageAliasAdder.class);
|
|
||||||
|
|
||||||
private static final String FILE_PATH = "/file/";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query: get all bytestream resources that do not have alias URLs.
|
|
||||||
*/
|
|
||||||
private static final String QUERY_BYTESTREAMS_WITHOUT_ALIASES = ""
|
|
||||||
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
|
|
||||||
+ "PREFIX public: <http://vitro.mannlib.cornell.edu/ns/vitro/public#>\n"
|
|
||||||
+ "SELECT ?bs\n" + "WHERE {\n"
|
|
||||||
+ " ?bs rdf:type public:FileByteStream\n"
|
|
||||||
+ " OPTIONAL { ?bs public:directDownloadUrl ?alias }\n"
|
|
||||||
+ " FILTER ( !BOUND(?alias) )\n" + "}\n";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query: get the filenames for all bytestream resources that do not have
|
|
||||||
* alias URLs.
|
|
||||||
*/
|
|
||||||
private static final String QUERY_FILENAMES_FOR_BYTESTREAMS = ""
|
|
||||||
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
|
|
||||||
+ "PREFIX public: <http://vitro.mannlib.cornell.edu/ns/vitro/public#>\n"
|
|
||||||
+ "SELECT ?bs ?fn\n" + "WHERE {\n"
|
|
||||||
+ " ?bs rdf:type public:FileByteStream . \n"
|
|
||||||
+ " ?f public:downloadLocation ?bs . \n"
|
|
||||||
+ " ?f public:filename ?fn . \n"
|
|
||||||
+ " OPTIONAL { ?bs public:directDownloadUrl ?alias . }\n"
|
|
||||||
+ " FILTER ( !BOUND(?alias) )\n" + "}\n";
|
|
||||||
|
|
||||||
private final Model model;
|
|
||||||
private final File upgradeDirectory;
|
|
||||||
private final String vivoDefaultNamespace;
|
|
||||||
|
|
||||||
private FSULog updateLog;
|
|
||||||
|
|
||||||
private Set<String> bytestreamUrisWithoutAliases;
|
|
||||||
private Map<String, String> bytestreamUrisAndFilenames;
|
|
||||||
|
|
||||||
public FileStorageAliasAdder(Model model, File uploadDirectory,
|
|
||||||
String vivoDefaultNamespace) {
|
|
||||||
this.model = model;
|
|
||||||
this.upgradeDirectory = new File(uploadDirectory, "upgrade");
|
|
||||||
this.vivoDefaultNamespace = vivoDefaultNamespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Go through all of the FileByteStream objects in the model, creating Alias
|
|
||||||
* URLs for any objects that don't have them.
|
|
||||||
*
|
|
||||||
* If there is nothing to do, don't even create a log file, just exit.
|
|
||||||
*
|
|
||||||
* If there is something to do, go through the whole process.
|
|
||||||
*
|
|
||||||
* At the end, there should be nothing to do.
|
|
||||||
*/
|
|
||||||
public void update() {
|
|
||||||
// If there is nothing to do, we're done: don't even create a log file.
|
|
||||||
if (!isThereAnythingToDo()) {
|
|
||||||
log.debug("Found no FileByteStreams without alias URLs.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setup();
|
|
||||||
|
|
||||||
try {
|
|
||||||
findAndAddMissingAliasUrls();
|
|
||||||
|
|
||||||
if (isThereAnythingToDo()) {
|
|
||||||
throw new IllegalStateException("FileStorageAliasAdder "
|
|
||||||
+ "was unsuccessful -- model still contains "
|
|
||||||
+ "FileByteStreams without alias URLs.");
|
|
||||||
}
|
|
||||||
|
|
||||||
updateLog.section("Finished adding alias URLs to FileByteStreams.");
|
|
||||||
} finally {
|
|
||||||
updateLog.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("Finished adding alias URLs to FileByteStreams.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query the model. If there are any FileByteStream objects with no Alias
|
|
||||||
* URL, we have work to do.
|
|
||||||
*/
|
|
||||||
private boolean isThereAnythingToDo() {
|
|
||||||
String queryString = QUERY_BYTESTREAMS_WITHOUT_ALIASES;
|
|
||||||
log.debug("query: " + queryString);
|
|
||||||
|
|
||||||
QueryExecution qexec = null;
|
|
||||||
try {
|
|
||||||
qexec = createQueryExecutor(queryString);
|
|
||||||
ResultSet results = qexec.execSelect();
|
|
||||||
|
|
||||||
boolean foundSome = results.hasNext();
|
|
||||||
log.debug("any work to do? " + foundSome);
|
|
||||||
|
|
||||||
return foundSome;
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error(e, e);
|
|
||||||
return false;
|
|
||||||
} finally {
|
|
||||||
if (qexec != null) {
|
|
||||||
qexec.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the upgrade directory. Create the log file. If we fail, drop dead.
|
|
||||||
*/
|
|
||||||
private void setup() {
|
|
||||||
try {
|
|
||||||
this.upgradeDirectory.mkdirs();
|
|
||||||
updateLog = new FSULog(this.upgradeDirectory,
|
|
||||||
"FileStorageAliasAdder-log");
|
|
||||||
log.info("Updating pre-1.1 file references. Log file is "
|
|
||||||
+ updateLog.getFilename());
|
|
||||||
} catch (IOException e) {
|
|
||||||
if (updateLog != null) {
|
|
||||||
updateLog.close();
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("can't create log file: '"
|
|
||||||
+ updateLog.getFilename() + "'", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an alias URL to any FileByteStream object that doesn't have one.
|
|
||||||
*/
|
|
||||||
private void findAndAddMissingAliasUrls() {
|
|
||||||
findBytestreamsWithoutAliasUrls();
|
|
||||||
findFilenamesForBytestreams();
|
|
||||||
addAliasUrlsToModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find every bytestream that doesn't have an alias URL.
|
|
||||||
*/
|
|
||||||
private void findBytestreamsWithoutAliasUrls() {
|
|
||||||
BytestreamUriUnpacker unpacker = new BytestreamUriUnpacker();
|
|
||||||
|
|
||||||
runQuery(QUERY_BYTESTREAMS_WITHOUT_ALIASES, unpacker);
|
|
||||||
this.bytestreamUrisWithoutAliases = unpacker.getUris();
|
|
||||||
|
|
||||||
log.debug("Found " + unpacker.getUris().size()
|
|
||||||
+ " bytestreams without alias URLs");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the filename for every bytestream that doesn't have an alias URL.
|
|
||||||
*/
|
|
||||||
private void findFilenamesForBytestreams() {
|
|
||||||
FilenameUnpacker unpacker = new FilenameUnpacker();
|
|
||||||
|
|
||||||
runQuery(QUERY_FILENAMES_FOR_BYTESTREAMS, unpacker);
|
|
||||||
this.bytestreamUrisAndFilenames = unpacker.getFilenameMap();
|
|
||||||
|
|
||||||
log.debug("Found " + unpacker.getFilenameMap().size()
|
|
||||||
+ " bytestreams with filenames but no alias URLs");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Add an alias URL to each resource in the list. */
|
|
||||||
private void addAliasUrlsToModel() {
|
|
||||||
if (this.bytestreamUrisWithoutAliases.isEmpty()) {
|
|
||||||
updateLog.warn("Found no bytestreams without aliases. "
|
|
||||||
+ "Why am I here?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Property aliasProperty = model
|
|
||||||
.createProperty(VitroVocabulary.FS_ALIAS_URL);
|
|
||||||
|
|
||||||
for (String bytestreamUri : this.bytestreamUrisWithoutAliases) {
|
|
||||||
String aliasUrl = figureAliasUrl(bytestreamUri);
|
|
||||||
Resource resource = model.getResource(bytestreamUri);
|
|
||||||
|
|
||||||
ModelWrapper.add(model, resource, aliasProperty, aliasUrl);
|
|
||||||
updateLog.log(resource, "added alias URL: '" + aliasUrl + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the bytestream URI and the filename into an alias URL.
|
|
||||||
*
|
|
||||||
* If they aren't in our default namespace, or they don't have a filename,
|
|
||||||
* then their URI is the best we can do for an alias URL.
|
|
||||||
*/
|
|
||||||
private String figureAliasUrl(String bytestreamUri) {
|
|
||||||
if (!bytestreamUri.startsWith(vivoDefaultNamespace)) {
|
|
||||||
updateLog.warn("bytestream uri does not start "
|
|
||||||
+ "with the default namespace: '" + bytestreamUri + "'");
|
|
||||||
return bytestreamUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
String filename = this.bytestreamUrisAndFilenames.get(bytestreamUri);
|
|
||||||
if (filename == null) {
|
|
||||||
updateLog.warn("bytestream has no surrogate or no filename: '"
|
|
||||||
+ bytestreamUri + "'");
|
|
||||||
return "filename_not_found";
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
String remainder = bytestreamUri.substring(vivoDefaultNamespace
|
|
||||||
.length());
|
|
||||||
String encodedFilename = URLEncoder.encode(filename, "UTF-8");
|
|
||||||
String separator = remainder.endsWith("/") ? "" : "/";
|
|
||||||
|
|
||||||
return FILE_PATH + remainder + separator + encodedFilename;
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new IllegalStateException(e); // No UTF-8? Can't happen.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runQuery(String queryString, QueryResultUnpacker unpacker) {
|
|
||||||
log.debug("query: " + queryString);
|
|
||||||
|
|
||||||
QueryExecution qexec = null;
|
|
||||||
try {
|
|
||||||
qexec = createQueryExecutor(queryString);
|
|
||||||
|
|
||||||
Iterator<QuerySolution> results = qexec.execSelect();
|
|
||||||
while (results.hasNext()) {
|
|
||||||
QuerySolution result = results.next();
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("Query result variables: "
|
|
||||||
+ listVariables(result));
|
|
||||||
}
|
|
||||||
unpacker.unpack(result);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error(e, e);
|
|
||||||
} finally {
|
|
||||||
if (qexec != null) {
|
|
||||||
qexec.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private QueryExecution createQueryExecutor(String queryString) {
|
|
||||||
Query query = QueryFactory.create(queryString);
|
|
||||||
return QueryExecutionFactory.create(query, model);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** For debug logging. */
|
|
||||||
private List<String> listVariables(QuerySolution result) {
|
|
||||||
List<String> list = new ArrayList<String>();
|
|
||||||
for (Iterator<String> names = result.varNames(); names.hasNext();) {
|
|
||||||
String name = names.next();
|
|
||||||
RDFNode value = result.get(name);
|
|
||||||
list.add(name + "=" + value);
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Helper classes
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
private interface QueryResultUnpacker {
|
|
||||||
public abstract void unpack(QuerySolution result);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class BytestreamUriUnpacker implements QueryResultUnpacker {
|
|
||||||
private final Set<String> uris = new HashSet<String>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unpack(QuerySolution result) {
|
|
||||||
Resource bytestream = result.getResource("bs");
|
|
||||||
if (bytestream == null) {
|
|
||||||
updateLog.error("Query result contains no "
|
|
||||||
+ "bytestream resource: " + result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uris.add(bytestream.getURI());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<String> getUris() {
|
|
||||||
return uris;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class FilenameUnpacker implements QueryResultUnpacker {
|
|
||||||
private final Map<String, String> filenameMap = new HashMap<String, String>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unpack(QuerySolution result) {
|
|
||||||
Resource bytestream = result.getResource("bs");
|
|
||||||
if (bytestream == null) {
|
|
||||||
updateLog.error("Query result contains no "
|
|
||||||
+ "bytestream resource: " + result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String bytestreamUri = bytestream.getURI();
|
|
||||||
|
|
||||||
Literal filenameLiteral = result.getLiteral("fn");
|
|
||||||
if (filenameLiteral == null) {
|
|
||||||
updateLog.error("Query result for '" + bytestreamUri
|
|
||||||
+ "' contains no filename.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String filename = filenameLiteral.getString();
|
|
||||||
|
|
||||||
filenameMap.put(bytestreamUri, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getFilenameMap() {
|
|
||||||
return filenameMap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,268 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Clean up any files that are stored in the old directory structure and
|
|
||||||
* referenced by old-style image properties.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Besides converting the files to the new framework, this process will produce
|
|
||||||
* these artifacts:
|
|
||||||
* <ul>
|
|
||||||
* <li>A log file in the uploaded files directory, with a timestamped name, such
|
|
||||||
* as <code>upgrade/upgradeLog2010-06-20T14-55-00.txt</code>, for example. If
|
|
||||||
* for any reason, the upgrade process must run again, the log will not be
|
|
||||||
* overwritten.</li>
|
|
||||||
* <li>A directory of "deleted" files - these were extra thumbnail files or
|
|
||||||
* extra main image files -- see the details below.</li>
|
|
||||||
* <li>A directory of "unreferenced" files - these were in the image directory,
|
|
||||||
* but not connected to any entity.</li>
|
|
||||||
* </ul>
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* We consider some special cases:
|
|
||||||
* <ul>
|
|
||||||
* <li>An individual may refer to an image file that does not actually exist. If
|
|
||||||
* so, that reference will be deleted.</li>
|
|
||||||
* <li>There may be more than one reference to the same image file. If so, all
|
|
||||||
* but the first such reference will be deleted.</li>
|
|
||||||
* <li>
|
|
||||||
* In the old style, it was possible to have a main image without a thumbnail.
|
|
||||||
* If we find that, we will generate a scaled down copy of the main image, store
|
|
||||||
* that as a thumbnail image file, and then proceed.</li>
|
|
||||||
* <li>
|
|
||||||
* In the old style, it was possible to have a thumbnail without a main image.
|
|
||||||
* If we find that, we will make a copy of the thumbnail image file, declare
|
|
||||||
* that copy to be the main image, and then proceed.</li>
|
|
||||||
* <li>
|
|
||||||
* We may find individuals with more than one main image, or more than one
|
|
||||||
* thumbnail. If so, we will discard all but the first one (move them to the
|
|
||||||
* "deleted" directory).</li>
|
|
||||||
* </ul>
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* Aside from these special cases, we will:
|
|
||||||
* <ul>
|
|
||||||
* <li>Translate the main image.
|
|
||||||
* <ul>
|
|
||||||
* <li>Store the image in the new file system.</li>
|
|
||||||
* <li>Delete the image from the old images directory.</li>
|
|
||||||
* <li>Create a ByteStream individual for the main image.</li>
|
|
||||||
* <li>Create a Surrogate individual for the main image.</li>
|
|
||||||
* <li>Tie these together and attach to the entity that owns the image.</li>
|
|
||||||
* </ul>
|
|
||||||
* </li>
|
|
||||||
* <li>Translate the thumbnail.
|
|
||||||
* <ul>
|
|
||||||
* <li>Store the thumbnail in the new file system.</li>
|
|
||||||
* <li>Create a ByteStream individual for the thumbnail.</li>
|
|
||||||
* <li>Create a Surrogate individual for the thumbnail.</li>
|
|
||||||
* <li>Tie these together and attach to the Surrogate for the main image.</li>
|
|
||||||
* </ul>
|
|
||||||
* </li>
|
|
||||||
* </ul>
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* After processing all of these cases, there may be some images remaining in
|
|
||||||
* the "images" directory. These will be moved to the "unreferenced" directory,
|
|
||||||
* while preserving any internal tree structure.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public class FileStorageUpdater implements FSUController {
|
|
||||||
private static final Log log = LogFactory.getLog(FileStorageUpdater.class);
|
|
||||||
|
|
||||||
/** How wide should a generated thumbnail image be (in pixels)? */
|
|
||||||
public static final int THUMBNAIL_WIDTH = 200;
|
|
||||||
|
|
||||||
/** How high should a generated thumbnail image be (in pixels)? */
|
|
||||||
public static final int THUMBNAIL_HEIGHT = 200;
|
|
||||||
|
|
||||||
/** How is the main image referenced in the old scheme? */
|
|
||||||
public static final String IMAGEFILE = VitroVocabulary.vitroURI
|
|
||||||
+ "imageFile";
|
|
||||||
|
|
||||||
/** How is the thumbnail referenced in the old scheme? */
|
|
||||||
public static final String IMAGETHUMB = VitroVocabulary.vitroURI
|
|
||||||
+ "imageThumb";
|
|
||||||
|
|
||||||
private final Model model;
|
|
||||||
|
|
||||||
private final FileStorage fileStorage;
|
|
||||||
private final UploadedFileHelper uploadedFileHelper;
|
|
||||||
private final ImageDirectoryWithBackup imageDirectoryWithBackup;
|
|
||||||
private final File upgradeDirectory;
|
|
||||||
|
|
||||||
private FSULog updateLog;
|
|
||||||
|
|
||||||
public FileStorageUpdater(WebappDaoFactory wadf, Model model,
|
|
||||||
FileStorage fileStorage, File uploadDirectory,
|
|
||||||
File webappImageDirectory, ServletContext ctx) {
|
|
||||||
this.model = model;
|
|
||||||
this.fileStorage = fileStorage;
|
|
||||||
this.uploadedFileHelper = new UploadedFileHelper(fileStorage, wadf, ctx);
|
|
||||||
this.upgradeDirectory = new File(uploadDirectory, "upgrade");
|
|
||||||
|
|
||||||
this.imageDirectoryWithBackup = new ImageDirectoryWithBackup(new File(
|
|
||||||
uploadDirectory, "images"), webappImageDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Go through all of the individuals who have image files or thumbnail
|
|
||||||
* files, adjusting them to the new way.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* If there is nothing to do, don't even create a log file, just exit.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* If there is something to do, go through the whole process.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* At the end, there should be nothing to do. If that's true, clean out the
|
|
||||||
* old images directory.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public void update() {
|
|
||||||
// If there is nothing to do, we're done: don't even create a log file.
|
|
||||||
if (!isThereAnythingToDo()) {
|
|
||||||
log.debug("Found no pre-1.1 file references.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the upgrade directory and the log file.
|
|
||||||
setup();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Remove any image properties that don't point to literals.
|
|
||||||
new NonLiteralPropertyRemover(this).remove();
|
|
||||||
|
|
||||||
// Remove any image properties that point to files that don't exist.
|
|
||||||
new DeadEndPropertyRemover(this).remove();
|
|
||||||
|
|
||||||
// No resource may have multiple main images or multiple thumbnails.
|
|
||||||
new MultiplePropertyRemover(this).remove();
|
|
||||||
|
|
||||||
// Create a main image for any thumbnail that doesn't have one.
|
|
||||||
new AllThumbsAdjuster(this).adjust();
|
|
||||||
|
|
||||||
// Create a thumbnail for any main image that doesn't have one.
|
|
||||||
new NoThumbsAdjuster(this).adjust();
|
|
||||||
|
|
||||||
// Copy all images into the new file storage system, translating
|
|
||||||
// into the new schema. Get a list of all the images we translated.
|
|
||||||
ImageSchemaTranslater translater = new ImageSchemaTranslater(this);
|
|
||||||
Collection<String> translatedFiles = translater.translate();
|
|
||||||
|
|
||||||
if (isThereAnythingToDo()) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"FileStorageUpdate was unsuccessful -- "
|
|
||||||
+ "model still contains pre-1.1 file references.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean out the old image directory, separating into files which
|
|
||||||
// were translated, and files for which we found no reference.
|
|
||||||
new ImageDirectoryCleaner(this).clean(translatedFiles);
|
|
||||||
|
|
||||||
updateLog.section("File Storage update is complete.");
|
|
||||||
} finally {
|
|
||||||
updateLog.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("Finished updating pre-1.1 file references.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query the model. If there are any resources with old-style image
|
|
||||||
* properties, we have work to do.
|
|
||||||
*/
|
|
||||||
private boolean isThereAnythingToDo() {
|
|
||||||
if (!ModelWrapper.listResourcesWithProperty(model,
|
|
||||||
model.createProperty(IMAGEFILE)).isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ModelWrapper.listResourcesWithProperty(model,
|
|
||||||
model.createProperty(IMAGETHUMB)).isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the upgrade directory. Create the log file. If we fail, drop dead.
|
|
||||||
*/
|
|
||||||
private void setup() {
|
|
||||||
try {
|
|
||||||
this.upgradeDirectory.mkdirs();
|
|
||||||
updateLog = new FSULog(this.upgradeDirectory,
|
|
||||||
"FileStorageUpdater-log");
|
|
||||||
log.info("Updating pre-1.1 file references. Log file is "
|
|
||||||
+ updateLog.getFilename());
|
|
||||||
} catch (IOException e) {
|
|
||||||
if (updateLog != null) {
|
|
||||||
updateLog.close();
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("can't create log file: '"
|
|
||||||
+ updateLog.getFilename() + "'", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Methods to set up the individual scanners.
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Model getModel() {
|
|
||||||
return this.model;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FSULog getUpdateLog() {
|
|
||||||
return this.updateLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UploadedFileHelper getUploadedFileHelper() {
|
|
||||||
return this.uploadedFileHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileStorage getFileStorage() {
|
|
||||||
return this.fileStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImageDirectoryWithBackup getImageDirectoryWithBackup() {
|
|
||||||
return this.imageDirectoryWithBackup;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public File getTranslatedDirectory() {
|
|
||||||
return new File(this.upgradeDirectory, "translatedImages");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public File getUnreferencedDirectory() {
|
|
||||||
return new File(this.upgradeDirectory, "unreferencedImages");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,126 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.rdf.model.Literal;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Property;
|
|
||||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
|
||||||
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
|
||||||
import com.hp.hpl.jena.shared.Lock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base class for the tools that scan the model. Holds some useful fields and
|
|
||||||
* some utility methods.
|
|
||||||
*/
|
|
||||||
public abstract class FsuScanner {
|
|
||||||
protected final Model model;
|
|
||||||
protected final FSULog updateLog;
|
|
||||||
|
|
||||||
protected final Property imageProperty;
|
|
||||||
protected final Property thumbProperty;
|
|
||||||
|
|
||||||
public FsuScanner(FSUController controller) {
|
|
||||||
this.model = controller.getModel();
|
|
||||||
this.updateLog = controller.getUpdateLog();
|
|
||||||
|
|
||||||
this.imageProperty = model.createProperty(FileStorageUpdater.IMAGEFILE);
|
|
||||||
this.thumbProperty = model
|
|
||||||
.createProperty(FileStorageUpdater.IMAGETHUMB);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read all of the specified properties on a resource, and return a
|
|
||||||
* {@link List} of the {@link String} values.
|
|
||||||
*/
|
|
||||||
protected List<String> getValues(Resource resource, Property property) {
|
|
||||||
List<String> list = new ArrayList<String>();
|
|
||||||
StmtIterator stmts = resource.listProperties(property);
|
|
||||||
try {
|
|
||||||
while (stmts.hasNext()) {
|
|
||||||
Statement stmt = stmts.next();
|
|
||||||
RDFNode object = stmt.getObject();
|
|
||||||
if (object.isLiteral()) {
|
|
||||||
list.add(((Literal) object).getString());
|
|
||||||
} else {
|
|
||||||
updateLog.error(resource,
|
|
||||||
"property value was not a literal: "
|
|
||||||
+ "property is '" + property.getURI()
|
|
||||||
+ "', value is '" + object + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
stmts.close();
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read all of the specified properties on a resource, and return a
|
|
||||||
* {@link List} of the {@link Statement}s.
|
|
||||||
*/
|
|
||||||
protected List<Statement> getStatements(Resource resource, Property property) {
|
|
||||||
List<Statement> list = new ArrayList<Statement>();
|
|
||||||
|
|
||||||
resource.getModel().enterCriticalSection(Lock.READ);
|
|
||||||
StmtIterator stmts = resource.listProperties(property);
|
|
||||||
try {
|
|
||||||
while (stmts.hasNext()) {
|
|
||||||
list.add(stmts.next());
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
stmts.close();
|
|
||||||
resource.getModel().leaveCriticalSection();
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the filename within a path so we can add this prefix to it, while
|
|
||||||
* retaining the path.
|
|
||||||
*/
|
|
||||||
protected String addFilenamePrefix(String prefix, String path) {
|
|
||||||
int slashHere = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
|
|
||||||
if (slashHere == -1) {
|
|
||||||
return prefix + path;
|
|
||||||
} else {
|
|
||||||
String dirs = path.substring(0, slashHere + 1);
|
|
||||||
String filename = path.substring(slashHere + 1);
|
|
||||||
return dirs + prefix + filename;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We are about to create a file - if a file of this name already exists,
|
|
||||||
* increment the name until we have no collision.
|
|
||||||
*
|
|
||||||
* @return the original file, or the file with the incremented name.
|
|
||||||
*/
|
|
||||||
protected File checkNameConflicts(final File file) {
|
|
||||||
if (!file.exists()) {
|
|
||||||
// No conflict.
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
File parent = file.getParentFile();
|
|
||||||
String filename = file.getName();
|
|
||||||
for (int i = 0; i < 100; i++) {
|
|
||||||
File newFile = new File(parent, i + filename);
|
|
||||||
if (!newFile.exists()) {
|
|
||||||
updateLog.log("File '" + file + "' already exists, using '"
|
|
||||||
+ newFile + "' to avoid conflict.");
|
|
||||||
return newFile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateLog.error("File '" + file
|
|
||||||
+ "' already exists. Unable to avoid conflict.");
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,134 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clean out the old image directory. Copy the files into the upgrade directory,
|
|
||||||
* separating into the ones that we translated, and the ones that weren't
|
|
||||||
* referenced.
|
|
||||||
*/
|
|
||||||
public class ImageDirectoryCleaner extends FsuScanner {
|
|
||||||
private final ImageDirectoryWithBackup imageDirectoryWithBackup;
|
|
||||||
protected final File translatedDirectory;
|
|
||||||
protected final File unreferencedDirectory;
|
|
||||||
|
|
||||||
public ImageDirectoryCleaner(FSUController controller) {
|
|
||||||
super(controller);
|
|
||||||
this.imageDirectoryWithBackup = controller
|
|
||||||
.getImageDirectoryWithBackup();
|
|
||||||
|
|
||||||
this.translatedDirectory = controller.getTranslatedDirectory();
|
|
||||||
this.unreferencedDirectory = controller.getUnreferencedDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all of the files from the old image directory.
|
|
||||||
*/
|
|
||||||
public void clean(Collection<String> translatedFiles) {
|
|
||||||
updateLog.section("Cleaning the old image directory of "
|
|
||||||
+ "files that were translated.");
|
|
||||||
removeTranslatedFiles(translatedFiles);
|
|
||||||
|
|
||||||
updateLog.section("Cleaning the old image directory of "
|
|
||||||
+ "files that were not referenced.");
|
|
||||||
removeRemainingFiles(imageDirectoryWithBackup
|
|
||||||
.getPrimaryImageDirectory());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Move all of the files that we translated into the new system.
|
|
||||||
*/
|
|
||||||
private void removeTranslatedFiles(Collection<String> translatedFiles) {
|
|
||||||
for (String path : translatedFiles) {
|
|
||||||
File oldFile = new File(
|
|
||||||
imageDirectoryWithBackup.getPrimaryImageDirectory(), path);
|
|
||||||
if (oldFile.exists()) {
|
|
||||||
updateLog.log("moving image file '" + path
|
|
||||||
+ "' to the 'translated' directory.");
|
|
||||||
File deletedFile = new File(translatedDirectory, path);
|
|
||||||
try {
|
|
||||||
FileUtil.moveFile(oldFile, deletedFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
updateLog.error("Failed to move translated file '"
|
|
||||||
+ oldFile.getAbsolutePath() + "'");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateLog.log("Not moving image file '" + path
|
|
||||||
+ "' to the 'translated' directory -- "
|
|
||||||
+ "found it in the backup directory.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Go through the images directory, and discard any that remain. They must
|
|
||||||
* not have been referenced by any existing individuals.
|
|
||||||
*/
|
|
||||||
private void removeRemainingFiles(File directory) {
|
|
||||||
updateLog.log("Cleaning image directory '" + directory + "'");
|
|
||||||
try {
|
|
||||||
File targetDirectory = makeCorrespondingDirectory(directory);
|
|
||||||
File[] children = directory.listFiles();
|
|
||||||
if (children != null) {
|
|
||||||
for (File child : children) {
|
|
||||||
if (child.isDirectory()) {
|
|
||||||
removeRemainingFiles(child);
|
|
||||||
} else {
|
|
||||||
moveUnreferencedFile(targetDirectory, child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
updateLog.error(
|
|
||||||
"Failed to clean images directory '"
|
|
||||||
+ directory.getAbsolutePath() + "'", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Move this file from its current location to its new home in the
|
|
||||||
* "unreferenced" directory. Log it.
|
|
||||||
*/
|
|
||||||
private void moveUnreferencedFile(File targetDirectory, File file) {
|
|
||||||
updateLog.log("Moving image file '" + file.getPath()
|
|
||||||
+ "' to the 'unreferenced' directory");
|
|
||||||
try {
|
|
||||||
File newFile = new File(targetDirectory, file.getName());
|
|
||||||
FileUtil.moveFile(file, newFile);
|
|
||||||
} catch (IOException e) {
|
|
||||||
updateLog.error(
|
|
||||||
"Can't move unreferenced file '" + file.getAbsolutePath()
|
|
||||||
+ "'", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Figure out the path from the "images" directory to this one, and create a
|
|
||||||
* corresponding directory in the "unreferenced" area.
|
|
||||||
*/
|
|
||||||
private File makeCorrespondingDirectory(File directory) throws IOException {
|
|
||||||
String imagesPath = imageDirectoryWithBackup.getPrimaryImageDirectory()
|
|
||||||
.getAbsolutePath();
|
|
||||||
String thisPath = directory.getAbsolutePath();
|
|
||||||
|
|
||||||
if (!thisPath.startsWith(imagesPath)) {
|
|
||||||
throw new IOException("Can't make a corresponding directory for '"
|
|
||||||
+ thisPath + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
String suffix = thisPath.substring(imagesPath.length());
|
|
||||||
|
|
||||||
File corresponding = new File(unreferencedDirectory, suffix);
|
|
||||||
corresponding.mkdirs();
|
|
||||||
if (!corresponding.exists()) {
|
|
||||||
throw new IOException("Failed to create corresponding directory '"
|
|
||||||
+ corresponding.getAbsolutePath() + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
return corresponding;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,170 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.SortedSet;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import org.apache.commons.io.FilenameUtils;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.rdf.model.ResIterator;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.UploadedFileHelper;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorage;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make copies of the main image and thumbnail in the new file storage system,
|
|
||||||
* and in the model. Remove the old properties, but don't remove the old files
|
|
||||||
* yet, in case someone else is referring to them also.
|
|
||||||
*/
|
|
||||||
public class ImageSchemaTranslater extends FsuScanner {
|
|
||||||
private final ImageDirectoryWithBackup imageDirectoryWithBackup;
|
|
||||||
protected final FileStorage fileStorage;
|
|
||||||
protected final UploadedFileHelper uploadedFileHelper;
|
|
||||||
|
|
||||||
public ImageSchemaTranslater(FSUController controller) {
|
|
||||||
super(controller);
|
|
||||||
this.imageDirectoryWithBackup = controller
|
|
||||||
.getImageDirectoryWithBackup();
|
|
||||||
this.fileStorage = controller.getFileStorage();
|
|
||||||
this.uploadedFileHelper = controller.getUploadedFileHelper();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By the time we get here, any individual with a main image also has a
|
|
||||||
* thumbnail, and vice versa, and exactly one of each. For each one,
|
|
||||||
* translate the main image and the thumbnail into the new system.
|
|
||||||
*/
|
|
||||||
public Collection<String> translate() {
|
|
||||||
updateLog.section("Copying images into the new file storage, "
|
|
||||||
+ "and adding them to the new model.");
|
|
||||||
|
|
||||||
SortedSet<String> translated = new TreeSet<String>();
|
|
||||||
ResIterator haveImage = model.listResourcesWithProperty(imageProperty);
|
|
||||||
try {
|
|
||||||
while (haveImage.hasNext()) {
|
|
||||||
Resource resource = haveImage.next();
|
|
||||||
translateImages(resource, translated);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
haveImage.close();
|
|
||||||
}
|
|
||||||
return translated;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This individual should have exactly one main image and exactly one
|
|
||||||
* thumbnail.
|
|
||||||
* <ul>
|
|
||||||
* <li>Translate the first main image into the new system.</li>
|
|
||||||
* <li>Translate the first thumbnail into the new system.</li>
|
|
||||||
* <li>Remove all old-style main image properties.</li>
|
|
||||||
* <li>Remove all old-style thumbnail properties.</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
private void translateImages(Resource resource,
|
|
||||||
Collection<String> translated) {
|
|
||||||
List<String> mainImages = getValues(resource, imageProperty);
|
|
||||||
if (mainImages.size() != 1) {
|
|
||||||
updateLog.error(resource, "has " + mainImages.size()
|
|
||||||
+ " main images: " + mainImages);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> thumbnails = getValues(resource, thumbProperty);
|
|
||||||
if (thumbnails.size() != 1) {
|
|
||||||
updateLog.error(resource, "has " + thumbnails.size()
|
|
||||||
+ " thumbnails: " + thumbnails);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInfo main = translateFile(resource, mainImages.get(0), "main image");
|
|
||||||
FileInfo thumb = translateFile(resource, thumbnails.get(0), "thumbnail");
|
|
||||||
if ((main == null) || (thumb == null)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uploadedFileHelper.setImagesOnEntity(resource.getURI(), main, thumb);
|
|
||||||
|
|
||||||
translated.add(mainImages.get(0));
|
|
||||||
ResourceWrapper.removeAll(resource, imageProperty);
|
|
||||||
|
|
||||||
translated.add(thumbnails.get(0));
|
|
||||||
ResourceWrapper.removeAll(resource, thumbProperty);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translate an image file into the new system
|
|
||||||
* <ul>
|
|
||||||
* <li>Attempt to infer MIME type.</li>
|
|
||||||
* <li>Copy into the File system.</li>
|
|
||||||
* <li>Create the File and Bytestream individuals in the model.</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
private FileInfo translateFile(Resource resource, String path, String label) {
|
|
||||||
File oldFile = imageDirectoryWithBackup.getExistingFile(path);
|
|
||||||
String filename = getSimpleFilename(path);
|
|
||||||
String mimeType = guessMimeType(resource, filename);
|
|
||||||
|
|
||||||
InputStream inputStream = null;
|
|
||||||
try {
|
|
||||||
inputStream = new FileInputStream(oldFile);
|
|
||||||
// Create the file individuals in the model
|
|
||||||
FileInfo fileInfo = uploadedFileHelper.createFile(filename,
|
|
||||||
mimeType, inputStream);
|
|
||||||
updateLog.log(resource, "translating " + label + " '" + path
|
|
||||||
+ "' into the file storage as '" + fileInfo.getUri() + "'");
|
|
||||||
return fileInfo;
|
|
||||||
} catch (IOException e) {
|
|
||||||
updateLog.error(resource, "Can't create the " + label + " file. ",
|
|
||||||
e);
|
|
||||||
return null;
|
|
||||||
} finally {
|
|
||||||
if (inputStream != null) {
|
|
||||||
try {
|
|
||||||
inputStream.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove any path parts, and just get the filename and extension.
|
|
||||||
*/
|
|
||||||
private String getSimpleFilename(String path) {
|
|
||||||
return FilenameUtils.getName(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Guess what the MIME type might be.
|
|
||||||
*/
|
|
||||||
private String guessMimeType(Resource resource, String filename) {
|
|
||||||
if (filename.endsWith(".gif") || filename.endsWith(".GIF")) {
|
|
||||||
return "image/gif";
|
|
||||||
} else if (filename.endsWith(".png") || filename.endsWith(".PNG")) {
|
|
||||||
return "image/png";
|
|
||||||
} else if (filename.endsWith(".jpg") || filename.endsWith(".JPG")) {
|
|
||||||
return "image/jpeg";
|
|
||||||
} else if (filename.endsWith(".jpeg") || filename.endsWith(".JPEG")) {
|
|
||||||
return "image/jpeg";
|
|
||||||
} else if (filename.endsWith(".jpe") || filename.endsWith(".JPE")) {
|
|
||||||
return "image/jpeg";
|
|
||||||
} else {
|
|
||||||
updateLog.warn(resource,
|
|
||||||
"can't recognize the MIME type of this image file: '"
|
|
||||||
+ filename + "'");
|
|
||||||
return "image";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Property;
|
|
||||||
import com.hp.hpl.jena.rdf.model.ResIterator;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
|
||||||
import com.hp.hpl.jena.shared.Lock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility methods that operate against the Model with proper locks.
|
|
||||||
*/
|
|
||||||
public class ModelWrapper {
|
|
||||||
|
|
||||||
public static Collection<Resource> listResourcesWithProperty(Model model,
|
|
||||||
Property property) {
|
|
||||||
List<Resource> list = new ArrayList<Resource>();
|
|
||||||
ResIterator iterator = model.listResourcesWithProperty(property);
|
|
||||||
try {
|
|
||||||
while (iterator.hasNext()) {
|
|
||||||
Resource resource = iterator.next();
|
|
||||||
list.add(resource);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
iterator.close();
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void removeStatement(Model model, Statement stmt) {
|
|
||||||
model.enterCriticalSection(Lock.WRITE);
|
|
||||||
try {
|
|
||||||
model.remove(stmt);
|
|
||||||
} finally {
|
|
||||||
model.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void add(Model model, Resource subject, Property predicate,
|
|
||||||
String value) {
|
|
||||||
model.enterCriticalSection(Lock.WRITE);
|
|
||||||
try {
|
|
||||||
model.add(subject, predicate, value);
|
|
||||||
} finally {
|
|
||||||
model.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.rdf.model.Literal;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Property;
|
|
||||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If a resource has more than one image or more than one thumbnail, this
|
|
||||||
* discards the extras.
|
|
||||||
*/
|
|
||||||
public class MultiplePropertyRemover extends FsuScanner {
|
|
||||||
|
|
||||||
public MultiplePropertyRemover(FSUController controller) {
|
|
||||||
super(controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By now, we have removed any non-literals or dead ends, so keep the first
|
|
||||||
* one and discard any extras.
|
|
||||||
*/
|
|
||||||
public void remove() {
|
|
||||||
updateLog.section("Checking for resources with more "
|
|
||||||
+ "than one main image, or more than one thumbnail.");
|
|
||||||
|
|
||||||
removeExtraProperties(imageProperty, "main image");
|
|
||||||
removeExtraProperties(thumbProperty, "thumbnail");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check each resource that has this property.
|
|
||||||
*/
|
|
||||||
public void removeExtraProperties(Property prop, String label) {
|
|
||||||
for (Resource resource : ModelWrapper.listResourcesWithProperty(model,
|
|
||||||
prop)) {
|
|
||||||
removeExtraProperties(resource, prop, label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If this resource has more than one of this property, delete the extras.
|
|
||||||
*/
|
|
||||||
private void removeExtraProperties(Resource resource, Property prop,
|
|
||||||
String label) {
|
|
||||||
List<Statement> stmts = getStatements(resource, prop);
|
|
||||||
for (int i = 1; i < stmts.size(); i++) {
|
|
||||||
Statement stmt = stmts.get(i);
|
|
||||||
RDFNode node = stmt.getObject();
|
|
||||||
if (node.isLiteral()) {
|
|
||||||
String value = ((Literal) node).getString();
|
|
||||||
updateLog.warn(resource, "removing extra " + label
|
|
||||||
+ " property: '" + value + "'");
|
|
||||||
} else {
|
|
||||||
updateLog.warn(resource, "removing extra " + label
|
|
||||||
+ " property: '" + node + "'");
|
|
||||||
}
|
|
||||||
ModelWrapper.removeStatement(model, stmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,173 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
|
|
||||||
|
|
||||||
import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.THUMBNAIL_HEIGHT;
|
|
||||||
import static edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.THUMBNAIL_WIDTH;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
|
|
||||||
import javax.media.jai.JAI;
|
|
||||||
import javax.media.jai.RenderedOp;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
|
||||||
import com.sun.media.jai.codec.MemoryCacheSeekableStream;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadController.CropRectangle;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.ImageUploadThumbnailer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adjust any individual that has a main image but no thumbnail.
|
|
||||||
*/
|
|
||||||
public class NoThumbsAdjuster extends FsuScanner {
|
|
||||||
private ImageDirectoryWithBackup imageDirectoryWithBackup;
|
|
||||||
|
|
||||||
public NoThumbsAdjuster(FSUController controller) {
|
|
||||||
super(controller);
|
|
||||||
this.imageDirectoryWithBackup = controller
|
|
||||||
.getImageDirectoryWithBackup();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For every individual with main images but no thumbnails, create a
|
|
||||||
* thumbnail from the first main image.
|
|
||||||
*/
|
|
||||||
public void adjust() {
|
|
||||||
updateLog.section("Creating thumbnails to match main images.");
|
|
||||||
|
|
||||||
for (Resource resource : ModelWrapper.listResourcesWithProperty(model,
|
|
||||||
imageProperty)) {
|
|
||||||
if (resource.getProperty(thumbProperty) == null) {
|
|
||||||
createThumbnailFromMainImage(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This individual has a main image but no thumbnail. Create one.
|
|
||||||
* <ul>
|
|
||||||
* <li>Figure a name for the thumbnail image.</li>
|
|
||||||
* <li>Make a scaled copy of the main image into the thumbnail.</li>
|
|
||||||
* <li>Set that file as a thumbnail (old-style) on the individual.</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
|
||||||
private void createThumbnailFromMainImage(Resource resource) {
|
|
||||||
String mainFilename = getValues(resource, imageProperty).get(0);
|
|
||||||
String thumbFilename = addFilenamePrefix("_thumbnail_", mainFilename);
|
|
||||||
updateLog.log(resource, "creating a thumbnail at '" + thumbFilename
|
|
||||||
+ "' from the main image at '" + mainFilename + "'");
|
|
||||||
|
|
||||||
File mainFile = imageDirectoryWithBackup.getExistingFile(mainFilename);
|
|
||||||
File thumbFile = imageDirectoryWithBackup.getNewfile(thumbFilename);
|
|
||||||
thumbFile = checkNameConflicts(thumbFile);
|
|
||||||
|
|
||||||
try {
|
|
||||||
CropRectangle crop = getImageSize(mainFile);
|
|
||||||
if (imageIsSmallEnoughAlready(crop)) {
|
|
||||||
copyMainImageToThumbnail(mainFile, thumbFile);
|
|
||||||
} else {
|
|
||||||
cropScaleAndStore(crop, mainFile, thumbFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
ResourceWrapper.addProperty(resource, thumbProperty, thumbFilename);
|
|
||||||
} catch (IOException e) {
|
|
||||||
updateLog.error(resource, "failed to create thumbnail file '"
|
|
||||||
+ thumbFilename + "'", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private CropRectangle getImageSize(File file) throws IOException {
|
|
||||||
InputStream imageSource = null;
|
|
||||||
try {
|
|
||||||
imageSource = new FileInputStream(file);
|
|
||||||
MemoryCacheSeekableStream stream = new MemoryCacheSeekableStream(
|
|
||||||
imageSource);
|
|
||||||
RenderedOp image = JAI.create("stream", stream);
|
|
||||||
return new CropRectangle(0, 0, image.getHeight(), image.getWidth());
|
|
||||||
} finally {
|
|
||||||
if (imageSource != null) {
|
|
||||||
try {
|
|
||||||
imageSource.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean imageIsSmallEnoughAlready(CropRectangle crop) {
|
|
||||||
return (crop.height <= THUMBNAIL_HEIGHT)
|
|
||||||
&& (crop.width <= THUMBNAIL_WIDTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void copyMainImageToThumbnail(File mainFile, File thumbFile)
|
|
||||||
throws IOException {
|
|
||||||
InputStream imageSource = null;
|
|
||||||
try {
|
|
||||||
imageSource = new FileInputStream(mainFile);
|
|
||||||
storeImage(imageSource, thumbFile);
|
|
||||||
} finally {
|
|
||||||
if (imageSource != null) {
|
|
||||||
try {
|
|
||||||
imageSource.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cropScaleAndStore(CropRectangle crop, File mainFile,
|
|
||||||
File thumbFile) throws IOException {
|
|
||||||
InputStream mainImageStream = null;
|
|
||||||
InputStream imageSource = null;
|
|
||||||
try {
|
|
||||||
mainImageStream = new FileInputStream(mainFile);
|
|
||||||
ImageUploadThumbnailer iut = new ImageUploadThumbnailer(
|
|
||||||
THUMBNAIL_HEIGHT, THUMBNAIL_WIDTH);
|
|
||||||
imageSource = iut.cropAndScale(mainImageStream, crop);
|
|
||||||
storeImage(imageSource, thumbFile);
|
|
||||||
} finally {
|
|
||||||
if (mainImageStream != null) {
|
|
||||||
try {
|
|
||||||
mainImageStream.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (imageSource != null) {
|
|
||||||
try {
|
|
||||||
imageSource.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void storeImage(InputStream source, File file) throws IOException {
|
|
||||||
OutputStream sink = null;
|
|
||||||
try {
|
|
||||||
sink = new FileOutputStream(file);
|
|
||||||
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
int howMany;
|
|
||||||
while (-1 != (howMany = source.read(buffer))) {
|
|
||||||
sink.write(buffer, 0, howMany);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (sink != null) {
|
|
||||||
try {
|
|
||||||
sink.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.rdf.model.Literal;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Property;
|
|
||||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
|
||||||
import com.hp.hpl.jena.shared.Lock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All image properties should have literal values. Burn any that don't.
|
|
||||||
*/
|
|
||||||
public class NonLiteralPropertyRemover extends FsuScanner {
|
|
||||||
|
|
||||||
public NonLiteralPropertyRemover(FSUController controller) {
|
|
||||||
super(controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove any image properties whose objects are not {@link Literal}s.
|
|
||||||
*/
|
|
||||||
public void remove() {
|
|
||||||
updateLog.section("Checking for image properties whose objects "
|
|
||||||
+ "are not literals.");
|
|
||||||
|
|
||||||
removeNonLiterals(imageProperty, "image file");
|
|
||||||
removeNonLiterals(thumbProperty, "thumbnail");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check all resources for bogus values on this property.
|
|
||||||
*/
|
|
||||||
private void removeNonLiterals(Property prop, String label) {
|
|
||||||
for (Resource resource : ModelWrapper.listResourcesWithProperty(model,
|
|
||||||
prop)) {
|
|
||||||
removeNonLiterals(resource, prop, label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check this resource for bogus values onthis property.
|
|
||||||
*/
|
|
||||||
private void removeNonLiterals(Resource resource, Property prop,
|
|
||||||
String label) {
|
|
||||||
List<RDFNode> bogusValues = new ArrayList<RDFNode>();
|
|
||||||
for (Statement stmt : ResourceWrapper.listProperties(resource, prop)) {
|
|
||||||
RDFNode object = stmt.getObject();
|
|
||||||
if (!object.isLiteral()) {
|
|
||||||
bogusValues.add(object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (RDFNode bogusValue : bogusValues) {
|
|
||||||
updateLog.warn(resource, "discarding " + label
|
|
||||||
+ " property with non-literal as object: '" + bogusValue
|
|
||||||
+ "'");
|
|
||||||
model.enterCriticalSection(Lock.WRITE);
|
|
||||||
try {
|
|
||||||
model.createStatement(resource, prop, bogusValue).remove();
|
|
||||||
} finally {
|
|
||||||
model.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.filestorage.updater;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.rdf.model.Property;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
|
||||||
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
|
||||||
import com.hp.hpl.jena.shared.Lock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility methods that get the appropriate model locks before manipluating
|
|
||||||
* resources.
|
|
||||||
*/
|
|
||||||
public class ResourceWrapper {
|
|
||||||
|
|
||||||
public static Statement getProperty(Resource resource, Property property) {
|
|
||||||
resource.getModel().enterCriticalSection(Lock.READ);
|
|
||||||
try {
|
|
||||||
return resource.getProperty(property);
|
|
||||||
} finally {
|
|
||||||
resource.getModel().leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addProperty(Resource resource, Property property,
|
|
||||||
String value) {
|
|
||||||
resource.getModel().enterCriticalSection(Lock.WRITE);
|
|
||||||
try {
|
|
||||||
resource.addProperty(property, value);
|
|
||||||
} finally {
|
|
||||||
resource.getModel().leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void removeAll(Resource resource, Property property) {
|
|
||||||
resource.getModel().enterCriticalSection(Lock.WRITE);
|
|
||||||
try {
|
|
||||||
resource.removeAll(property);
|
|
||||||
} finally {
|
|
||||||
resource.getModel().leaveCriticalSection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Collection<Statement> listProperties(Resource resource,
|
|
||||||
Property prop) {
|
|
||||||
List<Statement> list = new ArrayList<Statement>();
|
|
||||||
StmtIterator stmts = resource.listProperties(prop);
|
|
||||||
try {
|
|
||||||
while (stmts.hasNext()) {
|
|
||||||
list.add(stmts.next());
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
} finally {
|
|
||||||
stmts.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -5,6 +5,10 @@ package edu.cornell.mannlib.vitro.webapp.filters;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -21,18 +25,27 @@ import org.apache.commons.dbcp.BasicDataSource;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.graph.Graph;
|
||||||
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||||
|
import com.hp.hpl.jena.query.DataSource;
|
||||||
import com.hp.hpl.jena.query.Dataset;
|
import com.hp.hpl.jena.query.Dataset;
|
||||||
|
import com.hp.hpl.jena.query.DatasetFactory;
|
||||||
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
import com.hp.hpl.jena.sdb.SDBFactory;
|
import com.hp.hpl.jena.sdb.SDBFactory;
|
||||||
import com.hp.hpl.jena.sdb.Store;
|
import com.hp.hpl.jena.sdb.Store;
|
||||||
import com.hp.hpl.jena.sdb.StoreDesc;
|
import com.hp.hpl.jena.sdb.StoreDesc;
|
||||||
import com.hp.hpl.jena.sdb.sql.SDBConnection;
|
import com.hp.hpl.jena.sdb.sql.SDBConnection;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryConfig;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.SingleContentOntModelSelector;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraphMultilingual;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB;
|
||||||
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
|
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
|
||||||
|
|
||||||
|
@ -89,6 +102,15 @@ public class WebappDaoFactorySDBPrep implements Filter {
|
||||||
Dataset dataset = null;
|
Dataset dataset = null;
|
||||||
WebappDaoFactory wadf = null;
|
WebappDaoFactory wadf = null;
|
||||||
|
|
||||||
|
// temporary scaffolding in the rdfapi dev branch
|
||||||
|
// TODO remove me
|
||||||
|
if (ConfigurationProperties.getBean(request).getProperty(
|
||||||
|
"VitroConnection.DataSource.endpointURI") != null) {
|
||||||
|
filterSparql(request, oms, defaultNamespace);
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (bds == null || storeDesc == null || oms == null) {
|
if (bds == null || storeDesc == null || oms == null) {
|
||||||
throw new RuntimeException("SDB store not property set up");
|
throw new RuntimeException("SDB store not property set up");
|
||||||
|
@ -140,6 +162,56 @@ public class WebappDaoFactorySDBPrep implements Filter {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void filterSparql(ServletRequest request, OntModelSelector oms, String defaultNamespace) {
|
||||||
|
log.info("---------");
|
||||||
|
|
||||||
|
VitroRequest vreq = new VitroRequest((HttpServletRequest) request);
|
||||||
|
|
||||||
|
Enumeration<String> headStrs = vreq.getHeaderNames();
|
||||||
|
while (headStrs.hasMoreElements()) {
|
||||||
|
String head = headStrs.nextElement();
|
||||||
|
log.info(head + " : " + vreq.getHeader(head));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> langs = new ArrayList<String>();
|
||||||
|
|
||||||
|
log.info("Accept-Language: " + vreq.getHeader("Accept-Language"));
|
||||||
|
Enumeration<Locale> locs = vreq.getLocales();
|
||||||
|
while (locs.hasMoreElements()) {
|
||||||
|
Locale locale = locs.nextElement();
|
||||||
|
langs.add(locale.toString().replace("_", "-"));
|
||||||
|
log.info(locale.toString() + " / " + locale.getLanguage() + " + " + locale.getCountry() + " : " + locale.getDisplayCountry() + " | " + locale.getLanguage() + " : " + locale.getDisplayLanguage());
|
||||||
|
}
|
||||||
|
WebappDaoFactoryConfig config = new WebappDaoFactoryConfig();
|
||||||
|
config.setDefaultNamespace(defaultNamespace);
|
||||||
|
config.setPreferredLanguages(langs);
|
||||||
|
|
||||||
|
//okay let's make a graph-backed model
|
||||||
|
String endpointURI = ConfigurationProperties.getBean(
|
||||||
|
request).getProperty("VitroConnection.DataSource.endpointURI");
|
||||||
|
|
||||||
|
Graph g = new SparqlGraphMultilingual(endpointURI, langs);
|
||||||
|
//Graph g = new SparqlGraph(endpointURI);
|
||||||
|
|
||||||
|
Model m = ModelFactory.createModelForGraph(g);
|
||||||
|
OntModel om = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, m);
|
||||||
|
oms = new SingleContentOntModelSelector(om, oms.getDisplayModel(), oms.getUserAccountsModel());
|
||||||
|
|
||||||
|
DataSource dataset = DatasetFactory.create();
|
||||||
|
dataset.addNamedModel("fake:fake", m);
|
||||||
|
|
||||||
|
WebappDaoFactory wadf = new WebappDaoFactoryJena(oms, config);
|
||||||
|
//wadf = new WebappDaoFactorySDB(oms, dataset, config);
|
||||||
|
vreq.setWebappDaoFactory(wadf);
|
||||||
|
vreq.setFullWebappDaoFactory(wadf);
|
||||||
|
vreq.setUnfilteredWebappDaoFactory(wadf);
|
||||||
|
vreq.setWebappDaoFactory(wadf);
|
||||||
|
vreq.setAssertionsWebappDaoFactory(wadf);
|
||||||
|
vreq.setDataset(dataset);
|
||||||
|
vreq.setJenaOntModel(om);
|
||||||
|
vreq.setOntModelSelector(oms);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(FilterConfig filterConfig) throws ServletException {
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -43,12 +43,12 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent;
|
||||||
* Allows for real-time incremental materialization or retraction of RDFS-
|
* Allows for real-time incremental materialization or retraction of RDFS-
|
||||||
* style class and property subsumption based ABox inferences as statements
|
* style class and property subsumption based ABox inferences as statements
|
||||||
* are added to or removed from the (ABox or TBox) knowledge base.
|
* are added to or removed from the (ABox or TBox) knowledge base.
|
||||||
|
* @author sjm222
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class SimpleReasoner extends StatementListener {
|
public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(SimpleReasoner.class);
|
private static final Log log = LogFactory.getLog(SimpleReasoner.class);
|
||||||
//private static final MyTempLogger log = new MyTempLogger();
|
|
||||||
|
|
||||||
private OntModel tboxModel; // asserted and inferred TBox axioms
|
private OntModel tboxModel; // asserted and inferred TBox axioms
|
||||||
private OntModel aboxModel; // ABox assertions
|
private OntModel aboxModel; // ABox assertions
|
||||||
|
@ -120,9 +120,9 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs selected incremental ABox reasoning based
|
* Performs incremental ABox reasoning based
|
||||||
* on the addition of a new statement (aka assertion)
|
* on the addition of a new statement
|
||||||
* to the ABox.
|
* (aka assertion) to the ABox.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addedStatement(Statement stmt) {
|
public void addedStatement(Statement stmt) {
|
||||||
|
@ -142,7 +142,7 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs selected incremental ABox reasoning based
|
* Performs incremental ABox reasoning based
|
||||||
* on the retraction of a statement (aka assertion)
|
* on the retraction of a statement (aka assertion)
|
||||||
* from the ABox.
|
* from the ABox.
|
||||||
*/
|
*/
|
||||||
|
@ -160,7 +160,12 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void handleRemovedStatement(Statement stmt) {
|
|
||||||
|
/*
|
||||||
|
* Synchronized part of removedStatement. Interacts
|
||||||
|
* with DeltaComputer.
|
||||||
|
*/
|
||||||
|
protected synchronized void handleRemovedStatement(Statement stmt) {
|
||||||
|
|
||||||
if (batchMode1) {
|
if (batchMode1) {
|
||||||
aBoxDeltaModeler1.removedStatement(stmt);
|
aBoxDeltaModeler1.removedStatement(stmt);
|
||||||
|
@ -176,7 +181,7 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs incremental selected ABox reasoning based
|
* Performs incremental ABox reasoning based
|
||||||
* on changes to the class hierarchy.
|
* on changes to the class hierarchy.
|
||||||
*
|
*
|
||||||
* Handles rdfs:subclassOf, owl:equivalentClass,
|
* Handles rdfs:subclassOf, owl:equivalentClass,
|
||||||
|
@ -229,7 +234,7 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs incremental selected ABox reasoning based
|
* Performs incremental ABox reasoning based
|
||||||
* on changes to the class hierarchy.
|
* on changes to the class hierarchy.
|
||||||
*
|
*
|
||||||
* Handles rdfs:subclassOf, owl:equivalentClass,
|
* Handles rdfs:subclassOf, owl:equivalentClass,
|
||||||
|
@ -281,10 +286,10 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
* This signature used when recomputing the whole ABox
|
||||||
*/
|
*/
|
||||||
public void addedABoxTypeAssertion(Resource individual, Model inferenceModel, HashSet<String> unknownTypes) {
|
protected void addedABoxTypeAssertion(Resource individual, Model inferenceModel, HashSet<String> unknownTypes) {
|
||||||
|
|
||||||
StmtIterator iter = null;
|
StmtIterator iter = null;
|
||||||
|
|
||||||
|
@ -302,6 +307,7 @@ public class SimpleReasoner extends StatementListener {
|
||||||
aboxModel.leaveCriticalSection();
|
aboxModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Performs incremental reasoning based on a new type assertion
|
* Performs incremental reasoning based on a new type assertion
|
||||||
* added to the ABox (assertion that an individual is of a certain
|
* added to the ABox (assertion that an individual is of a certain
|
||||||
|
@ -309,9 +315,8 @@ public class SimpleReasoner extends StatementListener {
|
||||||
*
|
*
|
||||||
* If it is added that B is of type A, then for each superclass of
|
* If it is added that B is of type A, then for each superclass of
|
||||||
* A assert that B is of that type.
|
* A assert that B is of that type.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public void addedABoxTypeAssertion(Statement stmt, Model inferenceModel, HashSet<String> unknownTypes) {
|
protected void addedABoxTypeAssertion(Statement stmt, Model inferenceModel, HashSet<String> unknownTypes) {
|
||||||
|
|
||||||
tboxModel.enterCriticalSection(Lock.READ);
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
|
||||||
|
@ -377,13 +382,10 @@ public class SimpleReasoner extends StatementListener {
|
||||||
* that B is of that type.
|
* that B is of that type.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void removedABoxTypeAssertion(Statement stmt, Model inferenceModel) {
|
protected void removedABoxTypeAssertion(Statement stmt, Model inferenceModel) {
|
||||||
|
|
||||||
tboxModel.enterCriticalSection(Lock.READ);
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
|
||||||
// convert this method to use generic resources - not get ontclass, not cls.listSuperClasses...
|
|
||||||
// use model contains if want to log warning about type owl class
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
OntClass cls = null;
|
OntClass cls = null;
|
||||||
|
@ -431,7 +433,6 @@ public class SimpleReasoner extends StatementListener {
|
||||||
inferenceModel.enterCriticalSection(Lock.WRITE);
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
try {
|
try {
|
||||||
if (inferenceModel.contains(infStmt)) {
|
if (inferenceModel.contains(infStmt)) {
|
||||||
//log.debug("Removing this inferred statement: " + infStmt.toString() + " - " + infStmt.getSubject().toString() + " - " + infStmt.getPredicate().toString() + " - " + infStmt.getObject().toString());
|
|
||||||
inferenceModel.remove(infStmt);
|
inferenceModel.remove(infStmt);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -454,7 +455,7 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
// Returns true if it is entailed by class subsumption that
|
// Returns true if it is entailed by class subsumption that
|
||||||
// subject is of type cls; otherwise returns false.
|
// subject is of type cls; otherwise returns false.
|
||||||
public boolean entailedType(Resource subject, OntClass cls) {
|
protected boolean entailedType(Resource subject, OntClass cls) {
|
||||||
aboxModel.enterCriticalSection(Lock.READ);
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
tboxModel.enterCriticalSection(Lock.READ);
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
|
||||||
|
@ -485,9 +486,9 @@ public class SimpleReasoner extends StatementListener {
|
||||||
/*
|
/*
|
||||||
* If it is added that B is a subClass of A, then for each
|
* If it is added that B is a subClass of A, then for each
|
||||||
* individual that is typed as B, either in the ABox or in the
|
* individual that is typed as B, either in the ABox or in the
|
||||||
* inferred model, assert that it is of type A.
|
* inferred model, infer that it is of type A.
|
||||||
*/
|
*/
|
||||||
public void addedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) {
|
protected void addedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) {
|
||||||
log.debug("subClass = " + subClass.getURI() + " superClass = " + superClass.getURI());
|
log.debug("subClass = " + subClass.getURI() + " superClass = " + superClass.getURI());
|
||||||
OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
unionModel.addSubModel(aboxModel);
|
unionModel.addSubModel(aboxModel);
|
||||||
|
@ -530,7 +531,7 @@ public class SimpleReasoner extends StatementListener {
|
||||||
* UNLESS the individual is of some type C that is a subClass
|
* UNLESS the individual is of some type C that is a subClass
|
||||||
* of A (including A itself)
|
* of A (including A itself)
|
||||||
*/
|
*/
|
||||||
public void removedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) {
|
protected void removedSubClass(OntClass subClass, OntClass superClass, Model inferenceModel) {
|
||||||
OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
OntModel unionModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
unionModel.addSubModel(aboxModel);
|
unionModel.addSubModel(aboxModel);
|
||||||
unionModel.addSubModel(inferenceModel);
|
unionModel.addSubModel(inferenceModel);
|
||||||
|
@ -567,10 +568,10 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the most specific types (classes) of an individual and
|
* Find the most specific types (classes) of an individual and
|
||||||
* indicate them for the individual with the core:mostSpecificType
|
* indicate them for the individual with the mostSpecificType
|
||||||
* annotation.
|
* annotation.
|
||||||
*/
|
*/
|
||||||
public void setMostSpecificTypes(Resource individual, Model inferenceModel, HashSet<String> unknownTypes) {
|
protected void setMostSpecificTypes(Resource individual, Model inferenceModel, HashSet<String> unknownTypes) {
|
||||||
|
|
||||||
tboxModel.enterCriticalSection(Lock.READ);
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
aboxModel.enterCriticalSection(Lock.READ);
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
@ -665,13 +666,13 @@ public class SimpleReasoner extends StatementListener {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMostSpecificTypes(Resource individual, HashSet<String> typeURIs, Model inferenceModel) {
|
protected void setMostSpecificTypes(Resource individual, HashSet<String> typeURIs, Model inferenceModel) {
|
||||||
|
|
||||||
inferenceModel.enterCriticalSection(Lock.WRITE);
|
inferenceModel.enterCriticalSection(Lock.WRITE);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Model retractions = ModelFactory.createDefaultModel();
|
Model retractions = ModelFactory.createDefaultModel();
|
||||||
// remove obsolete most-specific-type assertions
|
// remove obsolete mostSpecificType assertions
|
||||||
StmtIterator iter = inferenceModel.listStatements(individual, mostSpecificType, (RDFNode) null);
|
StmtIterator iter = inferenceModel.listStatements(individual, mostSpecificType, (RDFNode) null);
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
|
@ -689,7 +690,7 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
inferenceModel.remove(retractions);
|
inferenceModel.remove(retractions);
|
||||||
|
|
||||||
// add new most-specific-type assertions
|
// add new mostSpecificType assertions
|
||||||
Iterator<String> typeIter = typeURIs.iterator();
|
Iterator<String> typeIter = typeURIs.iterator();
|
||||||
|
|
||||||
while (typeIter.hasNext()) {
|
while (typeIter.hasNext()) {
|
||||||
|
@ -707,12 +708,12 @@ public class SimpleReasoner extends StatementListener {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean recomputing = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the reasoner is in the process of recomputing all
|
* Returns true if the reasoner is in the process of recomputing all
|
||||||
* inferences.
|
* inferences.
|
||||||
*/
|
*/
|
||||||
|
private boolean recomputing = false;
|
||||||
|
|
||||||
public boolean isRecomputing() {
|
public boolean isRecomputing() {
|
||||||
return recomputing;
|
return recomputing;
|
||||||
}
|
}
|
||||||
|
@ -731,14 +732,14 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recompute the entire ABox inference graph. The new
|
* Recompute the entire ABox inference graph. The new
|
||||||
* inference graph is built up in a separate model and
|
* inference graph is built in a separate model and
|
||||||
* then reconciled with the inference graph used by the
|
* then reconciled with the inference graph in active
|
||||||
* application. The model reconciliation must be done
|
* use. The model reconciliation must be done
|
||||||
* without reading the whole inference models into
|
* without reading the whole inference models into
|
||||||
* memory in order to support very large ABox
|
* memory in order to support very large ABox
|
||||||
* inference models.
|
* inference models.
|
||||||
*/
|
*/
|
||||||
public synchronized void recomputeABox() {
|
protected synchronized void recomputeABox() {
|
||||||
|
|
||||||
HashSet<String> unknownTypes = new HashSet<String>();
|
HashSet<String> unknownTypes = new HashSet<String>();
|
||||||
|
|
||||||
|
@ -799,8 +800,8 @@ public class SimpleReasoner extends StatementListener {
|
||||||
|
|
||||||
log.info("Finished computing class-based ABox inferences");
|
log.info("Finished computing class-based ABox inferences");
|
||||||
|
|
||||||
// reflect the recomputed inferences into the application inference
|
// reflect the recomputed inferences into the application
|
||||||
// model.
|
// inference model.
|
||||||
log.info("Updating ABox inference model");
|
log.info("Updating ABox inference model");
|
||||||
StmtIterator iter = null;
|
StmtIterator iter = null;
|
||||||
|
|
||||||
|
@ -913,23 +914,16 @@ public class SimpleReasoner extends StatementListener {
|
||||||
log.info("ABox inference model updated");
|
log.info("ABox inference model updated");
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean isABoxReasoningAsynchronous() {
|
/*
|
||||||
if (batchMode1 || batchMode2) {
|
* Get the URIs for all individuals in the system
|
||||||
return true;
|
*/
|
||||||
} else {
|
protected ArrayList<String> getAllIndividualURIs() {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ArrayList<String> getAllIndividualURIs() {
|
|
||||||
|
|
||||||
String queryString = "select distinct ?subject where {?subject <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type}";
|
String queryString = "select distinct ?subject where {?subject <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?type}";
|
||||||
return getIndividualURIs(queryString);
|
return getIndividualURIs(queryString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<String> getIndividualURIs(String queryString) {
|
protected ArrayList<String> getIndividualURIs(String queryString) {
|
||||||
|
|
||||||
ArrayList<String> individuals = new ArrayList<String>();
|
ArrayList<String> individuals = new ArrayList<String>();
|
||||||
aboxModel.enterCriticalSection(Lock.READ);
|
aboxModel.enterCriticalSection(Lock.READ);
|
||||||
|
@ -960,6 +954,19 @@ public class SimpleReasoner extends StatementListener {
|
||||||
return individuals;
|
return individuals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// system-configured reasoning modules (plugins)
|
||||||
|
public boolean isInterestedInRemovedStatement(Statement stmt) {
|
||||||
|
|
||||||
|
if (stmt.getPredicate().equals(RDF.type)) return true;
|
||||||
|
|
||||||
|
for (ReasonerPlugin plugin : getPluginList()) {
|
||||||
|
if (plugin.isInterestedInRemovedStatement(stmt)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected void doPlugins(ModelUpdate.Operation op, Statement stmt) {
|
protected void doPlugins(ModelUpdate.Operation op, Statement stmt) {
|
||||||
|
|
||||||
for (ReasonerPlugin plugin : getPluginList()) {
|
for (ReasonerPlugin plugin : getPluginList()) {
|
||||||
|
@ -983,29 +990,16 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInterestedInRemovedStatement(Statement stmt) {
|
|
||||||
|
|
||||||
if (stmt.getPredicate().equals(RDF.type)) return true;
|
|
||||||
|
|
||||||
for (ReasonerPlugin plugin : getPluginList()) {
|
|
||||||
if (plugin.isInterestedInRemovedStatement(stmt)) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO remove this for 1.5
|
|
||||||
public synchronized void computeMostSpecificType() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is called when the system shuts down.
|
* This is called when the application shuts down.
|
||||||
*/
|
*/
|
||||||
public void setStopRequested() {
|
public void setStopRequested() {
|
||||||
this.stopRequested = true;
|
this.stopRequested = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility method for logging
|
||||||
|
*/
|
||||||
public static String stmtString(Statement statement) {
|
public static String stmtString(Statement statement) {
|
||||||
return " [subject = " + statement.getSubject().getURI() +
|
return " [subject = " + statement.getSubject().getURI() +
|
||||||
"] [property = " + statement.getPredicate().getURI() +
|
"] [property = " + statement.getPredicate().getURI() +
|
||||||
|
@ -1013,6 +1007,20 @@ public class SimpleReasoner extends StatementListener {
|
||||||
: ((Resource)statement.getObject()).getURI() + " (Resource)") + "]";
|
: ((Resource)statement.getObject()).getURI() + " (Resource)") + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// DeltaComputer
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Asynchronous reasoning mode (DeltaComputer) is used in the case of batch removals.
|
||||||
|
*/
|
||||||
|
public synchronized boolean isABoxReasoningAsynchronous() {
|
||||||
|
if (batchMode1 || batchMode2) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private volatile boolean deltaComputerProcessing = false;
|
private volatile boolean deltaComputerProcessing = false;
|
||||||
private int eventCount = 0;
|
private int eventCount = 0;
|
||||||
|
|
||||||
|
@ -1083,7 +1091,7 @@ public class SimpleReasoner extends StatementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.warn("unexpected condition, invoked when batchMode1 and batchMode2 were both false");
|
log.warn("unexpected condition, invoked when batchMode1 and batchMode2 are both false");
|
||||||
deltaComputerProcessing = false;
|
deltaComputerProcessing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,11 @@ import com.hp.hpl.jena.rdf.model.Statement;
|
||||||
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
|
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread;
|
import edu.cornell.mannlib.vitro.webapp.utils.threads.VitroBackgroundThread;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Route notification of changes to TBox to the incremental ABox reasoner.
|
* Route notification of changes to TBox to the incremental ABox reasoner.
|
||||||
* The incremental ABox reasoner handles only subclass, superclass
|
* The incremental ABox reasoner handles only subClass and
|
||||||
* and equivalent class axioms.
|
* equivalentClass class axioms. Reasoning dones as a result of TBox
|
||||||
*
|
* changes is always done in a separate thread.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class SimpleReasonerTBoxListener extends StatementListener {
|
public class SimpleReasonerTBoxListener extends StatementListener {
|
||||||
|
|
|
@ -20,7 +20,9 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import com.hp.hpl.jena.graph.Node;
|
import com.hp.hpl.jena.graph.Node;
|
||||||
|
import com.hp.hpl.jena.ontology.OntDocumentManager;
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
|
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
import com.hp.hpl.jena.sdb.SDBFactory;
|
import com.hp.hpl.jena.sdb.SDBFactory;
|
||||||
|
@ -48,6 +50,8 @@ public class FileGraphSetup implements ServletContextListener {
|
||||||
OntModelSelector baseOms = null;
|
OntModelSelector baseOms = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
OntDocumentManager.getInstance().setProcessImports(true);
|
||||||
baseOms = ModelContext.getBaseOntModelSelector(sce.getServletContext());
|
baseOms = ModelContext.getBaseOntModelSelector(sce.getServletContext());
|
||||||
Store kbStore = (Store) sce.getServletContext().getAttribute("kbStore");
|
Store kbStore = (Store) sce.getServletContext().getAttribute("kbStore");
|
||||||
|
|
||||||
|
@ -78,6 +82,8 @@ public class FileGraphSetup implements ServletContextListener {
|
||||||
System.out.println("Throwable in listener " + this.getClass().getName());
|
System.out.println("Throwable in listener " + this.getClass().getName());
|
||||||
log.error(t);
|
log.error(t);
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
OntDocumentManager.getInstance().setProcessImports(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isUpdateRequired(sce.getServletContext())) {
|
if (isUpdateRequired(sce.getServletContext())) {
|
||||||
|
@ -114,7 +120,7 @@ public class FileGraphSetup implements ServletContextListener {
|
||||||
try {
|
try {
|
||||||
FileInputStream fis = new FileInputStream( file );
|
FileInputStream fis = new FileInputStream( file );
|
||||||
try {
|
try {
|
||||||
Model model = ModelFactory.createDefaultModel();
|
OntModel model = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||||
if ( p.endsWith(".n3") || p.endsWith(".N3") || p.endsWith(".ttl") || p.endsWith(".TTL") ) {
|
if ( p.endsWith(".n3") || p.endsWith(".N3") || p.endsWith(".ttl") || p.endsWith(".TTL") ) {
|
||||||
model.read( fis, null, "N3" );
|
model.read( fis, null, "N3" );
|
||||||
} else if ( p.endsWith(".owl") || p.endsWith(".OWL") || p.endsWith(".rdf") || p.endsWith(".RDF") || p.endsWith(".xml") || p.endsWith(".XML") ) {
|
} else if ( p.endsWith(".owl") || p.endsWith(".OWL") || p.endsWith(".rdf") || p.endsWith(".RDF") || p.endsWith(".xml") || p.endsWith(".XML") ) {
|
||||||
|
|
|
@ -68,6 +68,14 @@ public class JenaDataSourceSetup extends JenaDataSourceSetupBase
|
||||||
ServletContext ctx = sce.getServletContext();
|
ServletContext ctx = sce.getServletContext();
|
||||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||||
|
|
||||||
|
// temporary scaffolding in the rdfapi dev branch
|
||||||
|
// TODO remove me
|
||||||
|
if (ConfigurationProperties.getBean(ctx).getProperty(
|
||||||
|
"VitroConnection.DataSource.endpointURI") != null) {
|
||||||
|
(new JenaDataSourceSetupSparql()).contextInitialized(sce);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
setUpJenaDataSource(ctx);
|
setUpJenaDataSource(ctx);
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.File;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,7 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
|
|
|
@ -16,7 +16,6 @@ import javax.servlet.ServletContextListener;
|
||||||
import org.apache.commons.dbcp.BasicDataSource;
|
import org.apache.commons.dbcp.BasicDataSource;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.mindswap.pellet.PelletOptions;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
import com.hp.hpl.jena.vocabulary.OWL;
|
import com.hp.hpl.jena.vocabulary.OWL;
|
||||||
|
@ -45,6 +44,14 @@ public class SimpleReasonerSetup implements ServletContextListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextInitialized(ServletContextEvent sce) {
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
|
||||||
|
// temporary scaffolding in the rdfapi dev branch
|
||||||
|
// TODO remove me
|
||||||
|
if (ConfigurationProperties.getBean(sce).getProperty(
|
||||||
|
"VitroConnection.DataSource.endpointURI") != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// set up Pellet reasoning for the TBox
|
// set up Pellet reasoning for the TBox
|
||||||
|
|
||||||
|
@ -60,12 +67,12 @@ public class SimpleReasonerSetup implements ServletContextListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set various Pellet options for incremental consistency checking, etc.
|
// Set various Pellet options for incremental consistency checking, etc.
|
||||||
PelletOptions.DL_SAFE_RULES = true;
|
//PelletOptions.DL_SAFE_RULES = true;
|
||||||
PelletOptions.USE_COMPLETION_QUEUE = true;
|
//PelletOptions.USE_COMPLETION_QUEUE = true;
|
||||||
PelletOptions.USE_TRACING = true;
|
//PelletOptions.USE_TRACING = true;
|
||||||
PelletOptions.TRACK_BRANCH_EFFECTS = true;
|
//PelletOptions.TRACK_BRANCH_EFFECTS = true;
|
||||||
PelletOptions.USE_INCREMENTAL_CONSISTENCY = true;
|
//PelletOptions.USE_INCREMENTAL_CONSISTENCY = true;
|
||||||
PelletOptions.USE_INCREMENTAL_DELETION = true;
|
//PelletOptions.USE_INCREMENTAL_DELETION = true;
|
||||||
|
|
||||||
PelletListener pelletListener = new PelletListener(unionOms.getTBoxModel(),assertionsOms.getTBoxModel(),inferencesOms.getTBoxModel(),ReasonerConfiguration.DEFAULT);
|
PelletListener pelletListener = new PelletListener(unionOms.getTBoxModel(),assertionsOms.getTBoxModel(),inferencesOms.getTBoxModel(),ReasonerConfiguration.DEFAULT);
|
||||||
sce.getServletContext().setAttribute("pelletListener",pelletListener);
|
sce.getServletContext().setAttribute("pelletListener",pelletListener);
|
||||||
|
|
|
@ -20,16 +20,8 @@ import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
import com.hp.hpl.jena.rdf.model.Property;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
|
||||||
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
|
||||||
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
|
||||||
import com.hp.hpl.jena.vocabulary.RDF;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
|
||||||
import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater;
|
import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater;
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,485 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.ServletContextEvent;
|
|
||||||
import javax.servlet.ServletContextListener;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
|
||||||
import com.hp.hpl.jena.ontology.OntResource;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Literal;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Property;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Resource;
|
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
|
||||||
import com.hp.hpl.jena.shared.Lock;
|
|
||||||
import com.hp.hpl.jena.util.iterator.ClosableIterator;
|
|
||||||
import com.hp.hpl.jena.vocabulary.RDF;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsLoader;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert any existing User resources (up to rel 1.2) in the UserAccounts Model
|
|
||||||
* to UserAccount resources (rel 1.3 and on).
|
|
||||||
*/
|
|
||||||
public class UpdateUserAccounts implements ServletContextListener {
|
|
||||||
private static final Log log = LogFactory.getLog(UpdateUserAccounts.class);
|
|
||||||
|
|
||||||
public static final String NS = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#";
|
|
||||||
public static final String USER = NS + "User";
|
|
||||||
public static final String USER_USERNAME = NS + "username";
|
|
||||||
public static final String USER_MD5PASSWORD = NS + "md5password";
|
|
||||||
public static final String USER_OLDPASSWORD = NS + "oldpassword";
|
|
||||||
public static final String USER_FIRSTTIME = NS + "firstTime";
|
|
||||||
public static final String USER_LOGINCOUNT = NS + "loginCount";
|
|
||||||
public static final String USER_ROLE = NS + "roleURI";
|
|
||||||
public static final String USER_LASTNAME = NS + "lastName";
|
|
||||||
public static final String USER_FIRSTNAME = NS + "firstName";
|
|
||||||
public static final String MAY_EDIT_AS = NS + "mayEditAs";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void contextInitialized(ServletContextEvent sce) {
|
|
||||||
ServletContext ctx = sce.getServletContext();
|
|
||||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Updater updater = new Updater(ctx);
|
|
||||||
if (updater.isThereAnythingToDo()) {
|
|
||||||
updater.update();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.fatal("Failed to update user accounts information", e);
|
|
||||||
ss.fatal(this, "Failed to update user accounts information", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void contextDestroyed(ServletContextEvent sce) {
|
|
||||||
// Nothing to destroy.
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// The Updater class
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
private static class Updater {
|
|
||||||
private final ServletContext ctx;
|
|
||||||
private final MockUserDao userDao;
|
|
||||||
private final UserAccountsDao userAccountsDao;
|
|
||||||
|
|
||||||
public Updater(ServletContext ctx) {
|
|
||||||
this.ctx = ctx;
|
|
||||||
|
|
||||||
WebappDaoFactory wadf = (WebappDaoFactory) ctx
|
|
||||||
.getAttribute("webappDaoFactory");
|
|
||||||
userAccountsDao = wadf.getUserAccountsDao();
|
|
||||||
|
|
||||||
userDao = new MockUserDao(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If there is nothing to do, we shouldn't even create a Journal.
|
|
||||||
*/
|
|
||||||
public boolean isThereAnythingToDo() {
|
|
||||||
return !userDao.getAllUsers().isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We found some old User resources, so convert them.
|
|
||||||
*/
|
|
||||||
public void update() throws IOException {
|
|
||||||
Journal journal = new Journal(ctx);
|
|
||||||
log.info("Updating user accounts info. Journal is in '"
|
|
||||||
+ journal.getPath() + "'");
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (MockUser user : userDao.getAllUsers()) {
|
|
||||||
try {
|
|
||||||
UserAccount ua = getConvertedUser(user);
|
|
||||||
if (ua != null) {
|
|
||||||
journal.noteAlreadyConverted(user, ua);
|
|
||||||
} else {
|
|
||||||
journal.writeUser(user);
|
|
||||||
|
|
||||||
ua = convertToUserAccount(user);
|
|
||||||
userAccountsDao.insertUserAccount(ua);
|
|
||||||
journal.noteUserAccount(ua);
|
|
||||||
}
|
|
||||||
|
|
||||||
userDao.deleteUser(user);
|
|
||||||
journal.noteDeletedUser(user);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error(e, e);
|
|
||||||
journal.noteException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
journal.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private UserAccount getConvertedUser(MockUser user) {
|
|
||||||
return userAccountsDao.getUserAccountByEmail(user.getUsername());
|
|
||||||
}
|
|
||||||
|
|
||||||
private UserAccount convertToUserAccount(MockUser u) {
|
|
||||||
UserAccount ua = new UserAccount();
|
|
||||||
ua.setEmailAddress(nonNull(u.getUsername()));
|
|
||||||
ua.setFirstName(nonNull(u.getFirstName()));
|
|
||||||
ua.setLastName(nonNull(u.getLastName()));
|
|
||||||
ua.setMd5Password(nonNull(u.getMd5password()));
|
|
||||||
ua.setLoginCount(nonNegative(u.getLoginCount()));
|
|
||||||
ua.setPasswordChangeRequired(u.getLoginCount() == 0);
|
|
||||||
ua.setPasswordLinkExpires(0L);
|
|
||||||
ua.setStatus(Status.ACTIVE);
|
|
||||||
ua.setExternalAuthId(nonNull(u.getUsername()));
|
|
||||||
ua.setPermissionSetUris(translateFromRoleUri(u.getRoleURI()));
|
|
||||||
return ua;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String nonNull(String value) {
|
|
||||||
return (value == null) ? "" : value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int nonNegative(int value) {
|
|
||||||
return Math.max(0, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<String> translateFromRoleUri(String roleUri) {
|
|
||||||
String permissionSetUri = PermissionSetsLoader.URI_SELF_EDITOR;
|
|
||||||
if ("role:/4".equals(roleUri)) {
|
|
||||||
permissionSetUri = PermissionSetsLoader.URI_EDITOR;
|
|
||||||
} else if ("role:/5".equals(roleUri)) {
|
|
||||||
permissionSetUri = PermissionSetsLoader.URI_CURATOR;
|
|
||||||
} else if ("role:/50".equals(roleUri)) {
|
|
||||||
permissionSetUri = PermissionSetsLoader.URI_DBA;
|
|
||||||
}
|
|
||||||
return Collections.singleton(permissionSetUri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// The Journal class
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
private static class Journal {
|
|
||||||
private final File file;
|
|
||||||
private final PrintWriter w;
|
|
||||||
private int errorCount;
|
|
||||||
|
|
||||||
Journal(ServletContext ctx) throws IOException {
|
|
||||||
String homeDirectoryPath = ConfigurationProperties.getBean(ctx)
|
|
||||||
.getProperty("vitro.home.directory");
|
|
||||||
if (homeDirectoryPath == null) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"No value found for vitro.home.directory");
|
|
||||||
}
|
|
||||||
File homeDirectory = new File(homeDirectoryPath);
|
|
||||||
confirmIsDirectory(homeDirectory);
|
|
||||||
|
|
||||||
File upgradeDirectory = createDirectory(homeDirectory, "upgrade");
|
|
||||||
String filename = timestampedFilename("UpgradeUserAccounts", ".txt");
|
|
||||||
this.file = new File(upgradeDirectory, filename);
|
|
||||||
|
|
||||||
this.w = new PrintWriter(this.file);
|
|
||||||
|
|
||||||
w.println("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>");
|
|
||||||
w.println("PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>");
|
|
||||||
w.println("PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>");
|
|
||||||
w.println("PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#>");
|
|
||||||
w.println("");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPath() {
|
|
||||||
return file.getAbsolutePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void note(String... notes) {
|
|
||||||
w.println();
|
|
||||||
for (String note : notes) {
|
|
||||||
w.println("# " + note);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void noteAlreadyConverted(MockUser user, UserAccount ua) {
|
|
||||||
note("UserAccount '" + ua.getUri() + "' already exists for User '"
|
|
||||||
+ user.getURI() + "', " + user.getFirstName() + " "
|
|
||||||
+ user.getLastName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void writeUser(MockUser u) {
|
|
||||||
w.println();
|
|
||||||
w.println("# converting User: ");
|
|
||||||
w.println(u.getURI());
|
|
||||||
w.println(" a vitro:User ;");
|
|
||||||
w.println(" vitro:username \"" + u.getUsername() + "\" ;");
|
|
||||||
w.println(" vitro:firstName \"" + u.getFirstName() + "\" ;");
|
|
||||||
w.println(" vitro:lastName \"" + u.getLastName() + "\" ;");
|
|
||||||
w.println(" vitro:md5password \"" + u.getMd5password() + "\" ;");
|
|
||||||
w.println(" vitro:loginCount " + u.getLoginCount() + " ;");
|
|
||||||
w.println(" vitro:roleUri \"" + u.getRoleURI() + "\" ;");
|
|
||||||
w.println(" .");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void noteUserAccount(UserAccount ua) {
|
|
||||||
note("Created UserAccount '" + ua.getUri() + "' for "
|
|
||||||
+ ua.getFirstName() + " " + ua.getLastName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void noteDeletedUser(MockUser user) {
|
|
||||||
note("Delete User: '" + user.getURI() + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void noteException(Exception e) {
|
|
||||||
errorCount++;
|
|
||||||
note("Exception: " + e, " (full stack trace in Vitro log file)");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() {
|
|
||||||
w.println("upgrade complete with " + errorCount + " errors.");
|
|
||||||
w.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void confirmIsDirectory(File home) {
|
|
||||||
if (!home.exists()) {
|
|
||||||
throw new IllegalStateException("Vitro home directory '"
|
|
||||||
+ home.getPath() + "' does not exist.");
|
|
||||||
}
|
|
||||||
if (!home.isDirectory()) {
|
|
||||||
throw new IllegalStateException("Vitro home '" + home.getPath()
|
|
||||||
+ "' is not a directory.");
|
|
||||||
}
|
|
||||||
if (!home.canWrite()) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Can't write to Vitro home directory '"
|
|
||||||
+ home.getPath() + "'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private File createDirectory(File home, String name) {
|
|
||||||
File upgradeDirectory = new File(home, name);
|
|
||||||
if (!upgradeDirectory.exists()) {
|
|
||||||
upgradeDirectory.mkdirs();
|
|
||||||
if (!upgradeDirectory.exists()) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Failed to create the upgrade directory '"
|
|
||||||
+ upgradeDirectory.getPath() + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!upgradeDirectory.isDirectory()) {
|
|
||||||
throw new IllegalStateException("Upgrade directory '"
|
|
||||||
+ upgradeDirectory.getPath() + "' is not a directory.");
|
|
||||||
}
|
|
||||||
if (!upgradeDirectory.canWrite()) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Can't write to Upgrade directory '"
|
|
||||||
+ upgradeDirectory.getPath() + "'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return upgradeDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String timestampedFilename(String prefix, String suffix) {
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat(
|
|
||||||
"yyyy-MM-dd'T'HH-mm-sss");
|
|
||||||
return prefix + "." + sdf.format(new Date()) + suffix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// Classes to replace the User and UserDao, just for the upgrade.
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
private static class MockUser {
|
|
||||||
private String username;
|
|
||||||
private String roleURI;
|
|
||||||
private int loginCount;
|
|
||||||
private String md5password;
|
|
||||||
private String lastName;
|
|
||||||
private String firstName;
|
|
||||||
private String URI;
|
|
||||||
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUsername(String username) {
|
|
||||||
this.username = username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRoleURI() {
|
|
||||||
return roleURI;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRoleURI(String roleURI) {
|
|
||||||
this.roleURI = roleURI;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLoginCount() {
|
|
||||||
return loginCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLoginCount(int loginCount) {
|
|
||||||
this.loginCount = loginCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMd5password() {
|
|
||||||
return md5password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMd5password(String md5password) {
|
|
||||||
this.md5password = md5password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLastName() {
|
|
||||||
return lastName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastName(String lastName) {
|
|
||||||
this.lastName = lastName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFirstName() {
|
|
||||||
return firstName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFirstName(String firstName) {
|
|
||||||
this.firstName = firstName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getURI() {
|
|
||||||
return URI;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setURI(String uRI) {
|
|
||||||
URI = uRI;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class MockUserDao {
|
|
||||||
private final OntModel model;
|
|
||||||
|
|
||||||
public MockUserDao(ServletContext ctx) {
|
|
||||||
this.model = ModelContext.getBaseOntModelSelector(ctx)
|
|
||||||
.getUserAccountsModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<MockUser> getAllUsers() {
|
|
||||||
List<MockUser> allUsersList = new ArrayList<MockUser>();
|
|
||||||
model.enterCriticalSection(Lock.READ);
|
|
||||||
try {
|
|
||||||
ClosableIterator<Statement> userStmtIt = model.listStatements(
|
|
||||||
null, RDF.type, resource(USER));
|
|
||||||
try {
|
|
||||||
while (userStmtIt.hasNext()) {
|
|
||||||
Statement stmt = userStmtIt.next();
|
|
||||||
OntResource subjRes = stmt.getSubject().as(
|
|
||||||
OntResource.class);
|
|
||||||
allUsersList.add(userFromUserInd(subjRes));
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
userStmtIt.close();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
model.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
return allUsersList;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MockUser userFromUserInd(OntResource userInd) {
|
|
||||||
MockUser user = new MockUser();
|
|
||||||
user.setURI(userInd.getURI());
|
|
||||||
|
|
||||||
try {
|
|
||||||
user.setUsername(getStringPropertyValue(userInd, USER_USERNAME));
|
|
||||||
} catch (Exception e) {
|
|
||||||
// ignore it.
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
user.setMd5password(getStringPropertyValue(userInd,
|
|
||||||
USER_MD5PASSWORD));
|
|
||||||
} catch (Exception e) {
|
|
||||||
// ignore it.
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
user.setLoginCount(getIntegerPropertyValue(userInd,
|
|
||||||
USER_LOGINCOUNT));
|
|
||||||
} catch (Exception e) {
|
|
||||||
user.setLoginCount(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
user.setRoleURI(getStringPropertyValue(userInd, USER_ROLE));
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unable to set user role\n", e);
|
|
||||||
e.printStackTrace();
|
|
||||||
user.setRoleURI("1");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
user.setLastName(getStringPropertyValue(userInd, USER_LASTNAME));
|
|
||||||
} catch (Exception e) {
|
|
||||||
// ignore it.
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
user.setFirstName(getStringPropertyValue(userInd,
|
|
||||||
USER_FIRSTNAME));
|
|
||||||
} catch (Exception e) {
|
|
||||||
// ignore it.
|
|
||||||
}
|
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getStringPropertyValue(OntResource userInd,
|
|
||||||
String propertyUri) {
|
|
||||||
Property property = model.getProperty(propertyUri);
|
|
||||||
Literal object = (Literal) userInd.getProperty(property)
|
|
||||||
.getObject();
|
|
||||||
return object.getString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getIntegerPropertyValue(OntResource userInd,
|
|
||||||
String propertyUri) {
|
|
||||||
Property property = model.getProperty(propertyUri);
|
|
||||||
Literal object = (Literal) userInd.getProperty(property)
|
|
||||||
.getObject();
|
|
||||||
return object.getInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteUser(MockUser user) {
|
|
||||||
model.removeAll(resource(user.getURI()), null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Resource resource(String uri) {
|
|
||||||
return model.getResource(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.utils;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some static methods that help in dealing with image files.
|
|
||||||
*/
|
|
||||||
public class ImageUtil {
|
|
||||||
private static final String DEFAULT_IMAGE_PATH = "/images/placeholders/thumbnail.jpg";
|
|
||||||
|
|
||||||
private static final Map<String, String> DEFAULT_IMAGE_PATHS_BY_TYPE = initImagePaths();
|
|
||||||
|
|
||||||
private static Map<String, String> initImagePaths() {
|
|
||||||
Map<String, String> map = new HashMap<String, String>();
|
|
||||||
// No images other than the default.
|
|
||||||
return Collections.unmodifiableMap(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If we have a placeholder image for this exact type, return it. Otherwise,
|
|
||||||
* return the default.
|
|
||||||
*/
|
|
||||||
public static String getPlaceholderImagePathForType(String typeUri) {
|
|
||||||
for (Entry<String, String> entry : DEFAULT_IMAGE_PATHS_BY_TYPE
|
|
||||||
.entrySet()) {
|
|
||||||
if (typeUri.equals(entry.getKey())) {
|
|
||||||
return entry.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DEFAULT_IMAGE_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If there is a placeholder image for any type that this Individual
|
|
||||||
* instantiates, return that image. Otherwise, return the default.
|
|
||||||
*/
|
|
||||||
public static String getPlaceholderImagePathForIndividual(
|
|
||||||
VitroRequest vreq, String individualUri) {
|
|
||||||
IndividualDao indDao = vreq.getWebappDaoFactory().getIndividualDao();
|
|
||||||
for (Entry<String, String> entry : DEFAULT_IMAGE_PATHS_BY_TYPE
|
|
||||||
.entrySet()) {
|
|
||||||
if (indDao.isIndividualOfClass(entry.getKey(), individualUri)) {
|
|
||||||
return entry.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return DEFAULT_IMAGE_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Never need to instantiate this -- all methods are static. */
|
|
||||||
private ImageUtil() {
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -97,7 +97,7 @@ public class ClassGroupPageData extends DataGetterBase implements DataGetter{
|
||||||
setAllClassCountsToZero(group);
|
setAllClassCountsToZero(group);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
log.error("classgroup " + classGroupUri + " does not exist in the system");
|
throw new RuntimeException("classgroup " + classGroupUri + " does not exist in the system");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,238 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.web.images;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
import javax.servlet.ServletContextListener;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility for finding the URL of the correct Placeholder image.
|
||||||
|
*
|
||||||
|
* The mapping of image URLs to classes is created at startup, and stored in the
|
||||||
|
* ServletContext.
|
||||||
|
*/
|
||||||
|
public class PlaceholderUtil {
|
||||||
|
private static final Log log = LogFactory.getLog(PlaceholderUtil.class);
|
||||||
|
|
||||||
|
private static final String ATTRIBUTE_NAME = PlaceholderUtil.class
|
||||||
|
.getName();
|
||||||
|
private static final String PROPERTIES_FILE_PATH = "/images/placeholders/placeholders.properties";
|
||||||
|
private static final String DEFAULT_IMAGE_PATH = "/images/placeholders/thumbnail.jpg";
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Static methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we have a placeholder image for this exact type, return it. Otherwise,
|
||||||
|
* return the default.
|
||||||
|
*/
|
||||||
|
public static String getPlaceholderImagePathForType(VitroRequest vreq,
|
||||||
|
String typeUri) {
|
||||||
|
PlaceholderUtil pu = getPlaceholderUtil(vreq);
|
||||||
|
if (pu == null) {
|
||||||
|
return DEFAULT_IMAGE_PATH;
|
||||||
|
} else {
|
||||||
|
return pu.getPlaceholderImagePathForType(typeUri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there is a placeholder image for any type that this Individual
|
||||||
|
* instantiates, return that image. Otherwise, return the default.
|
||||||
|
*/
|
||||||
|
public static String getPlaceholderImagePathForIndividual(
|
||||||
|
VitroRequest vreq, String individualUri) {
|
||||||
|
PlaceholderUtil pu = getPlaceholderUtil(vreq);
|
||||||
|
if (pu == null) {
|
||||||
|
return DEFAULT_IMAGE_PATH;
|
||||||
|
} else {
|
||||||
|
IndividualDao iDao = vreq.getWebappDaoFactory().getIndividualDao();
|
||||||
|
return pu.getPlaceholderImagePathForIndividual(iDao, individualUri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the PlaceholderUtil instance from the context, or null if none. */
|
||||||
|
private static PlaceholderUtil getPlaceholderUtil(VitroRequest vreq) {
|
||||||
|
if (vreq == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ServletContext ctx = vreq.getSession().getServletContext();
|
||||||
|
Object attrib = ctx.getAttribute(ATTRIBUTE_NAME);
|
||||||
|
if (attrib instanceof PlaceholderUtil) {
|
||||||
|
return (PlaceholderUtil) attrib;
|
||||||
|
} else {
|
||||||
|
log.warn("Looked for a PlaceholerUtil, but found " + attrib);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// The object
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private final Map<String, String> mapUrlsByClass;
|
||||||
|
|
||||||
|
private PlaceholderUtil(Map<String, String> map) {
|
||||||
|
this.mapUrlsByClass = Collections
|
||||||
|
.unmodifiableMap(new HashMap<String, String>(map));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we have a placeholder image for this exact type, return it. Otherwise,
|
||||||
|
* return the default.
|
||||||
|
*/
|
||||||
|
private String getPlaceholderImagePathForType(String typeUri) {
|
||||||
|
if (typeUri == null) {
|
||||||
|
log.debug("getPlaceholderImagePathForType: typeUri is null");
|
||||||
|
return DEFAULT_IMAGE_PATH;
|
||||||
|
}
|
||||||
|
String url = mapUrlsByClass.get(typeUri);
|
||||||
|
if (url == null) {
|
||||||
|
log.debug("getPlaceholderImagePathForType: no value for '"
|
||||||
|
+ typeUri + "'");
|
||||||
|
return DEFAULT_IMAGE_PATH;
|
||||||
|
}
|
||||||
|
log.debug("getPlaceholderImagePathForType: value for '" + typeUri
|
||||||
|
+ "' is '" + url + "'");
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there is a placeholder image for any type that this Individual
|
||||||
|
* instantiates, return that image. Otherwise, return the default.
|
||||||
|
*/
|
||||||
|
private String getPlaceholderImagePathForIndividual(IndividualDao iDao,
|
||||||
|
String individualUri) {
|
||||||
|
if (individualUri == null) {
|
||||||
|
log.debug("getPlaceholderImagePathForIndividual: "
|
||||||
|
+ "individualUri is null");
|
||||||
|
return DEFAULT_IMAGE_PATH;
|
||||||
|
}
|
||||||
|
for (String classUri : mapUrlsByClass.keySet()) {
|
||||||
|
String imageUrl = mapUrlsByClass.get(classUri);
|
||||||
|
if (iDao.isIndividualOfClass(classUri, individualUri)) {
|
||||||
|
log.debug("getPlaceholderImagePathForIndividual: individual '"
|
||||||
|
+ individualUri + "' is of class '" + classUri
|
||||||
|
+ "', value is '" + imageUrl + "'");
|
||||||
|
return imageUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.debug("getPlaceholderImagePathForIndividual: individual '"
|
||||||
|
+ individualUri + "' is not of any recognized class");
|
||||||
|
return DEFAULT_IMAGE_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Classes used for setup
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
public static class Setup implements ServletContextListener {
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
ServletContext ctx = sce.getServletContext();
|
||||||
|
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||||
|
|
||||||
|
try {
|
||||||
|
File propertiesFile = confirmRealPath(ctx, PROPERTIES_FILE_PATH);
|
||||||
|
Map<String, String> map = loadPropertiesToMap(propertiesFile);
|
||||||
|
confirmImagesArePresent(ctx, map);
|
||||||
|
ctx.setAttribute(ATTRIBUTE_NAME, new PlaceholderUtil(map));
|
||||||
|
} catch (SetupException e) {
|
||||||
|
if (e.getCause() == null) {
|
||||||
|
ss.warning(this, e.getMessage());
|
||||||
|
} else {
|
||||||
|
ss.warning(this, e.getMessage(), e.getCause());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> loadPropertiesToMap(File propertiesFile)
|
||||||
|
throws SetupException {
|
||||||
|
Properties props = new Properties();
|
||||||
|
try {
|
||||||
|
props.load(new FileReader(propertiesFile));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new SetupException(
|
||||||
|
"Can't load properties from the file at '"
|
||||||
|
+ PROPERTIES_FILE_PATH
|
||||||
|
+ "'. Is it in a valid format?", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
|
for (Enumeration<Object> keys = props.keys(); keys
|
||||||
|
.hasMoreElements();) {
|
||||||
|
String key = (String) keys.nextElement();
|
||||||
|
String value = props.getProperty(key);
|
||||||
|
map.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void confirmImagesArePresent(ServletContext ctx,
|
||||||
|
Map<String, String> map) throws SetupException {
|
||||||
|
Set<String> imageUrls = new HashSet<String>();
|
||||||
|
imageUrls.add(DEFAULT_IMAGE_PATH);
|
||||||
|
imageUrls.addAll(map.values());
|
||||||
|
for (String imageUrl : imageUrls) {
|
||||||
|
confirmRealPath(ctx, imageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private File confirmRealPath(ServletContext ctx, String url)
|
||||||
|
throws SetupException {
|
||||||
|
String path = ctx.getRealPath(url);
|
||||||
|
if (path == null) {
|
||||||
|
throw new SetupException("Can't translate to real path: '"
|
||||||
|
+ url + "'");
|
||||||
|
}
|
||||||
|
File file = new File(path);
|
||||||
|
if (!file.exists()) {
|
||||||
|
throw new SetupException("No file found at '" + url + "'.");
|
||||||
|
}
|
||||||
|
if (!file.canRead()) {
|
||||||
|
throw new SetupException("Can't read the file at '" + url
|
||||||
|
+ "'.");
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent sce) {
|
||||||
|
sce.getServletContext().removeAttribute(ATTRIBUTE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SetupException extends Exception {
|
||||||
|
public SetupException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SetupException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.web.methods;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil;
|
||||||
|
import freemarker.core.Environment;
|
||||||
|
import freemarker.template.TemplateModelException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a URL for the placeholder image for this Individual, based on the VClass
|
||||||
|
* that the Individual belongs to.
|
||||||
|
*/
|
||||||
|
public class IndividualPlaceholderImageUrlMethod extends BaseTemplateMethodModel {
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
@Override
|
||||||
|
public String exec(List args) throws TemplateModelException {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
throw new TemplateModelException("Wrong number of arguments");
|
||||||
|
}
|
||||||
|
|
||||||
|
String uri = (String) args.get(0);
|
||||||
|
Environment env = Environment.getCurrentEnvironment();
|
||||||
|
HttpServletRequest request = (HttpServletRequest) env.getCustomAttribute("request");
|
||||||
|
VitroRequest vreq = new VitroRequest(request);
|
||||||
|
String imageUrl = PlaceholderUtil.getPlaceholderImagePathForIndividual(vreq, uri);
|
||||||
|
return UrlBuilder.getUrl(imageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> help(String name) {
|
||||||
|
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||||
|
|
||||||
|
map.put("return value", "The URL of the placeholder image for this individual, " +
|
||||||
|
"based on the VClasses that the individual belongs to.");
|
||||||
|
|
||||||
|
List<String>params = new ArrayList<String>();
|
||||||
|
params.add("Uri of individual");
|
||||||
|
map.put("parameters", params);
|
||||||
|
|
||||||
|
List<String> examples = new ArrayList<String>();
|
||||||
|
examples.add(name + "(individual.uri)");
|
||||||
|
map.put("examples", examples);
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -76,15 +76,11 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel {
|
||||||
return UrlBuilder.getIndividualProfileUrl(individual, vreq);
|
return UrlBuilder.getIndividualProfileUrl(individual, vreq);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For image, we use the default list view and Individual methods to reconstruct the image
|
|
||||||
// url from various triples. A custom list view would require that logic to be duplicated here.
|
|
||||||
public String getImageUrl() {
|
public String getImageUrl() {
|
||||||
String imageUrl = individual.getImageUrl();
|
String imageUrl = individual.getImageUrl();
|
||||||
return imageUrl == null ? null : getUrl(imageUrl);
|
return imageUrl == null ? null : getUrl(imageUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For image, we use the default list view and Individual methods to reconstruct the image
|
|
||||||
// url from various triples. A custom list view would require that logic to be duplicated here.
|
|
||||||
public String getThumbUrl() {
|
public String getThumbUrl() {
|
||||||
String thumbUrl = individual.getThumbUrl();
|
String thumbUrl = individual.getThumbUrl();
|
||||||
return thumbUrl == null ? null : getUrl(thumbUrl);
|
return thumbUrl == null ? null : getUrl(thumbUrl);
|
||||||
|
|
|
@ -207,7 +207,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
||||||
ObjectPropertyDao opDao = wdf.getObjectPropertyDao();
|
ObjectPropertyDao opDao = wdf.getObjectPropertyDao();
|
||||||
ObjectProperty op = opDao.getObjectPropertyByURI(propertyUri);
|
ObjectProperty op = opDao.getObjectPropertyByURI(propertyUri);
|
||||||
if (op == null) {
|
if (op == null) {
|
||||||
log.error("ObjectProperty op returned null from opDao.getObjectPropertyByURI()");
|
log.error("ObjectProperty op returned null from opDao.getObjectPropertyByURI(" + propertyUri + ")");
|
||||||
} else if (op.getURI() == null) {
|
} else if (op.getURI() == null) {
|
||||||
log.error("ObjectProperty op returned with null propertyURI from opDao.getObjectPropertyByURI()");
|
log.error("ObjectProperty op returned with null propertyURI from opDao.getObjectPropertyByURI()");
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -111,7 +111,8 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAddUrl() {
|
public String getAddUrl() {
|
||||||
return addUrl;
|
//log.info("addUrl=" + addUrl);
|
||||||
|
return (addUrl != null) ? addUrl : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> getVerboseDisplay() {
|
public Map<String, Object> getVerboseDisplay() {
|
||||||
|
|
|
@ -638,18 +638,6 @@ public class IndividualFilteringByStatementTest extends AbstractTestClass {
|
||||||
// Un-implemented methods
|
// Un-implemented methods
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSubjectOriented() {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"ObjectPropertyStatement.isSubjectOriented() not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSubjectOriented(boolean subjectOriented) {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"ObjectPropertyStatement.setSubjectOriented() not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSubjectURI(String subjectURI) {
|
public void setSubjectURI(String subjectURI) {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
|
|
|
@ -9,12 +9,16 @@ import java.util.Map;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.hp.hpl.jena.rdf.model.Literal;
|
||||||
import com.hp.hpl.jena.rdf.model.Model;
|
import com.hp.hpl.jena.rdf.model.Model;
|
||||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||||
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
import com.hp.hpl.jena.rdf.model.ResourceFactory;
|
||||||
|
import com.hp.hpl.jena.vocabulary.RDF;
|
||||||
|
import com.hp.hpl.jena.vocabulary.RDFS;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
|
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.configuration.EditConfigurationConstants;
|
||||||
|
|
||||||
public class ProcessRdfFormTest extends AbstractTestClass{
|
public class ProcessRdfFormTest extends AbstractTestClass{
|
||||||
|
|
||||||
|
@ -243,6 +247,137 @@ public class ProcessRdfFormTest extends AbstractTestClass{
|
||||||
ResourceFactory.createResource("http://test.com/uri3")));
|
ResourceFactory.createResource("http://test.com/uri3")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
//Edit existing statement
|
||||||
|
public void forcedNewResourceTest() throws Exception{
|
||||||
|
/* A very basic new statement edit. */
|
||||||
|
EditConfigurationVTwo config = new EditConfigurationVTwo();
|
||||||
|
config.setEditKey("mockEditKey");
|
||||||
|
config.setN3Required(Arrays.asList("?newRes ?test2 ?test3 ." ));
|
||||||
|
config.setUrisOnform(Arrays.asList( "newRes", "test2", "test3"));
|
||||||
|
//set uris in scope to include an existing value for new resource
|
||||||
|
config.addUrisInScope("newRes", Arrays.asList("<http://test.com/uri1>"));
|
||||||
|
config.addNewResource("newRes", null);
|
||||||
|
config.setEntityToReturnTo("?newRes");
|
||||||
|
|
||||||
|
Map<String,String[]> values = new HashMap<String, String[]>();
|
||||||
|
//value from form should indicate that newRes should have new uri created
|
||||||
|
values.put("newRes", (new String[] {EditConfigurationConstants.NEW_URI_SENTINEL}));
|
||||||
|
values.put("test2", (new String[] {"http://test.com/uri2"}));
|
||||||
|
values.put("test3", (new String[] {"http://test.com/uri3"}));
|
||||||
|
values.put("editKey", (new String[] {"mockEditKey"}));
|
||||||
|
|
||||||
|
MultiValueEditSubmission submission = new MultiValueEditSubmission(values, config);
|
||||||
|
|
||||||
|
ProcessRdfForm processor = new ProcessRdfForm(config,getMockNewURIMaker());
|
||||||
|
|
||||||
|
/* test just the N3 substitution part */
|
||||||
|
List<String>req = config.getN3Required();
|
||||||
|
List<String>opt = config.getN3Optional();
|
||||||
|
processor.subInValuesToN3( config , submission, req, opt, null , null);
|
||||||
|
assertNotNull(req);
|
||||||
|
assertTrue( req.size() > 0);
|
||||||
|
assertNotNull(req.get(0));
|
||||||
|
assertEquals("<"+NEWURI_STRING + "0> <http://test.com/uri2> <http://test.com/uri3> .", req.get(0));
|
||||||
|
|
||||||
|
assertEquals("<" + NEWURI_STRING + "0>", submission.getEntityToReturnTo());
|
||||||
|
|
||||||
|
/* test the N3 and parse RDF parts */
|
||||||
|
AdditionsAndRetractions changes = processor.process( config, submission );
|
||||||
|
|
||||||
|
assertNotNull( changes );
|
||||||
|
assertNotNull( changes.getAdditions() );
|
||||||
|
assertNotNull( changes.getRetractions());
|
||||||
|
assertTrue( changes.getAdditions().size() == 1 );
|
||||||
|
//the old uri should be removed
|
||||||
|
assertTrue( changes.getRetractions().size() == 0 );
|
||||||
|
|
||||||
|
assertTrue( changes.getAdditions().contains(
|
||||||
|
ResourceFactory.createResource(NEWURI_STRING + "0"),
|
||||||
|
ResourceFactory.createProperty("http://test.com/uri2"),
|
||||||
|
ResourceFactory.createResource("http://test.com/uri3")));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* An edit of an existing statement set where some statements need to be replaced while
|
||||||
|
* others must be retained. */
|
||||||
|
@Test
|
||||||
|
public void basicEditReplaceStatement() throws Exception{
|
||||||
|
String testXURI = "http://test.com/uriX";
|
||||||
|
String testYURI = "http://test.com/uriY";
|
||||||
|
String testZURIOrginal = "http://test.com/uriZ";
|
||||||
|
String testZURIChanged = "http://test.com/uriZChanged";
|
||||||
|
String zType = "http://test.com/TestType";
|
||||||
|
String rdfsLabel = "http://www.w3.org/2000/01/rdf-schema#label";
|
||||||
|
/* set up model */
|
||||||
|
Model model = ModelFactory.createDefaultModel();
|
||||||
|
//?x ?y ?zOriginal.
|
||||||
|
model.add(model.createResource(testXURI),
|
||||||
|
model.createProperty(testYURI),
|
||||||
|
model.createResource(testZURIOrginal));
|
||||||
|
//?zOriginal a TestType.
|
||||||
|
|
||||||
|
model.add(model.createResource(testZURIOrginal),
|
||||||
|
RDF.type,
|
||||||
|
model.createResource(zType));
|
||||||
|
//?zOriginal label "zLabel";
|
||||||
|
|
||||||
|
model.add(model.createResource(testZURIOrginal),
|
||||||
|
RDFS.label,
|
||||||
|
model.createLiteral("Z Original Label"));
|
||||||
|
|
||||||
|
/* set up EditConfiguration */
|
||||||
|
EditConfigurationVTwo config = new EditConfigurationVTwo();
|
||||||
|
config.setEditKey("mockEditKey");
|
||||||
|
config.setLiteralsOnForm(Arrays.asList("zLabel"));
|
||||||
|
config.setUrisOnform(Arrays.asList("testX", "testY", "testZ"));
|
||||||
|
config.setN3Required( Arrays.asList("?testX ?testY ?testZ ." ));
|
||||||
|
config.setN3Optional( Arrays.asList("?testZ a <" + zType + "> . \n" +
|
||||||
|
"?testZ <" + rdfsLabel + "> ?zLabel ." ));
|
||||||
|
//mimicking an existing value for the label
|
||||||
|
config.addLiteralInScope("zLabel", model.createLiteral("Z Original Label"));
|
||||||
|
|
||||||
|
config.setVarNameForSubject("testX");
|
||||||
|
config.setSubjectUri(testXURI);
|
||||||
|
|
||||||
|
config.setPredicateUri(testYURI);
|
||||||
|
config.setVarNameForPredicate("testY");
|
||||||
|
|
||||||
|
config.setObject(testZURIOrginal);
|
||||||
|
config.setVarNameForObject("testZ");
|
||||||
|
|
||||||
|
config.addField(new FieldVTwo().setName("zLabel"));
|
||||||
|
config.prepareForObjPropUpdate(model);
|
||||||
|
/* set up Submission */
|
||||||
|
Map<String,String[]> values = new HashMap<String, String[]>();
|
||||||
|
values.put("testZ", (new String[] {testZURIChanged}));
|
||||||
|
values.put("zLabel", (new String[] {"New Z Label"}));
|
||||||
|
values.put("editKey", (new String[] {"mockEditKey"}));
|
||||||
|
MultiValueEditSubmission submission = new MultiValueEditSubmission(values, config);
|
||||||
|
|
||||||
|
ProcessRdfForm processor = new ProcessRdfForm(config,getMockNewURIMaker());
|
||||||
|
AdditionsAndRetractions changes = processor.process( config, submission );
|
||||||
|
|
||||||
|
assertNotNull( changes );
|
||||||
|
assertNotNull( changes.getAdditions() );
|
||||||
|
assertNotNull( changes.getRetractions());
|
||||||
|
|
||||||
|
// assertTrue( changes.getAdditions().size() == 3 );
|
||||||
|
//only one statement should be retracted
|
||||||
|
// assertTrue( changes.getRetractions().size() == 1 );
|
||||||
|
|
||||||
|
assertTrue( changes.getAdditions().contains(
|
||||||
|
ResourceFactory.createResource(testXURI),
|
||||||
|
ResourceFactory.createProperty(testYURI),
|
||||||
|
ResourceFactory.createResource(testZURIChanged)));
|
||||||
|
|
||||||
|
assertTrue( changes.getRetractions().contains(
|
||||||
|
ResourceFactory.createResource(testXURI),
|
||||||
|
ResourceFactory.createProperty(testYURI),
|
||||||
|
ResourceFactory.createResource(testZURIOrginal)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String NEWURI_STRING= "http://newURI/n";
|
String NEWURI_STRING= "http://newURI/n";
|
||||||
|
|
||||||
|
|
|
@ -55,16 +55,6 @@ public class ObjectPropertyStatementDaoStub implements
|
||||||
.getObjectURI());
|
.getObjectURI());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSubjectOriented() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSubjectOriented(boolean subjectOriented) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSubjectURI() {
|
public String getSubjectURI() {
|
||||||
return s;
|
return s;
|
||||||
|
|
|
@ -7,7 +7,6 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.Classes2ClassesDao;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
|
||||||
|
@ -144,12 +143,6 @@ return this.objectPropertyStatementDao; }
|
||||||
// Un-implemented methods
|
// Un-implemented methods
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, String> getProperties() {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"WebappDaoFactory.getProperties() not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String checkURI(String uriStr) {
|
public String checkURI(String uriStr) {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
|
@ -169,7 +162,7 @@ return this.objectPropertyStatementDao; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getPreferredLanguages() {
|
public List<String> getPreferredLanguages() {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
"WebappDaoFactory.getPreferredLanguages() not implemented.");
|
"WebappDaoFactory.getPreferredLanguages() not implemented.");
|
||||||
}
|
}
|
||||||
|
@ -192,12 +185,6 @@ return this.objectPropertyStatementDao; }
|
||||||
"WebappDaoFactory.getUserURI() not implemented.");
|
"WebappDaoFactory.getUserURI() not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Classes2ClassesDao getClasses2ClassesDao() {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"WebappDaoFactory.getClasses2ClassesDao() not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatatypeDao getDatatypeDao() {
|
public DatatypeDao getDatatypeDao() {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
|
|
|
@ -32,4 +32,4 @@ display:Home
|
||||||
########## Data Getter ############
|
########## Data Getter ############
|
||||||
|
|
||||||
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#homeDataGetter>
|
<http://vitro.mannlib.cornell.edu/ontologies/display/1.1#homeDataGetter>
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.utils.pageDataGetter.BrowseDataGetter> .
|
a <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.BrowseDataGetter> .
|
|
@ -22,6 +22,7 @@ auth:ADMIN
|
||||||
auth:hasPermission simplePermission:SeeStartupStatus ;
|
auth:hasPermission simplePermission:SeeStartupStatus ;
|
||||||
auth:hasPermission simplePermission:UseAdvancedDataToolsPages ;
|
auth:hasPermission simplePermission:UseAdvancedDataToolsPages ;
|
||||||
auth:hasPermission simplePermission:UseMiscellaneousAdminPages ;
|
auth:hasPermission simplePermission:UseMiscellaneousAdminPages ;
|
||||||
|
auth:hasPermission simplePermission:UseSparqlQueryPage ;
|
||||||
|
|
||||||
# permissions for CURATOR and above.
|
# permissions for CURATOR and above.
|
||||||
auth:hasPermission simplePermission:EditOntology ;
|
auth:hasPermission simplePermission:EditOntology ;
|
||||||
|
|
|
@ -24,6 +24,8 @@ edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase
|
||||||
|
|
||||||
edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup
|
edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup
|
||||||
|
|
||||||
|
edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil$Setup
|
||||||
|
|
||||||
# Update the URIs on Permission Sets on UserAccounts from model (1.4) to 1.5.
|
# Update the URIs on Permission Sets on UserAccounts from model (1.4) to 1.5.
|
||||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdatePermissionSetUris
|
edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdatePermissionSetUris
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
<%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %>
|
<%@taglib prefix="vitro" uri="/WEB-INF/tlds/VitroUtils.tld" %>
|
||||||
<%@page import="edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission" %>
|
<%@page import="edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission" %>
|
||||||
<% request.setAttribute("requestedActions", SimplePermission.MANAGE_PORTALS.ACTION); %>
|
<% request.setAttribute("requestedActions", SimplePermission.USE_SPARQL_QUERY_PAGE.ACTION); %>
|
||||||
<vitro:confirmAuthorization />
|
<vitro:confirmAuthorization />
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
38
webapp/web/css/jquery_plugins/jquery.realperson.css
Normal file
38
webapp/web/css/jquery_plugins/jquery.realperson.css
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/* http://keith-wood.name/realPerson.html
|
||||||
|
Real Person Form Submission for jQuery v1.0.1.
|
||||||
|
Written by Keith Wood (kwood{at}iinet.com.au) June 2009.
|
||||||
|
Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
|
||||||
|
MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
|
||||||
|
Please attribute the author if you use it. */
|
||||||
|
|
||||||
|
/* Real Person jQuery plugin styles v1.0.1. */
|
||||||
|
.realperson-challenge {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #ddd;
|
||||||
|
width: 150px;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
.realperson-text {
|
||||||
|
font-family: "Courier New",monospace;
|
||||||
|
font-size: 6px;
|
||||||
|
font-weight: bold;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
line-height: 3px;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.realperson-regen {
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-right: 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.realpersonLabel {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
#defaultReal {
|
||||||
|
margin-left: 20px;
|
||||||
|
vertical-align: top;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 3.4 KiB |
17
webapp/web/images/placeholders/placeholders.properties
Normal file
17
webapp/web/images/placeholders/placeholders.properties
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#
|
||||||
|
# Assign placeholder images to classes of individuals.
|
||||||
|
#
|
||||||
|
# If showing an individual that has no image, a placeholder image may be shown.
|
||||||
|
# By default, the placeholder is /images/placeholders/thumbnail.jpg. However,
|
||||||
|
# this file allows you to associate classes with special placeholder images, and
|
||||||
|
# if the individual belongs to such a class, the special placeholder is shown
|
||||||
|
# instead of the default.
|
||||||
|
#
|
||||||
|
# EXAMPLE:
|
||||||
|
# http\://xmlns.com/foaf/0.1/Person = /images/placeholders/person.thumbnail.jpg
|
||||||
|
# means that any individual of type foaf:Person will be represented by
|
||||||
|
# person.thumbnail.jpg
|
||||||
|
#
|
||||||
|
# NOTE: a colon is a special character in a properties file, and must be escaped
|
||||||
|
# by a backslash.
|
||||||
|
|
|
@ -44,7 +44,7 @@ function itemElement(template, uri, label, classLabel, imageUrl, removeInfo) {
|
||||||
this.uri = uri;
|
this.uri = uri;
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.classLabel = classLabel;
|
this.classLabel = classLabel;
|
||||||
this.imageUrl = (imageUrl) ? imageUrl : imageUrl="../images/placeholders/person.thumbnail.jpg";
|
this.imageUrl = imageUrl;
|
||||||
this.removeInfo = removeInfo;
|
this.removeInfo = removeInfo;
|
||||||
|
|
||||||
this.toString = function() {
|
this.toString = function() {
|
||||||
|
|
|
@ -6,41 +6,9 @@ function ValidateForm(formName) {
|
||||||
errors = false;
|
errors = false;
|
||||||
var errorList;
|
var errorList;
|
||||||
|
|
||||||
if (document.forms[formName].RequiredFields) {
|
|
||||||
errorList = 'Please fill out the following required fields:\n';
|
|
||||||
// build array of required fields
|
|
||||||
reqStr = document.forms[formName].RequiredFields.value;
|
|
||||||
requiredFields = reqStr.split(',');
|
|
||||||
// build array holding the names of required fields as
|
|
||||||
// displayed in error box
|
|
||||||
if (document.forms[formName].RequiredFieldsNames) {
|
|
||||||
reqNameStr = document.forms[formName].RequiredFieldsNames.value;
|
|
||||||
} else {
|
|
||||||
reqNameStr = document.forms[formName].RequiredFields.value;
|
|
||||||
}
|
|
||||||
requiredNames = reqNameStr.split(',');
|
|
||||||
// Loop through form elements, checking for required fields
|
|
||||||
while ((x < document.forms[formName].elements.length)) {
|
|
||||||
if (document.forms[formName].elements[x].name == requiredFields[y]) {
|
|
||||||
if (document.forms[formName].elements[x].value == '') {
|
|
||||||
errorList += requiredNames[y] + '\n';
|
|
||||||
errors = true;
|
|
||||||
}
|
|
||||||
y++;
|
|
||||||
}
|
|
||||||
x++;
|
|
||||||
}
|
|
||||||
if (errors) {
|
|
||||||
alert(errorList);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for Email formatting
|
// Check for Email formatting
|
||||||
if (document.forms[formName].EmailFields) {
|
if (document.forms[formName].EmailFields) {
|
||||||
errorList = 'Please format your e-mail address as: \"userid@institution.edu\" or enter another complete email address';
|
errorList = '\nPlease format your e-mail address as:\n \"userid@institution.edu\" or enter another complete and valid email address';
|
||||||
// build array of required fields
|
// build array of required fields
|
||||||
emailStr = document.forms[formName].EmailFields.value;
|
emailStr = document.forms[formName].EmailFields.value;
|
||||||
emailFields = emailStr.split(',');
|
emailFields = emailStr.split(',');
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue