Merge branch 'develop' of https://github.com/vivo-project/Vitro into develop

Conflicts:
	webapp/src/edu/cornell/mannlib/vitro/webapp/edit/n3editing/configuration/generators/ManageLabelsForIndividualGenerator.java
This commit is contained in:
hudajkhan 2013-09-24 15:10:43 -04:00
commit 525267f40a
94 changed files with 3259 additions and 2407 deletions

View file

@ -1,7 +1,7 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */ /* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.utilities.testing; package edu.cornell.mannlib.vitro.utilities.testing;
import static edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel.BRIEF; import static edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel.BRIEF;
import static edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel.FULL; import static edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel.FULL;
import static edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel.MORE; import static edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel.MORE;
@ -20,327 +20,327 @@ import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunListener;
import edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel; import edu.cornell.mannlib.vitro.utilities.testing.VitroTestRunner.ReportLevel;
/** /**
* Listen to events as they come from the JUnit test runner. The events from the * Listen to events as they come from the JUnit test runner. The events from the
* lifecycle methods are broken down into semantic chunks and executed. Three * lifecycle methods are broken down into semantic chunks and executed. Three
* levels of output are available. * levels of output are available.
* *
* On the surface, JUnit treats "failures" (failed assertions) the same as * On the surface, JUnit treats "failures" (failed assertions) the same as
* "errors" (unexpected exceptions). We're going to distinguish between them. * "errors" (unexpected exceptions). We're going to distinguish between them.
* *
* @author jeb228 * @author jeb228
*/ */
public class VitroTestRunListener extends RunListener { public class VitroTestRunListener extends RunListener {
private final ReportLevel reportLevel; private final ReportLevel reportLevel;
private int classCount; private int classCount;
private int testsTotal; private int testsTotal;
private int errorsTotal; private int errorsTotal;
private int failuresTotal; private int failuresTotal;
private int ignoresTotal; private int ignoresTotal;
private long overallStartTime; private long overallStartTime;
private Class<?> currentClass; private Class<?> currentClass;
private int testsCurrentClass; private int testsCurrentClass;
private int errorsCurrentClass; private int errorsCurrentClass;
private int failuresCurrentClass; private int failuresCurrentClass;
private int ignoresCurrentClass; private int ignoresCurrentClass;
private long classStartTime; private long classStartTime;
private String currentTest; private String currentTest;
private boolean testHadError; private boolean testHadError;
private boolean testFailed; private boolean testFailed;
private boolean testIgnored; private boolean testIgnored;
private long testStartTime; private long testStartTime;
public VitroTestRunListener(ReportLevel reportLevel) { public VitroTestRunListener(ReportLevel reportLevel) {
this.reportLevel = reportLevel; this.reportLevel = reportLevel;
} }
/** Did any of the tests fail or have errors? */ /** Did any of the tests fail or have errors? */
public boolean didEverythingPass() { public boolean didEverythingPass() {
return (failuresTotal == 0) && (errorsTotal == 0); return (failuresTotal == 0) && (errorsTotal == 0);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Life-cycle methods that will be called by the test runner. // Life-cycle methods that will be called by the test runner.
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@Override @Override
public void testRunStarted(Description description) throws Exception { public void testRunStarted(Description description) throws Exception {
openTestRun(); openTestRun();
reportTestRunStart(); reportTestRunStart();
} }
@Override @Override
public void testStarted(Description description) throws Exception { public void testStarted(Description description) throws Exception {
if (currentClass != description.getTestClass()) { if (currentClass != description.getTestClass()) {
if (currentClass != null) { if (currentClass != null) {
closeCurrentClass(); closeCurrentClass();
reportCurrentClass(); reportCurrentClass();
} }
openCurrentClass(description); openCurrentClass(description);
reportCurrentClassStart(); reportCurrentClassStart();
} }
openCurrentTest(description); openCurrentTest(description);
} }
@Override @Override
public void testAssumptionFailure(Failure failure) { public void testAssumptionFailure(Failure failure) {
if (isError(failure)) { if (isError(failure)) {
testHadError = true; testHadError = true;
reportError(failure); reportError(failure);
} else { } else {
testFailed = true; testFailed = true;
reportFailure(failure); reportFailure(failure);
} }
} }
@Override @Override
public void testFailure(Failure failure) throws Exception { public void testFailure(Failure failure) throws Exception {
if (isError(failure)) { if (isError(failure)) {
testHadError = true; testHadError = true;
reportError(failure); reportError(failure);
} else { } else {
testFailed = true; testFailed = true;
reportFailure(failure); reportFailure(failure);
} }
} }
@Override @Override
public void testFinished(Description description) throws Exception { public void testFinished(Description description) throws Exception {
closeCurrentTest(); closeCurrentTest();
reportCurrentTest(); reportCurrentTest();
} }
@Override @Override
public void testIgnored(Description description) throws Exception { public void testIgnored(Description description) throws Exception {
testStarted(description); testStarted(description);
testIgnored = true; testIgnored = true;
testFinished(description); testFinished(description);
} }
@Override @Override
public void testRunFinished(Result result) throws Exception { public void testRunFinished(Result result) throws Exception {
if (currentClass != null) { if (currentClass != null) {
closeCurrentClass(); closeCurrentClass();
reportCurrentClass(); reportCurrentClass();
} }
closeTestRun(); closeTestRun();
reportTestRun(); reportTestRun();
System.out.println(); System.out.println();
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Handling the logical events. // Handling the logical events.
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
private void openTestRun() { private void openTestRun() {
overallStartTime = System.currentTimeMillis(); overallStartTime = System.currentTimeMillis();
} }
private void closeTestRun() { private void closeTestRun() {
// Nothing to close. // Nothing to close.
} }
private void reportTestRunStart() { private void reportTestRunStart() {
if (reportLevel == FULL) { if (reportLevel == FULL) {
System.out System.out
.println("Starting test run at " + time(overallStartTime)); .println("Starting test run at " + time(overallStartTime));
System.out.println(); System.out.println();
} }
if (reportLevel == MORE) { if (reportLevel == MORE) {
System.out System.out
.println("Starting test run at " + time(overallStartTime)); .println("Starting test run at " + time(overallStartTime));
System.out.println(); System.out.println();
System.out.println("Tests Pass Error Fail Ignore Seconds"); System.out.println("Tests Pass Error Fail Ignore Seconds");
} }
} }
private void reportTestRun() { private void reportTestRun() {
int successes = testsTotal - errorsTotal - failuresTotal - ignoresTotal; int successes = testsTotal - errorsTotal - failuresTotal - ignoresTotal;
if (reportLevel != BRIEF) { if (reportLevel != BRIEF) {
System.out.println(); System.out.println();
} }
System.out.format( System.out.format(
"Tests Pass Error Fail Ignore Seconds TOTAL (%d classes)\n", "Tests Pass Error Fail Ignore Seconds TOTAL (%d classes)\n",
classCount); classCount);
System.out.format(" %4d %4d %4d %4d %4d %6s\n", testsTotal, System.out.format(" %4d %4d %4d %4d %4d %6s\n", testsTotal,
successes, errorsTotal, failuresTotal, ignoresTotal, successes, errorsTotal, failuresTotal, ignoresTotal,
elapsed(overallStartTime)); elapsed(overallStartTime));
if (reportLevel != BRIEF) { if (reportLevel != BRIEF) {
System.out.println("Ending test run at " System.out.println("Ending test run at "
+ time(System.currentTimeMillis())); + time(System.currentTimeMillis()));
} }
} }
private void openCurrentClass(Description description) { private void openCurrentClass(Description description) {
currentClass = description.getTestClass(); currentClass = description.getTestClass();
classStartTime = System.currentTimeMillis(); classStartTime = System.currentTimeMillis();
testsCurrentClass = 0; testsCurrentClass = 0;
errorsCurrentClass = 0; errorsCurrentClass = 0;
failuresCurrentClass = 0; failuresCurrentClass = 0;
ignoresCurrentClass = 0; ignoresCurrentClass = 0;
} }
private void closeCurrentClass() { private void closeCurrentClass() {
classCount++; classCount++;
testsTotal += testsCurrentClass; testsTotal += testsCurrentClass;
errorsTotal += errorsCurrentClass; errorsTotal += errorsCurrentClass;
failuresTotal += failuresCurrentClass; failuresTotal += failuresCurrentClass;
ignoresTotal += ignoresCurrentClass; ignoresTotal += ignoresCurrentClass;
} }
private void reportCurrentClassStart() { private void reportCurrentClassStart() {
if (reportLevel == FULL) { if (reportLevel == FULL) {
System.out.format("Tests Pass Error Fail Ignore Seconds %s\n", System.out.format("Tests Pass Error Fail Ignore Seconds %s\n",
currentClass.getName()); currentClass.getName());
} }
} }
private void reportCurrentClass() { private void reportCurrentClass() {
int successes = testsCurrentClass - errorsCurrentClass int successes = testsCurrentClass - errorsCurrentClass
- failuresCurrentClass - ignoresCurrentClass; - failuresCurrentClass - ignoresCurrentClass;
if (reportLevel == MORE) { if (reportLevel == MORE) {
System.out.format(" %4d %4d %4d %4d %4d %6s %s\n", System.out.format(" %4d %4d %4d %4d %4d %6s %s\n",
testsCurrentClass, successes, errorsCurrentClass, testsCurrentClass, successes, errorsCurrentClass,
failuresCurrentClass, ignoresCurrentClass, failuresCurrentClass, ignoresCurrentClass,
elapsed(classStartTime), currentClass.getSimpleName()); elapsed(classStartTime), currentClass.getSimpleName());
} }
if (reportLevel == FULL) { if (reportLevel == FULL) {
System.out.println("-----------------------------------"); System.out.println("-----------------------------------");
System.out.format(" %4d %4d %4d %4d %4d %6s\n", System.out.format(" %4d %4d %4d %4d %4d %6s\n",
testsCurrentClass, successes, errorsCurrentClass, testsCurrentClass, successes, errorsCurrentClass,
failuresCurrentClass, ignoresCurrentClass, failuresCurrentClass, ignoresCurrentClass,
elapsed(classStartTime)); elapsed(classStartTime));
System.out.println(); System.out.println();
} }
} }
private void openCurrentTest(Description description) { private void openCurrentTest(Description description) {
currentTest = description.getMethodName(); currentTest = description.getMethodName();
testHadError = false; testHadError = false;
testFailed = false; testFailed = false;
testIgnored = false; testIgnored = false;
testStartTime = System.currentTimeMillis(); testStartTime = System.currentTimeMillis();
} }
private void closeCurrentTest() { private void closeCurrentTest() {
if (testHadError) { if (testHadError) {
errorsCurrentClass++; errorsCurrentClass++;
} }
if (testFailed) { if (testFailed) {
failuresCurrentClass++; failuresCurrentClass++;
} }
if (testIgnored) { if (testIgnored) {
ignoresCurrentClass++; ignoresCurrentClass++;
} }
testsCurrentClass++; testsCurrentClass++;
} }
private boolean isError(Failure failure) { private boolean isError(Failure failure) {
Throwable throwable = failure.getException(); Throwable throwable = failure.getException();
return (throwable != null) && !(throwable instanceof AssertionError); return (throwable != null) && !(throwable instanceof AssertionError);
} }
private void reportError(Failure error) { private void reportError(Failure error) {
Description description = error.getDescription(); Description description = error.getDescription();
String methodName = description.getMethodName(); String methodName = description.getMethodName();
String className = description.getTestClass().getName(); String className = description.getTestClass().getName();
String message = error.getMessage(); String message = error.getMessage();
System.out.format("EXCEPTION: test %s() in %s: %s\n", System.out.format("EXCEPTION: test %s() in %s: %s\n",
methodName, className, message); methodName, className, message);
System.out.println(formatStackTrace(error.getException())); System.out.println(formatStackTrace(error.getException()));
} }
private void reportFailure(Failure failure) { private void reportFailure(Failure failure) {
Description description = failure.getDescription(); Description description = failure.getDescription();
String methodName = description.getMethodName(); String methodName = description.getMethodName();
String className = description.getTestClass().getName(); String className = description.getTestClass().getName();
String message = failure.getMessage(); String message = failure.getMessage();
System.out.format("TEST FAILED: test %s() in %s: %s\n", methodName, System.out.format("TEST FAILED: test %s() in %s: %s\n", methodName,
className, message); className, message);
} }
private void reportCurrentTest() { private void reportCurrentTest() {
if (reportLevel == FULL) { if (reportLevel == FULL) {
char passFlag = (testIgnored | testFailed | testHadError) ? ' ' char passFlag = (testIgnored | testFailed | testHadError) ? ' '
: '1'; : '1';
char errorFlag = testHadError ? '1' : ' '; char errorFlag = testHadError ? '1' : ' ';
char failFlag = testFailed ? '1' : ' '; char failFlag = testFailed ? '1' : ' ';
char ignoreFlag = testIgnored ? '1' : ' '; char ignoreFlag = testIgnored ? '1' : ' ';
System.out.format( System.out.format(
" %c %c %c %c %6s %s()\n", " %c %c %c %c %6s %s()\n",
passFlag, errorFlag, failFlag, ignoreFlag, passFlag, errorFlag, failFlag, ignoreFlag,
elapsed(testStartTime), currentTest); elapsed(testStartTime), currentTest);
} }
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Formatting methods. // Formatting methods.
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
private final SimpleDateFormat formatter = new SimpleDateFormat( private final SimpleDateFormat formatter = new SimpleDateFormat(
"HH:mm:ss 'on' MMM dd, yyyy"); "HH:mm:ss 'on' MMM dd, yyyy");
private String time(long time) { private String time(long time) {
return formatter.format(new Date(time)); return formatter.format(new Date(time));
} }
/** Show elapsed time in 6 columns. */ /** Show elapsed time in 6 columns. */
private String elapsed(long start) { private String elapsed(long start) {
long interval = System.currentTimeMillis() - start; long interval = System.currentTimeMillis() - start;
return String.format("%6.2f", ((float) interval) / 1000.0); return String.format("%6.2f", ((float) interval) / 1000.0);
} }
/** /**
* Trim the stack trace: don't show the line saying "23 more", and don't * Trim the stack trace: don't show the line saying "23 more", and don't
* show the lines about org.junit or java.lang.reflect or sun.reflect. * show the lines about org.junit or java.lang.reflect or sun.reflect.
* *
* Once we hit some "client code", we won't trim any futher lines even if * Once we hit some "client code", we won't trim any futher lines even if
* they belong to org.junit, or the others. * they belong to org.junit, or the others.
* *
* If we have nested exceptions, the process repeats for each "Caused by" * If we have nested exceptions, the process repeats for each "Caused by"
* section. * section.
*/ */
private String formatStackTrace(Throwable throwable) { private String formatStackTrace(Throwable throwable) {
StringWriter w = new StringWriter(); StringWriter w = new StringWriter();
throwable.printStackTrace(new PrintWriter(w)); throwable.printStackTrace(new PrintWriter(w));
String[] lineArray = w.toString().split("\\n"); String[] lineArray = w.toString().split("\\n");
List<String> lines = new ArrayList<String>(Arrays.asList(lineArray)); List<String> lines = new ArrayList<String>(Arrays.asList(lineArray));
boolean removing = true; boolean removing = true;
for (int i = lines.size() - 1; i > 0; i--) { for (int i = lines.size() - 1; i > 0; i--) {
String line = lines.get(i); String line = lines.get(i);
if (removing) { if (removing) {
if (line.matches("\\s*[\\.\\s\\d]+more\\s*") if (line.matches("\\s*[\\.\\s\\d]+more\\s*")
|| line.contains("at " || line.contains("at "
+ VitroTestRunner.class.getName()) + VitroTestRunner.class.getName())
|| line.contains("at org.junit.") || line.contains("at org.junit.")
|| line.contains("at java.lang.reflect.") || line.contains("at java.lang.reflect.")
|| line.contains("at sun.reflect.")) { || line.contains("at sun.reflect.")) {
lines.remove(line); lines.remove(line);
} else { } else {
removing = false; removing = false;
} }
} else { } else {
if (line.contains("Caused by: ")) { if (line.contains("Caused by: ")) {
removing = true; removing = true;
} }
} }
} }
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
for (String line : lines) { for (String line : lines) {
result.append(line).append('\n'); result.append(line).append('\n');
} }
return result.toString().trim(); return result.toString().trim();
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -35,7 +35,7 @@ display:InternalClassesPage a owl:Class .
display:DataGetter a owl:Class . display:DataGetter a owl:Class .
display:RequiredAction a owl:Class ; display:RequiredAction a owl:Class ;
rdfs:comment "Represents a action that may need authorization to perform.". rdfs:comment "Represents a action that may need authorization to perform." .
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlQueryDataGetter> <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.SparqlQueryDataGetter>
a owl:Class ; a owl:Class ;
@ -55,11 +55,11 @@ display:RequiredAction a owl:Class ;
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.ClassGroupPageData> <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.ClassGroupPageData>
a owl:Class ; a owl:Class ;
rdfs:comment "A data getter for a VClassGroup page". rdfs:comment "A data getter for a VClassGroup page" .
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter> <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.FixedHTMLDataGetter>
a owl:Class ; a owl:Class ;
rdfs:comment "A data getter for a Fixed piece of HTML stored in RDF". rdfs:comment "A data getter for a Fixed piece of HTML stored in RDF" .
<java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.IndividualsForClassesDataGetter> <java:edu.cornell.mannlib.vitro.webapp.utils.dataGetter.IndividualsForClassesDataGetter>
a owl:Class . a owl:Class .

View file

@ -2,28 +2,37 @@
package edu.cornell.mannlib.vedit.validator.impl; package edu.cornell.mannlib.vedit.validator.impl;
import edu.cornell.mannlib.vedit.validator.Validator; import java.util.Iterator;
import com.hp.hpl.jena.iri.IRI;
import com.hp.hpl.jena.iri.IRIFactory;
import com.hp.hpl.jena.iri.Violation;
import edu.cornell.mannlib.vedit.validator.ValidationObject; import edu.cornell.mannlib.vedit.validator.ValidationObject;
import java.util.regex.*; import edu.cornell.mannlib.vedit.validator.Validator;
public class UrlValidator implements Validator { public class UrlValidator implements Validator {
public ValidationObject validate (Object obj) throws IllegalArgumentException { public ValidationObject validate (Object obj) throws IllegalArgumentException {
ValidationObject vo = new ValidationObject(); ValidationObject vo = new ValidationObject();
String theString = null;
if (!(obj instanceof String)){ if (!(obj instanceof String)){
throw new IllegalArgumentException("Expected instance of String"); throw new IllegalArgumentException("Expected instance of String");
} }
Pattern pat = Pattern.compile("[a-z]{3,5}*://.*\\.[a-z]{2,4}"); IRIFactory factory = IRIFactory.jenaImplementation();
Matcher mat = pat.matcher(theString); IRI iri = factory.create((String) obj);
if (mat.matches()){ if (iri.hasViolation(false) ) {
vo.setValid(true); String errorStr = "";
} else { Iterator<Violation> violIt = iri.violations(false);
while(violIt.hasNext()) {
errorStr += violIt.next().getShortMessage() + " ";
}
vo.setValid(false); vo.setValid(false);
vo.setMessage("Please enter a valid URL"); vo.setMessage("Please enter a valid URL. " + errorStr);
} else {
vo.setValid(true);
} }
vo.setValidatedObject(obj); vo.setValidatedObject(obj);

View file

@ -16,6 +16,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/** /**
* Is the user authorized to display properties that are marked as restricted to * Is the user authorized to display properties that are marked as restricted to
@ -82,7 +83,7 @@ public class DisplayByRolePermission extends Permission {
*/ */
private boolean isAuthorized(DisplayDataProperty action) { private boolean isAuthorized(DisplayDataProperty action) {
String predicateUri = action.getDataProperty().getURI(); String predicateUri = action.getDataProperty().getURI();
return canDisplayPredicate(predicateUri); return canDisplayPredicate(new Property(predicateUri));
} }
/** /**
@ -90,8 +91,7 @@ public class DisplayByRolePermission extends Permission {
* predicate. * predicate.
*/ */
private boolean isAuthorized(DisplayObjectProperty action) { private boolean isAuthorized(DisplayObjectProperty action) {
String predicateUri = action.getObjectProperty().getURI(); return canDisplayPredicate(action.getObjectProperty());
return canDisplayPredicate(predicateUri);
} }
/** /**
@ -103,7 +103,7 @@ public class DisplayByRolePermission extends Permission {
String subjectUri = stmt.getIndividualURI(); String subjectUri = stmt.getIndividualURI();
String predicateUri = stmt.getDatapropURI(); String predicateUri = stmt.getDatapropURI();
return canDisplayResource(subjectUri) return canDisplayResource(subjectUri)
&& canDisplayPredicate(predicateUri); && canDisplayPredicate(new Property(predicateUri));
} }
/** /**
@ -113,12 +113,10 @@ public class DisplayByRolePermission extends Permission {
private boolean isAuthorized(DisplayObjectPropertyStatement action) { private boolean isAuthorized(DisplayObjectPropertyStatement action) {
ObjectPropertyStatement stmt = action.getObjectPropertyStatement(); ObjectPropertyStatement stmt = action.getObjectPropertyStatement();
String subjectUri = stmt.getSubjectURI(); String subjectUri = stmt.getSubjectURI();
String predicateUri = stmt.getPropertyURI(); Property predicate = stmt.getProperty();
String rangeUri = (stmt.getProperty() == null) ? null
: stmt.getProperty().getRangeVClassURI();
String objectUri = stmt.getObjectURI(); String objectUri = stmt.getObjectURI();
return canDisplayResource(subjectUri) return canDisplayResource(subjectUri)
&& canDisplayPredicate(predicateUri, rangeUri) && canDisplayPredicate(predicate)
&& canDisplayResource(objectUri); && canDisplayResource(objectUri);
} }
@ -126,14 +124,10 @@ public class DisplayByRolePermission extends Permission {
return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource( return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource(
resourceUri, this.roleLevel); resourceUri, this.roleLevel);
} }
private boolean canDisplayPredicate(String predicateUri) {
return canDisplayPredicate(predicateUri, null);
}
private boolean canDisplayPredicate(String predicateUri, String rangeUri) { private boolean canDisplayPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx) return PropertyRestrictionPolicyHelper.getBean(ctx)
.canDisplayPredicate(predicateUri, rangeUri, this.roleLevel); .canDisplayPredicate(predicate, this.roleLevel);
} }
@Override @Override

View file

@ -12,6 +12,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/** /**
* Is the user authorized to edit properties that are marked as restricted to a * Is the user authorized to edit properties that are marked as restricted to a
@ -78,9 +79,9 @@ public class EditByRolePermission extends Permission {
*/ */
private boolean isAuthorized(AbstractDataPropertyStatementAction action) { private boolean isAuthorized(AbstractDataPropertyStatementAction action) {
String subjectUri = action.getSubjectUri(); String subjectUri = action.getSubjectUri();
String predicateUri = action.getPredicateUri(); Property predicate = action.getPredicate();
return canModifyResource(subjectUri) return canModifyResource(subjectUri)
&& canModifyPredicate(predicateUri); && canModifyPredicate(predicate);
} }
/** /**
@ -89,10 +90,10 @@ public class EditByRolePermission extends Permission {
*/ */
private boolean isAuthorized(AbstractObjectPropertyStatementAction action) { private boolean isAuthorized(AbstractObjectPropertyStatementAction action) {
String subjectUri = action.getSubjectUri(); String subjectUri = action.getSubjectUri();
String predicateUri = action.getPredicateUri(); Property predicate = action.getPredicate();
String objectUri = action.getObjectUri(); String objectUri = action.getObjectUri();
return canModifyResource(subjectUri) return canModifyResource(subjectUri)
&& canModifyPredicate(predicateUri) && canModifyPredicate(predicate)
&& canModifyResource(objectUri); && canModifyResource(objectUri);
} }
@ -101,9 +102,9 @@ public class EditByRolePermission extends Permission {
resourceUri, roleLevel); resourceUri, roleLevel);
} }
private boolean canModifyPredicate(String predicateUri) { private boolean canModifyPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
predicateUri, roleLevel); predicate, roleLevel);
} }
@Override @Override

View file

@ -8,6 +8,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPoli
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/** /**
* A base class with utility methods for policies involving self-editing. * A base class with utility methods for policies involving self-editing.
@ -26,9 +27,9 @@ public abstract class BaseSelfEditingPolicy {
uri, roleLevel); uri, roleLevel);
} }
protected boolean canModifyPredicate(String uri) { protected boolean canModifyPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
uri, roleLevel); predicate, roleLevel);
} }
protected PolicyDecision cantModifyResource(String uri) { protected PolicyDecision cantModifyResource(String uri) {
@ -36,9 +37,9 @@ public abstract class BaseSelfEditingPolicy {
+ uri); + uri);
} }
protected PolicyDecision cantModifyPredicate(String uri) { protected PolicyDecision cantModifyPredicate(Property predicate) {
return inconclusiveDecision("No access to admin predicates; cannot modify " return inconclusiveDecision("No access to admin predicates; cannot modify "
+ uri); + predicate.getURI());
} }
protected PolicyDecision userNotAuthorizedToStatement() { protected PolicyDecision userNotAuthorizedToStatement() {

View file

@ -23,6 +23,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/** /**
* Permit display of various data if it relates to the user's associated * Permit display of various data if it relates to the user's associated
@ -92,14 +93,14 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface {
Collection<String> individuals) { Collection<String> individuals) {
DataPropertyStatement stmt = action.getDataPropertyStatement(); DataPropertyStatement stmt = action.getDataPropertyStatement();
String subjectUri = stmt.getIndividualURI(); String subjectUri = stmt.getIndividualURI();
String predicateUri = stmt.getDatapropURI(); Property predicate = new Property(stmt.getDatapropURI());
if (canDisplayResource(subjectUri) && canDisplayPredicate(predicateUri) if (canDisplayResource(subjectUri) && canDisplayPredicate(predicate)
&& isAboutAssociatedIndividual(individuals, stmt)) { && isAboutAssociatedIndividual(individuals, stmt)) {
return authorized("user may view DataPropertyStatement " return authorized("user may view DataPropertyStatement "
+ subjectUri + " ==> " + predicateUri); + subjectUri + " ==> " + predicate.getURI());
} else { } else {
return defaultDecision("user may not view DataPropertyStatement " return defaultDecision("user may not view DataPropertyStatement "
+ subjectUri + " ==> " + predicateUri); + subjectUri + " ==> " + predicate.getURI());
} }
} }
@ -115,7 +116,8 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface {
String subjectUri = stmt.getSubjectURI(); String subjectUri = stmt.getSubjectURI();
String predicateUri = stmt.getPropertyURI(); String predicateUri = stmt.getPropertyURI();
String objectUri = stmt.getObjectURI(); String objectUri = stmt.getObjectURI();
if (canDisplayResource(subjectUri) && canDisplayPredicate(predicateUri) if (canDisplayResource(subjectUri) && canDisplayPredicate(new Property
(predicateUri))
&& canDisplayResource(objectUri) && canDisplayResource(objectUri)
&& isAboutAssociatedIndividual(individuals, stmt)) { && isAboutAssociatedIndividual(individuals, stmt)) {
return authorized("user may view ObjectPropertyStatement " return authorized("user may view ObjectPropertyStatement "
@ -143,9 +145,9 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface {
uri, RoleLevel.SELF); uri, RoleLevel.SELF);
} }
private boolean canDisplayPredicate(String uri) { private boolean canDisplayPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx) return PropertyRestrictionPolicyHelper.getBean(ctx)
.canDisplayPredicate(uri, RoleLevel.SELF); .canDisplayPredicate(predicate, RoleLevel.SELF);
} }
private boolean isAboutAssociatedIndividual(Collection<String> selves, private boolean isAboutAssociatedIndividual(Collection<String> selves,

View file

@ -35,6 +35,8 @@ public class PermissionsPolicy implements PolicyIface {
log.debug("Permission " + p + " approves request " + whatToAuth); log.debug("Permission " + p + " approves request " + whatToAuth);
return new BasicPolicyDecision(Authorization.AUTHORIZED, return new BasicPolicyDecision(Authorization.AUTHORIZED,
"PermissionsPolicy: approved by " + p); "PermissionsPolicy: approved by " + p);
} else {
log.trace("Permission " + p + " denies request " + whatToAuth);
} }
} }
log.debug("No permission will approve " + whatToAuth); log.debug("No permission will approve " + whatToAuth);

View file

@ -122,7 +122,8 @@ public class PolicyHelper {
} }
Resource subject = stmt.getSubject(); Resource subject = stmt.getSubject();
Property predicate = stmt.getPredicate(); edu.cornell.mannlib.vitro.webapp.beans.Property predicate =
new edu.cornell.mannlib.vitro.webapp.beans.Property(stmt.getPredicate().getURI());
RDFNode objectNode = stmt.getObject(); RDFNode objectNode = stmt.getObject();
if ((subject == null) || (predicate == null) || (objectNode == null)) { if ((subject == null) || (predicate == null) || (objectNode == null)) {
return false; return false;
@ -131,7 +132,7 @@ public class PolicyHelper {
RequestedAction action; RequestedAction action;
if (objectNode.isResource()) { if (objectNode.isResource()) {
action = new AddObjectPropertyStatement(modelToBeModified, action = new AddObjectPropertyStatement(modelToBeModified,
subject.getURI(), predicate.getURI(), objectNode subject.getURI(), predicate, objectNode
.asResource().getURI()); .asResource().getURI());
} else { } else {
action = new AddDataPropertyStatement(modelToBeModified, action = new AddDataPropertyStatement(modelToBeModified,
@ -153,7 +154,9 @@ public class PolicyHelper {
} }
Resource subject = stmt.getSubject(); Resource subject = stmt.getSubject();
Property predicate = stmt.getPredicate(); edu.cornell.mannlib.vitro.webapp.beans.Property predicate =
new edu.cornell.mannlib.vitro.webapp.beans.Property();
predicate.setURI(stmt.getPredicate().getURI());
RDFNode objectNode = stmt.getObject(); RDFNode objectNode = stmt.getObject();
if ((subject == null) || (predicate == null) || (objectNode == null)) { if ((subject == null) || (predicate == null) || (objectNode == null)) {
return false; return false;
@ -162,7 +165,7 @@ public class PolicyHelper {
RequestedAction action; RequestedAction action;
if (objectNode.isResource()) { if (objectNode.isResource()) {
action = new DropObjectPropertyStatement(modelToBeModified, action = new DropObjectPropertyStatement(modelToBeModified,
subject.getURI(), predicate.getURI(), objectNode subject.getURI(), predicate, objectNode
.asResource().getURI()); .asResource().getURI());
} else { } else {
action = new DropDataPropertyStatement(modelToBeModified, action = new DropDataPropertyStatement(modelToBeModified,

View file

@ -16,6 +16,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDa
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.AbstractResourceAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.AbstractResourceAction;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/** /**
* Policy to use for Vivo Self-Editing based on NetId for use at Cornell. All * Policy to use for Vivo Self-Editing based on NetId for use at Cornell. All
@ -69,7 +70,7 @@ public class SelfEditingPolicy extends BaseSelfEditingPolicy implements
private PolicyDecision isAuthorizedForObjectPropertyAction( private PolicyDecision isAuthorizedForObjectPropertyAction(
List<String> userUris, AbstractObjectPropertyStatementAction action) { List<String> userUris, AbstractObjectPropertyStatementAction action) {
String subject = action.getSubjectUri(); String subject = action.getSubjectUri();
String predicate = action.getPredicateUri(); Property predicate = action.getPredicate();
String object = action.getObjectUri(); String object = action.getObjectUri();
if (!canModifyResource(subject)) { if (!canModifyResource(subject)) {
@ -96,7 +97,7 @@ public class SelfEditingPolicy extends BaseSelfEditingPolicy implements
private PolicyDecision isAuthorizedForDataPropertyAction( private PolicyDecision isAuthorizedForDataPropertyAction(
List<String> userUris, AbstractDataPropertyStatementAction action) { List<String> userUris, AbstractDataPropertyStatementAction action) {
String subject = action.getSubjectUri(); String subject = action.getSubjectUri();
String predicate = action.getPredicateUri(); Property predicate = action.getPredicate();
if (!canModifyResource(subject)) { if (!canModifyResource(subject)) {
return cantModifyResource(subject); return cantModifyResource(subject);

View file

@ -7,6 +7,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
@ -17,6 +18,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; 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.query.Query; import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryExecutionFactory;
@ -24,18 +26,23 @@ import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement; 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.rdf.model.impl.Util; import com.hp.hpl.jena.rdf.model.impl.Util;
import com.hp.hpl.jena.sdb.util.Pair;
import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.vocabulary.OWL;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
import edu.cornell.mannlib.vitro.webapp.utils.ApplicationConfigurationOntologyUtils;
/** /**
* Assists the role-based policies in determining whether a property or resource * Assists the role-based policies in determining whether a property or resource
@ -108,17 +115,22 @@ public class PropertyRestrictionPolicyHelper {
Model displayModel) { Model displayModel) {
Map<String, RoleLevel> displayThresholdMap = new HashMap<String, RoleLevel>(); Map<Pair<String, Pair<String,String>>, RoleLevel> displayThresholdMap =
Map<String, RoleLevel> modifyThresholdMap = new HashMap<String, RoleLevel>(); new HashMap<Pair<String, Pair<String,String>>, RoleLevel>();
Map<Pair<String, Pair<String,String>>, RoleLevel> modifyThresholdMap =
new HashMap<Pair<String, Pair<String,String>>, RoleLevel>();
OntModel union = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM,
ModelFactory.createUnion(displayModel, model));
populateThresholdMap(union, displayThresholdMap,
VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT);
populateThresholdMap(
union,
modifyThresholdMap,
VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT);
if (model != null) {
populateThresholdMap(model, displayThresholdMap,
VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT);
populateThresholdMap(
model,
modifyThresholdMap,
VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT);
}
PropertyRestrictionPolicyHelper bean = new PropertyRestrictionPolicyHelper( PropertyRestrictionPolicyHelper bean = new PropertyRestrictionPolicyHelper(
PROHIBITED_NAMESPACES, PERMITTED_EXCEPTIONS, PROHIBITED_NAMESPACES, PERMITTED_EXCEPTIONS,
@ -127,29 +139,85 @@ public class PropertyRestrictionPolicyHelper {
return bean; return bean;
} }
private RoleLevel getModifyThreshold(Property property) {
return getThreshold(property, modifyThresholdMap);
}
private RoleLevel getThreshold(Property property,
Map<Pair<String, Pair<String,String>>, RoleLevel>
thresholdMap) {
if (property.getURI() == null) {
return RoleLevel.NOBODY;
}
RoleLevel roleLevel = getRoleLevelFromMap(
property.getDomainVClassURI(), property.getURI(),
property.getRangeVClassURI(), thresholdMap);
if (roleLevel == null) {
roleLevel = getRoleLevelFromMap(
OWL.Thing.getURI(), property.getURI(), OWL.Thing.getURI(),
thresholdMap);
}
return roleLevel;
}
private RoleLevel getRoleLevelFromMap(String domainURI,
String predicateURI,
String rangeURI,
Map<Pair<String, Pair<String,String>>,
RoleLevel> map) {
return map.get(
new Pair<String, Pair<String,String>>(
domainURI, new Pair<String,String>(
predicateURI, rangeURI)));
}
/** /**
* Find all the resources that possess this property, and map the resource * Find all the resources that possess this property, and map the resource
* URI to the required RoleLevel. * URI to the required RoleLevel.
*/ */
private static void populateThresholdMap(OntModel model, private static void populateThresholdMap(OntModel model,
Map<String, RoleLevel> map, String propertyUri) { Map<Pair<String,Pair<String,String>>, RoleLevel> map, String propertyUri) {
model.enterCriticalSection(Lock.READ); model.enterCriticalSection(Lock.READ);
try { try {
Property property = model.getProperty(propertyUri); com.hp.hpl.jena.rdf.model.Property property = model.getProperty(propertyUri);
StmtIterator stmts = model.listStatements((Resource) null, StmtIterator stmts = model.listStatements((Resource) null,
property, (Resource) null); property, (Resource) null);
while (stmts.hasNext()) { try {
Statement stmt = stmts.next(); while (stmts.hasNext()) {
Resource subject = stmt.getSubject(); Statement stmt = stmts.next();
RDFNode objectNode = stmt.getObject(); Resource subject = stmt.getSubject();
if ((subject == null) || (!(objectNode instanceof Resource))) { RDFNode objectNode = stmt.getObject();
continue; if ((subject == null) || (!(objectNode instanceof Resource))) {
} continue;
Resource object = (Resource) objectNode; }
RoleLevel role = RoleLevel.getRoleByUri(object.getURI()); Resource object = (Resource) objectNode;
map.put(subject.getURI(), role); RoleLevel role = RoleLevel.getRoleByUri(object.getURI());
map.put(new Pair<String,Pair<String,String>>(
OWL.Thing.getURI(), new Pair<String,String>(
subject.getURI(), OWL.Thing.getURI())), role);
}
} finally {
stmts.close();
} }
stmts.close(); List<ObjectProperty> fauxOps = ApplicationConfigurationOntologyUtils
.getAdditionalFauxSubproperties(null, null, model, model);
for (ObjectProperty faux : fauxOps) {
RoleLevel role = null;
if(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT
.equals(propertyUri)) {
role = faux.getProhibitedFromUpdateBelowRoleLevel();
} else if (VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT
.equals(propertyUri)) {
role = faux.getHiddenFromDisplayBelowRoleLevel();
}
if (role != null) {
log.debug("Putting D:" + faux.getDomainVClassURI() + " P:" + faux.getURI() + " R:" + faux.getRangeVClassURI() + " ==> L:" + role);
map.put(new Pair<String,Pair<String,String>>(
faux.getDomainVClassURI(), new Pair<String,String>(
faux.getURI(), faux.getRangeVClassURI())), role);
}
}
} finally { } finally {
model.leaveCriticalSection(); model.leaveCriticalSection();
} }
@ -175,15 +243,14 @@ public class PropertyRestrictionPolicyHelper {
* These URIs can be displayed only if the user's role is at least as high * These URIs can be displayed only if the user's role is at least as high
* as the threshold role. * as the threshold role.
*/ */
private final Map<String, RoleLevel> displayThresholdMap; private final Map<Pair<String, Pair<String,String>>, RoleLevel> displayThresholdMap;
/** /**
* These URIs can be modified only if the user's role is at least as high as * These URIs can be modified only if the user's role is at least as high as
* the threshold role. * the threshold role.
*/ */
private final Map<String, RoleLevel> modifyThresholdMap; private final Map<Pair<String, Pair<String,String>>, RoleLevel> modifyThresholdMap;
private final Model displayModel;
/** /**
* Store unmodifiable versions of the inputs. * Store unmodifiable versions of the inputs.
@ -194,14 +261,15 @@ public class PropertyRestrictionPolicyHelper {
protected PropertyRestrictionPolicyHelper( protected PropertyRestrictionPolicyHelper(
Collection<String> modifyProhibitedNamespaces, Collection<String> modifyProhibitedNamespaces,
Collection<String> modifyExceptionsAllowedUris, Collection<String> modifyExceptionsAllowedUris,
Map<String, RoleLevel> displayThresholdMap, Map<Pair<String, Pair<String,String>>, RoleLevel> displayThresholdMap,
Map<String, RoleLevel> modifyThresholdMap, Map<Pair<String, Pair<String,String>>, RoleLevel> modifyThresholdMap,
Model displayModel) { Model displayModel) {
this.modifyProhibitedNamespaces = unmodifiable(modifyProhibitedNamespaces); this.modifyProhibitedNamespaces = unmodifiable(modifyProhibitedNamespaces);
this.modifyExceptionsAllowedUris = unmodifiable(modifyExceptionsAllowedUris); this.modifyExceptionsAllowedUris = unmodifiable(modifyExceptionsAllowedUris);
this.displayThresholdMap = unmodifiable(displayThresholdMap); this.displayThresholdMap = displayThresholdMap;
this.modifyThresholdMap = unmodifiable(modifyThresholdMap); this.modifyThresholdMap = modifyThresholdMap;
this.displayModel = displayModel; // this.displayThresholdMap = unmodifiable(displayThresholdMap);
// this.modifyThresholdMap = unmodifiable(modifyThresholdMap);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("prohibited: " + this.modifyProhibitedNamespaces); log.debug("prohibited: " + this.modifyProhibitedNamespaces);
@ -219,6 +287,7 @@ public class PropertyRestrictionPolicyHelper {
} }
} }
@SuppressWarnings("unused")
private Map<String, RoleLevel> unmodifiable(Map<String, RoleLevel> raw) { private Map<String, RoleLevel> unmodifiable(Map<String, RoleLevel> raw) {
if (raw == null) { if (raw == null) {
return Collections.emptyMap(); return Collections.emptyMap();
@ -271,83 +340,34 @@ public class PropertyRestrictionPolicyHelper {
log.debug("can modify resource '" + resourceUri + "'"); log.debug("can modify resource '" + resourceUri + "'");
return true; return true;
} }
public boolean canDisplayPredicate(String predicateUri, RoleLevel userRole) {
return canDisplayPredicate(predicateUri, null, userRole);
}
/** /**
* If display of a predicate is restricted, the user's role must be at least * If display of a predicate is restricted, the user's role must be at least
* as high as the restriction level. * as high as the restriction level.
*/ */
public boolean canDisplayPredicate(String predicateUri, String rangeUri, RoleLevel userRole) { public boolean canDisplayPredicate(Property predicate, RoleLevel userRole) {
if (predicateUri == null) { if (predicate == null) {
log.debug("can't display predicate: predicateUri was null"); log.debug("can't display predicate: predicate was null");
return false; return false;
} }
RoleLevel displayThreshold = RoleLevel.NOBODY; RoleLevel displayThreshold = getThreshold(predicate, displayThresholdMap);
if (rangeUri == null) {
displayThreshold = displayThresholdMap.get(predicateUri);
} else {
log.debug("Getting display threshold for " + predicateUri + " " + rangeUri);
displayThreshold = getDisplayThreshold(predicateUri, rangeUri);
if (displayThreshold == null) {
displayThreshold = displayThresholdMap.get(predicateUri);
}
log.debug(displayThreshold);
}
if (isAuthorized(userRole, displayThreshold)) { if (isAuthorized(userRole, displayThreshold)) {
log.debug("can display predicate: '" + predicateUri log.debug("can display predicate: '" + predicate.getURI() + "', domain="
+ "', userRole=" + userRole + ", thresholdRole=" + predicate.getDomainVClassURI() + ", range="
+ displayThreshold); + predicate.getRangeVClassURI() + ", userRole="
+ userRole + ", thresholdRole=" + displayThreshold);
return true; return true;
} }
log.debug("can't display predicate: '" + predicateUri + "', userRole=" log.debug("can't display predicate: '" + predicate.getURI() + "', domain="
+ userRole + ", thresholdRole=" + displayThreshold); + predicate.getDomainVClassURI() + ", range="
+ predicate.getRangeVClassURI() + ", userRole="
+ userRole + ", thresholdRole=" + displayThreshold);
return false; return false;
} }
/**
* Gets the role level threshold for displaying a predicate with a particular
* object class
* @param predicateUri
* @param rangeUri
* @return RoleLevel threshold
*/
private RoleLevel getDisplayThreshold(String predicateUri, String rangeUri) {
String query = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
"SELECT ?level WHERE { \n" +
// " ?p rdfs:subPropertyOf ?property . \n" +
" ?context config:configContextFor ?p . \n" +
" ?context config:qualifiedBy ?range . \n" +
" ?context config:hasConfiguration ?configuration . \n" +
" ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?level \n" +
"}";
Query q = QueryFactory.create(query);
QueryExecution qe = QueryExecutionFactory.create(q, displayModel);
try {
ResultSet rs = qe.execSelect();
if (!rs.hasNext()) {
return null;
}
while(rs.hasNext()) {
QuerySolution qsoln = rs.nextSolution();
Resource levelRes = qsoln.getResource("level");
if (levelRes != null) {
return RoleLevel.getRoleByUri(levelRes.getURI());
}
}
} finally {
qe.close();
}
return null;
}
/** /**
* A predicate cannot be modified if its namespace is in the prohibited list * A predicate cannot be modified if its namespace is in the prohibited list
* (some exceptions are allowed). * (some exceptions are allowed).
@ -355,32 +375,36 @@ public class PropertyRestrictionPolicyHelper {
* If modification of a predicate is restricted, the user's role must be at * If modification of a predicate is restricted, the user's role must be at
* least as high as the restriction level. * least as high as the restriction level.
*/ */
public boolean canModifyPredicate(String predicateUri, RoleLevel userRole) { public boolean canModifyPredicate(Property predicate, RoleLevel userRole) {
if (predicateUri == null) { if (predicate == null || predicate.getURI() == null) {
log.debug("can't modify predicate: predicateUri was null"); log.debug("can't modify predicate: predicate was null");
return false; return false;
} }
if (modifyProhibitedNamespaces.contains(namespace(predicateUri))) { if (modifyProhibitedNamespaces.contains(namespace(predicate.getURI()))) {
if (modifyExceptionsAllowedUris.contains(predicateUri)) { if (modifyExceptionsAllowedUris.contains(predicate.getURI())) {
log.debug("'" + predicateUri + "' is a permitted exception"); log.debug("'" + predicate.getURI() + "' is a permitted exception");
} else { } else {
log.debug("can't modify resource '" + predicateUri log.debug("can't modify resource '" + predicate.getURI()
+ "': prohibited namespace: '" + "': prohibited namespace: '"
+ namespace(predicateUri) + "'"); + namespace(predicate.getURI()) + "'");
return false; return false;
} }
} }
RoleLevel modifyThreshold = modifyThresholdMap.get(predicateUri); RoleLevel modifyThreshold = getModifyThreshold(predicate);
if (isAuthorized(userRole, modifyThreshold)) { if (isAuthorized(userRole, modifyThreshold)) {
log.debug("can modify predicate: '" + predicateUri + "', userRole=" log.debug("can modify predicate: '" + predicate.getURI() + "', domain="
+ predicate.getDomainVClassURI() + ", range="
+ predicate.getRangeVClassURI() + ", userRole="
+ userRole + ", thresholdRole=" + modifyThreshold); + userRole + ", thresholdRole=" + modifyThreshold);
return true; return true;
} }
log.debug("can't modify predicate: '" + predicateUri + "', userRole=" log.debug("can't modify predicate: '" + predicate.getURI() + "', domain="
+ userRole + ", thresholdRole=" + modifyThreshold); + predicate.getDomainVClassURI() + ", range="
+ predicate.getRangeVClassURI() + ", userRole="
+ userRole + ", thresholdRole=" + modifyThreshold);
return false; return false;
} }
@ -422,7 +446,7 @@ public class PropertyRestrictionPolicyHelper {
throw new NullPointerException( throw new NullPointerException(
"display model has not been initialized."); "display model has not been initialized.");
} }
PropertyRestrictionPolicyHelper bean = PropertyRestrictionPolicyHelper PropertyRestrictionPolicyHelper bean = PropertyRestrictionPolicyHelper
.createBean(model, displayModel); .createBean(model, displayModel);
PropertyRestrictionPolicyHelper.setBean(ctx, bean); PropertyRestrictionPolicyHelper.setBean(ctx, bean);

View file

@ -13,6 +13,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/** /**
* A collection of building-block methods so we can code a policy based on the * A collection of building-block methods so we can code a policy based on the
@ -34,9 +35,9 @@ public abstract class AbstractRelationshipPolicy implements PolicyIface {
uri, RoleLevel.SELF); uri, RoleLevel.SELF);
} }
protected boolean canModifyPredicate(String uri) { protected boolean canModifyPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate( return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
uri, RoleLevel.SELF); predicate, RoleLevel.SELF);
} }
protected PolicyDecision cantModifyResource(String uri) { protected PolicyDecision cantModifyResource(String uri) {

View file

@ -2,9 +2,12 @@
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces; package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
public class RequestActionConstants { public class RequestActionConstants {
public static String actionNamespace = "java:"; public static String actionNamespace = "java:";
public static String SOME_URI = "?SOME_URI"; public static String SOME_URI = "?SOME_URI";
public static Property SOME_PREDICATE = new Property(SOME_URI);
public static String SOME_LITERAL = "?SOME_LITERAL"; public static String SOME_LITERAL = "?SOME_LITERAL";
} }

View file

@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/** /**
* A base class for requested actions that involve adding, editing, or dropping * A base class for requested actions that involve adding, editing, or dropping
@ -14,12 +15,16 @@ public abstract class AbstractDataPropertyStatementAction extends
AbstractPropertyStatementAction { AbstractPropertyStatementAction {
private final String subjectUri; private final String subjectUri;
private final String predicateUri; private final String predicateUri;
private final Property predicate;
public AbstractDataPropertyStatementAction(OntModel ontModel, public AbstractDataPropertyStatementAction(OntModel ontModel,
String subjectUri, String predicateUri) { String subjectUri, String predicateUri) {
super(ontModel); super(ontModel);
this.subjectUri = subjectUri; this.subjectUri = subjectUri;
this.predicateUri = predicateUri; this.predicateUri = predicateUri;
Property dataProperty = new Property();
dataProperty.setURI(predicateUri);
this.predicate = dataProperty;
} }
public AbstractDataPropertyStatementAction(OntModel ontModel, public AbstractDataPropertyStatementAction(OntModel ontModel,
@ -28,12 +33,19 @@ public abstract class AbstractDataPropertyStatementAction extends
this.subjectUri = (dps.getIndividual() == null) ? dps this.subjectUri = (dps.getIndividual() == null) ? dps
.getIndividualURI() : dps.getIndividual().getURI(); .getIndividualURI() : dps.getIndividual().getURI();
this.predicateUri = dps.getDatapropURI(); this.predicateUri = dps.getDatapropURI();
Property dataProperty = new Property();
dataProperty.setURI(predicateUri);
this.predicate = dataProperty;
} }
public String getSubjectUri() { public String getSubjectUri() {
return subjectUri; return subjectUri;
} }
public Property getPredicate() {
return predicate;
}
@Override @Override
public String getPredicateUri() { public String getPredicateUri() {
return predicateUri; return predicateUri;

View file

@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/** /**
* A base class for requested actions that involve adding, editing, or deleting * A base class for requested actions that involve adding, editing, or deleting
@ -13,14 +14,14 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
public abstract class AbstractObjectPropertyStatementAction extends public abstract class AbstractObjectPropertyStatementAction extends
AbstractPropertyStatementAction { AbstractPropertyStatementAction {
private final String subjectUri; private final String subjectUri;
private final String predicateUri; private final Property predicate;
private final String objectUri; private final String objectUri;
public AbstractObjectPropertyStatementAction(OntModel ontModel, String subjectUri, public AbstractObjectPropertyStatementAction(OntModel ontModel, String subjectUri,
String predicateUri, String objectUri) { Property predicate, String objectUri) {
super(ontModel); super(ontModel);
this.subjectUri = subjectUri; this.subjectUri = subjectUri;
this.predicateUri = predicateUri; this.predicate = predicate;
this.objectUri = objectUri; this.objectUri = objectUri;
} }
@ -28,8 +29,7 @@ public abstract class AbstractObjectPropertyStatementAction extends
super(ontModel); super(ontModel);
this.subjectUri = (ops.getSubject() == null) ? ops.getSubjectURI() this.subjectUri = (ops.getSubject() == null) ? ops.getSubjectURI()
: ops.getSubject().getURI(); : ops.getSubject().getURI();
this.predicateUri = (ops.getProperty() == null) ? ops.getPropertyURI() this.predicate = (ops.getProperty());
: ops.getProperty().getURI();
this.objectUri = (ops.getObject() == null) ? ops.getObjectURI() : ops this.objectUri = (ops.getObject() == null) ? ops.getObjectURI() : ops
.getObject().getURI(); .getObject().getURI();
} }
@ -42,9 +42,13 @@ public abstract class AbstractObjectPropertyStatementAction extends
return objectUri; return objectUri;
} }
public Property getPredicate() {
return predicate;
}
@Override @Override
public String getPredicateUri() { public String getPredicateUri() {
return predicateUri; return predicate.getURI();
} }
@Override @Override
@ -55,6 +59,6 @@ public abstract class AbstractObjectPropertyStatementAction extends
@Override @Override
public String toString() { public String toString() {
return this.getClass().getSimpleName() + ": <" + subjectUri + "> <" return this.getClass().getSimpleName() + ": <" + subjectUri + "> <"
+ predicateUri + "> <" + objectUri + ">"; + predicate.getURI() + "> <" + objectUri + ">";
} }
} }

View file

@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/** /**
* A base class for requested actions that involve adding, editing, or deleting * A base class for requested actions that involve adding, editing, or deleting
@ -27,5 +28,7 @@ public abstract class AbstractPropertyStatementAction extends RequestedAction {
*/ */
public abstract String[] getResourceUris(); public abstract String[] getResourceUris();
public abstract Property getPredicate();
public abstract String getPredicateUri(); public abstract String getPredicateUri();
} }

View file

@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/** /**
* Should we allow the user to add this ObjectPropertyStatement to this model? * Should we allow the user to add this ObjectPropertyStatement to this model?
@ -12,8 +13,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
public class AddObjectPropertyStatement extends public class AddObjectPropertyStatement extends
AbstractObjectPropertyStatementAction { AbstractObjectPropertyStatementAction {
public AddObjectPropertyStatement(OntModel ontModel, String uriOfSub, public AddObjectPropertyStatement(OntModel ontModel, String uriOfSub,
String uriOfPred, String uriOfObj) { Property predicate, String uriOfObj) {
super(ontModel, uriOfSub, uriOfPred, uriOfObj); super(ontModel, uriOfSub, predicate, uriOfObj);
} }
public AddObjectPropertyStatement(OntModel ontModel, public AddObjectPropertyStatement(OntModel ontModel,

View file

@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/** /**
* Should we allow the user to delete this ObjectPropertyStatement from this * Should we allow the user to delete this ObjectPropertyStatement from this
@ -13,7 +14,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
public class DropObjectPropertyStatement extends public class DropObjectPropertyStatement extends
AbstractObjectPropertyStatementAction { AbstractObjectPropertyStatementAction {
public DropObjectPropertyStatement(OntModel ontModel, String sub, public DropObjectPropertyStatement(OntModel ontModel, String sub,
String pred, String obj) { Property pred, String obj) {
super(ontModel, sub, pred, obj); super(ontModel, sub, pred, obj);
} }

View file

@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
/** /**
* Should we allow the user to edit this ObjectPropertyStatement in this model? * Should we allow the user to edit this ObjectPropertyStatement in this model?
@ -12,8 +13,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
public class EditObjectPropertyStatement extends public class EditObjectPropertyStatement extends
AbstractObjectPropertyStatementAction { AbstractObjectPropertyStatementAction {
public EditObjectPropertyStatement(OntModel ontModel, String subjectUri, public EditObjectPropertyStatement(OntModel ontModel, String subjectUri,
String keywordPredUri, String objectUri) { Property keywordPred, String objectUri) {
super(ontModel, subjectUri, keywordPredUri, objectUri); super(ontModel, subjectUri, keywordPred, objectUri);
} }
public EditObjectPropertyStatement(OntModel ontModel, public EditObjectPropertyStatement(OntModel ontModel,

View file

@ -78,10 +78,12 @@ public class ObjectProperty extends Property implements Comparable<ObjectPropert
e.writeObject(this); e.writeObject(this);
} }
@Override
public String getDomainVClassURI() { public String getDomainVClassURI() {
return domainVClassURI; return domainVClassURI;
} }
@Override
public void setDomainVClassURI(String domainClassURI) { public void setDomainVClassURI(String domainClassURI) {
this.domainVClassURI = domainClassURI; this.domainVClassURI = domainClassURI;
} }
@ -111,9 +113,13 @@ public class ObjectProperty extends Property implements Comparable<ObjectPropert
public void setParentURI(String parentURI) { public void setParentURI(String parentURI) {
this.parentURI = parentURI; this.parentURI = parentURI;
} }
@Override
public String getRangeVClassURI() { public String getRangeVClassURI() {
return rangeVClassURI; return rangeVClassURI;
} }
@Override
public void setRangeVClassURI(String rangeClassURI) { public void setRangeVClassURI(String rangeClassURI) {
this.rangeVClassURI = rangeClassURI; this.rangeVClassURI = rangeClassURI;
} }

View file

@ -15,11 +15,20 @@ public class Property extends BaseResourceBean {
private String groupURI = null; private String groupURI = null;
private String label = null; // keep so can set in a context-specific way private String label = null; // keep so can set in a context-specific way
private final boolean subjectSide = true; // only relevant to ObjectProperty private final boolean subjectSide = true; // only relevant to ObjectProperty
private String domainVClassURI = null;
private String rangeVClassURI = null;
private boolean editLinkSuppressed = false;
private boolean addLinkSuppressed = false;
private boolean deleteLinkSuppressed = false;
public Property() { public Property() {
this.groupURI = null; this.groupURI = null;
this.label = null; this.label = null;
} }
public Property(String URI) {
this.setURI(URI);
}
public String getCustomEntryForm() { public String getCustomEntryForm() {
return customEntryForm; return customEntryForm;
@ -43,10 +52,53 @@ public class Property extends BaseResourceBean {
this.label = label; this.label = label;
} }
public String getDomainVClassURI() {
return this.domainVClassURI;
}
public void setDomainVClassURI(String domainVClassURI) {
this.domainVClassURI = domainVClassURI;
}
public String getRangeVClassURI() {
return this.rangeVClassURI;
}
public void setRangeVClassURI(String rangeVClassURI) {
this.rangeVClassURI = rangeVClassURI;
}
public boolean isSubjectSide() { public boolean isSubjectSide() {
return subjectSide; return subjectSide;
} }
public boolean isEditLinkSuppressed() {
return editLinkSuppressed;
}
public boolean isAddLinkSuppressed() {
return addLinkSuppressed;
}
public boolean isDeleteLinkSuppressed() {
return deleteLinkSuppressed;
}
public void setEditLinkSuppressed(boolean editLinkSuppressed) {
this.editLinkSuppressed = editLinkSuppressed;
}
public void setAddLinkSuppressed(boolean addLinkSuppressed) {
if (this.addLinkSuppressed) {
throw new RuntimeException("addLinkSuppressed already true");
}
this.addLinkSuppressed = addLinkSuppressed;
}
public void setDeleteLinkSuppressed(boolean deleteLinkSuppressed) {
this.deleteLinkSuppressed = deleteLinkSuppressed;
}
/** /**
* Sorts Property objects, by property rank, then alphanumeric. * Sorts Property objects, by property rank, then alphanumeric.
* @author bdc34 * @author bdc34

View file

@ -3,6 +3,8 @@
package edu.cornell.mannlib.vitro.webapp.beans; package edu.cornell.mannlib.vitro.webapp.beans;
import java.text.Collator; import java.text.Collator;
import java.util.ArrayList;
import java.util.List;
import org.openrdf.model.impl.URIImpl; import org.openrdf.model.impl.URIImpl;
@ -91,6 +93,9 @@ public class VClass extends BaseResourceBean implements Comparable<VClass>
public Float getSearchBoost() { return searchBoost; } public Float getSearchBoost() { return searchBoost; }
public void setSearchBoost( Float boost ){ searchBoost = boost;} public void setSearchBoost( Float boost ){ searchBoost = boost;}
public boolean isUnion() { return false; }
public List<VClass> getUnionComponents() { return new ArrayList<VClass>(); }
/** /**
* Default constructor * Default constructor
*/ */

View file

@ -9,9 +9,11 @@ import java.io.PrintWriter;
import java.io.Writer; import java.io.Writer;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.servlet.RequestDispatcher; import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@ -40,6 +42,7 @@ import com.hp.hpl.jena.vocabulary.XSD;
import edu.cornell.mannlib.vedit.controller.BaseEditController; 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.Ontology; import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.controller.individual.IndividualController;
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat;
@ -47,45 +50,37 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ResultFormat;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils; import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryUtils;
import edu.cornell.mannlib.vitro.webapp.web.ContentType;
/** /**
* Services a sparql query. This will return a simple error message and a 501 if * Services a SPARQL query. This will return a simple error message and a 501 if
* there is no Model. * there is no Model.
* *
*
* @author bdc34 * @author bdc34
* *
*/ */
public class SparqlQueryServlet extends BaseEditController { public class SparqlQueryServlet extends BaseEditController {
private static final Log log = LogFactory.getLog(SparqlQueryServlet.class.getName()); private static final Log log = LogFactory.getLog(SparqlQueryServlet.class.getName());
private final static boolean CONVERT = true;
/** /**
* format configurations for SELECT queries. * format configurations for SELECT queries.
*/ */
protected static HashMap<String,RSFormatConfig> rsFormats = new HashMap<String,RSFormatConfig>(); protected static HashMap<String,RSFormatConfig> rsFormats = new HashMap<String,RSFormatConfig>();
private static RSFormatConfig[] rsfs = {
new RSFormatConfig( "RS_XML", !CONVERT, ResultFormat.XML, null, "text/xml"),
new RSFormatConfig( "RS_TEXT", !CONVERT, ResultFormat.TEXT, null, "text/plain"),
new RSFormatConfig( "vitro:csv", !CONVERT, ResultFormat.CSV, null, "text/csv"),
new RSFormatConfig( "RS_JSON", !CONVERT, ResultFormat.JSON, null, "application/javascript") };
/** /**
* format configurations for CONSTRUCT/DESCRIBE queries. * format configurations for CONSTRUCT/DESCRIBE queries.
*/ */
protected static HashMap<String,ModelFormatConfig> modelFormats = protected static HashMap<String,ModelFormatConfig> modelFormats =
new HashMap<String,ModelFormatConfig>(); new HashMap<String,ModelFormatConfig>();
private static ModelFormatConfig[] fmts = { /**
new ModelFormatConfig("RDF/XML", !CONVERT, ModelSerializationFormat.RDFXML, null, "application/rdf+xml" ), * Use this map to decide which MIME type is suited for the "accept" header.
new ModelFormatConfig("RDF/XML-ABBREV", CONVERT, ModelSerializationFormat.N3, "RDF/XML-ABBREV", "application/rdf+xml" ), */
new ModelFormatConfig("N3", !CONVERT, ModelSerializationFormat.N3, null, "text/n3" ), public static final Map<String, Float> ACCEPTED_CONTENT_TYPES;
new ModelFormatConfig("N-TRIPLE", !CONVERT, ModelSerializationFormat.NTRIPLE, null, "text/plain" ),
new ModelFormatConfig("TTL", CONVERT, ModelSerializationFormat.N3, "TTL", "application/x-turtle" ),
new ModelFormatConfig("JSON-LD", CONVERT, ModelSerializationFormat.N3, "JSON-LD", "application/javascript" ) };
@Override @Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException throws ServletException, IOException
@ -113,100 +108,85 @@ public class SparqlQueryServlet extends BaseEditController {
String queryParam = vreq.getParameter("query"); String queryParam = vreq.getParameter("query");
log.debug("queryParam was : " + queryParam); log.debug("queryParam was : " + queryParam);
String resultFormatParam = vreq.getParameter("resultFormat"); if( queryParam == null || "".equals(queryParam) ){
log.debug("resultFormat was: " + resultFormatParam);
String rdfResultFormatParam = vreq.getParameter("rdfResultFormat");
if (rdfResultFormatParam == null) {
rdfResultFormatParam = "RDF/XML-ABBREV";
}
log.debug("rdfResultFormat was: " + rdfResultFormatParam);
if( queryParam == null || "".equals(queryParam) ||
resultFormatParam == null || "".equals(resultFormatParam) ||
!rsFormats.containsKey( resultFormatParam ) ||
rdfResultFormatParam == null || "".equals(rdfResultFormatParam) ||
!modelFormats.containsKey( rdfResultFormatParam ) ) {
doHelp(request,response); doHelp(request,response);
return; return;
} }
executeQuery(response, resultFormatParam, rdfResultFormatParam, String contentType = checkForContentType(vreq.getHeader("Accept"));
queryParam, vreq.getUnfilteredRDFService());
Query query = SparqlQueryUtils.create(queryParam);
if( query.isSelectType() ){
String format = contentType!=null ? contentType:vreq.getParameter("resultFormat");
RSFormatConfig formatConf = rsFormats.get(format);
doSelect(response, queryParam, formatConf, vreq.getRDFService());
}else if( query.isAskType()){
doAsk( queryParam, vreq.getRDFService(), response );
}else if( query.isConstructType() ){
String format = contentType != null ? contentType : vreq.getParameter("rdfResultFormat");
if (format== null) {
format= "RDF/XML-ABBREV";
}
ModelFormatConfig formatConf = modelFormats.get(format);
doConstruct(response, query, formatConf, vreq.getRDFService());
}else{
doHelp(request,response);
}
return; return;
} }
private void executeQuery(HttpServletResponse response,
String resultFormatParam,
String rdfResultFormatParam,
String queryParam,
RDFService rdfService ) throws IOException {
/* BJL23 2008-11-06
* modified to support CSV output.
* Unfortunately, ARQ doesn't make it easy to
* do this by implementing a new ResultSetFormat, because
* ResultSetFormatter is hardwired with expected values.
* This slightly ugly approach will have to do for now.
*/
// if ( !("vitro:csv").equals(resultFormatParam) ) {
// rsf = selectFormatSymbols.get(resultFormatParam);
// }
// String mimeType = rdfFormatToMimeType.get(resultFormatParam);
try{
Query query = SparqlQueryUtils.create(queryParam);
if( query.isSelectType() ){
doSelectQuery( queryParam, rdfService, resultFormatParam, response);
} else if(query.isAskType()){
// Irrespective of the ResultFormatParam,
// this always prints a boolean to the default OutputStream.
String result = (rdfService.sparqlAskQuery(queryParam) == true)
? "true"
: "false";
PrintWriter p = response.getWriter();
p.write(result);
return;
} else {
doModelResultQuery( query, rdfService, rdfResultFormatParam, response);
}
} catch (RDFServiceException e) {
throw new RuntimeException(e);
}
}
private void doAsk(String queryParam, RDFService rdfService,
HttpServletResponse response) throws ServletException, IOException {
// Irrespective of the ResultFormatParam,
// this always prints a boolean to the default OutputStream.
String result;
try {
result = (rdfService.sparqlAskQuery(queryParam) == true)
? "true"
: "false";
} catch (RDFServiceException e) {
throw new ServletException( "Could not execute ask query ", e );
}
PrintWriter p = response.getWriter();
p.write(result);
return;
}
/** /**
* Execute the query and send the result to out. Attempt to * Execute the query and send the result to out. Attempt to
* send the RDFService the same format as the rdfResultFormatParam * send the RDFService the same format as the rdfResultFormatParam
* so that the results from the RDFService can be directly piped to the client. * so that the results from the RDFService can be directly piped to the client.
* @param rdfService
* @throws IOException
* @throws RDFServiceException
*/ */
private void doSelectQuery( String queryParam, private void doSelect(HttpServletResponse response,
RDFService rdfService, String resultFormatParam, String queryParam,
HttpServletResponse response) throws IOException, RDFServiceException{ RSFormatConfig formatConf,
RSFormatConfig config = rsFormats.get( resultFormatParam ); RDFService rdfService
) throws ServletException {
try {
if( ! formatConf.converstionFromWireFormat ){
response.setContentType( formatConf.responseMimeType );
InputStream results;
results = rdfService.sparqlSelectQuery(queryParam, formatConf.wireFormat );
pipe( results, response.getOutputStream() );
}else{
//always use JSON when conversion is needed.
InputStream results = rdfService.sparqlSelectQuery(queryParam, ResultFormat.JSON );
if( ! config.converstionFromWireFormat ){ response.setContentType( formatConf.responseMimeType );
response.setContentType( config.responseMimeType );
InputStream results = rdfService.sparqlSelectQuery(queryParam, config.wireFormat ); ResultSet rs = ResultSetFactory.fromJSON( results );
pipe( results, response.getOutputStream() ); OutputStream out = response.getOutputStream();
}else{ ResultSetFormatter.output(out, rs, formatConf.jenaResponseFormat);
//always use JSON when conversion is needed. }
InputStream results = rdfService.sparqlSelectQuery(queryParam, ResultFormat.JSON ); } catch (RDFServiceException e) {
throw new ServletException("Cannot get result from the RDFService",e);
response.setContentType( config.responseMimeType ); } catch (IOException e) {
throw new ServletException("Cannot perform SPARQL SELECT",e);
ResultSet rs = ResultSetFactory.fromJSON( results );
OutputStream out = response.getOutputStream();
ResultSetFormatter.output(out, rs, config.jenaResponseFormat);
// } else {
// Writer out = response.getWriter();
// toCsv(out, results);
//}
} }
} }
/** /**
* Execute the query and send the result to out. Attempt to * Execute the query and send the result to out. Attempt to
@ -217,40 +197,44 @@ public class SparqlQueryServlet extends BaseEditController {
* @throws RDFServiceException * @throws RDFServiceException
* @throws * @throws
*/ */
private void doModelResultQuery( Query query, private void doConstruct( HttpServletResponse response,
RDFService rdfService, String rdfResultFormatParam, Query query,
HttpServletResponse response) throws IOException, RDFServiceException{ ModelFormatConfig formatConfig,
RDFService rdfService
//config drives what formats and conversions to use ) throws ServletException{
ModelFormatConfig config = modelFormats.get( rdfResultFormatParam ); try{
InputStream rawResult = null;
InputStream rawResult = null; if( query.isConstructType() ){
if( query.isConstructType() ){ rawResult= rdfService.sparqlConstructQuery( query.toString(), formatConfig.wireFormat );
rawResult= rdfService.sparqlConstructQuery( query.toString(), config.wireFormat ); }else if ( query.isDescribeType() ){
}else if ( query.isDescribeType() ){ rawResult = rdfService.sparqlDescribeQuery( query.toString(), formatConfig.wireFormat );
rawResult = rdfService.sparqlDescribeQuery( query.toString(), config.wireFormat ); }
}
response.setContentType( formatConfig.responseMimeType );
response.setContentType( config.responseMimeType );
if( formatConfig.converstionFromWireFormat ){
if( config.converstionFromWireFormat ){ Model resultModel = RDFServiceUtils.parseModel( rawResult, formatConfig.wireFormat );
Model resultModel = RDFServiceUtils.parseModel( rawResult, config.wireFormat ); if( "JSON-LD".equals( formatConfig.jenaResponseFormat )){
if( "JSON-LD".equals( config.jenaResponseFormat )){ //since jena 2.6.4 doesn't support JSON-LD we do it
//since jena 2.6.4 doesn't support JSON-LD we do it try {
try { JenaRDFParser parser = new JenaRDFParser();
JenaRDFParser parser = new JenaRDFParser(); Object json = JSONLD.fromRDF(resultModel, parser);
Object json = JSONLD.fromRDF(resultModel, parser); JSONUtils.write(response.getWriter(), json);
JSONUtils.write(response.getWriter(), json); } catch (JSONLDProcessingError e) {
} catch (JSONLDProcessingError e) { throw new RDFServiceException("Could not convert from Jena model to JSON-LD", e);
throw new RDFServiceException("Could not convert from Jena model to JSON-LD", e); }
}else{
OutputStream out = response.getOutputStream();
resultModel.write(out, formatConfig.jenaResponseFormat );
} }
}else{ }else{
OutputStream out = response.getOutputStream(); OutputStream out = response.getOutputStream();
resultModel.write(out, config.jenaResponseFormat ); pipe( rawResult, out );
} }
}else{ }catch( IOException ex){
OutputStream out = response.getOutputStream(); throw new ServletException("could not run SPARQL CONSTRUCT",ex);
pipe( rawResult, out ); } catch (RDFServiceException ex) {
throw new ServletException("could not run SPARQL CONSTRUCT",ex);
} }
} }
@ -362,13 +346,35 @@ public class SparqlQueryServlet extends BaseEditController {
rd.forward(req,res); rd.forward(req,res);
} }
/** Simple boolean vaule to improve the legibility of confiugrations. */
private final static boolean CONVERT = true;
public static class ModelFormatConfig{ /** Simple vaule to improve the legibility of confiugrations. */
private final static String NO_CONVERSION = null;
public static class FormatConfig{
public String valueFromForm; public String valueFromForm;
public boolean converstionFromWireFormat; public boolean converstionFromWireFormat;
public RDFService.ModelSerializationFormat wireFormat;
public String jenaResponseFormat;
public String responseMimeType; public String responseMimeType;
}
private static ModelFormatConfig[] fmts = {
new ModelFormatConfig("RDF/XML",
!CONVERT, ModelSerializationFormat.RDFXML, NO_CONVERSION, "application/rdf+xml" ),
new ModelFormatConfig("RDF/XML-ABBREV",
CONVERT, ModelSerializationFormat.N3, "RDF/XML-ABBREV", "application/rdf+xml" ),
new ModelFormatConfig("N3",
!CONVERT, ModelSerializationFormat.N3, NO_CONVERSION, "text/n3" ),
new ModelFormatConfig("N-TRIPLE",
!CONVERT, ModelSerializationFormat.NTRIPLE, NO_CONVERSION, "text/plain" ),
new ModelFormatConfig("TTL",
CONVERT, ModelSerializationFormat.N3, "TTL", "application/x-turtle" ),
new ModelFormatConfig("JSON-LD",
CONVERT, ModelSerializationFormat.N3, "JSON-LD", "application/javascript" ) };
public static class ModelFormatConfig extends FormatConfig{
public RDFService.ModelSerializationFormat wireFormat;
public String jenaResponseFormat;
public ModelFormatConfig( String valueFromForm, public ModelFormatConfig( String valueFromForm,
boolean converstionFromWireFormat, boolean converstionFromWireFormat,
@ -383,12 +389,20 @@ public class SparqlQueryServlet extends BaseEditController {
} }
} }
public static class RSFormatConfig{
public String valueFromForm; private static RSFormatConfig[] rsfs = {
public boolean converstionFromWireFormat; new RSFormatConfig( "RS_XML",
!CONVERT, ResultFormat.XML, null, "text/xml"),
new RSFormatConfig( "RS_TEXT",
!CONVERT, ResultFormat.TEXT, null, "text/plain"),
new RSFormatConfig( "vitro:csv",
!CONVERT, ResultFormat.CSV, null, "text/csv"),
new RSFormatConfig( "RS_JSON",
!CONVERT, ResultFormat.JSON, null, "application/javascript") };
public static class RSFormatConfig extends FormatConfig{
public ResultFormat wireFormat; public ResultFormat wireFormat;
public ResultSetFormat jenaResponseFormat; public ResultSetFormat jenaResponseFormat;
public String responseMimeType;
public RSFormatConfig( String valueFromForm, public RSFormatConfig( String valueFromForm,
boolean converstionFromWireFormat, boolean converstionFromWireFormat,
@ -403,14 +417,48 @@ public class SparqlQueryServlet extends BaseEditController {
} }
} }
static{ static{
/* move the lists of configs into maps for easy lookup */ HashMap<String, Float> map = new HashMap<String, Float>();
/* move the lists of configurations into maps for easy lookup
* by both MIME content type and the parameters from the form */
for( RSFormatConfig rsfc : rsfs ){ for( RSFormatConfig rsfc : rsfs ){
rsFormats.put( rsfc.valueFromForm, rsfc ); rsFormats.put( rsfc.valueFromForm, rsfc );
rsFormats.put( rsfc.responseMimeType, rsfc);
map.put(rsfc.responseMimeType, 1.0f);
} }
for( ModelFormatConfig mfc : fmts ){ for( ModelFormatConfig mfc : fmts ){
modelFormats.put( mfc.valueFromForm, mfc); modelFormats.put( mfc.valueFromForm, mfc);
} modelFormats.put(mfc.responseMimeType, mfc);
map.put(mfc.responseMimeType, 1.0f);
}
ACCEPTED_CONTENT_TYPES = Collections.unmodifiableMap(map);
} }
/**
* Get the content type based on content negotiation.
* Returns null of no content type can be agreed on or
* if there is no accept header.
*/
protected String checkForContentType( String acceptHeader ) {
if (acceptHeader == null)
return null;
try {
Map<String, Float> typesAndQ = ContentType
.getTypesAndQ(acceptHeader);
String ctStr = ContentType
.getBestContentType(typesAndQ,ACCEPTED_CONTENT_TYPES);
if( ACCEPTED_CONTENT_TYPES.containsKey( ctStr )){
return ctStr;
}
} catch (Throwable th) {
log.error("Problem while checking accept header ", th);
}
return null;
}
} }

View file

@ -91,7 +91,7 @@ public class ShowAuthController extends FreemarkerHttpServlet {
private boolean mayEditIndividual(VitroRequest vreq, String individualUri) { private boolean mayEditIndividual(VitroRequest vreq, String individualUri) {
RequestedAction action = new EditObjectPropertyStatement( RequestedAction action = new EditObjectPropertyStatement(
vreq.getJenaOntModel(), individualUri, vreq.getJenaOntModel(), individualUri,
RequestActionConstants.SOME_URI, RequestActionConstants.SOME_PREDICATE,
RequestActionConstants.SOME_URI); RequestActionConstants.SOME_URI);
return PolicyHelper.isAuthorizedForActions(vreq, action); return PolicyHelper.isAuthorizedForActions(vreq, action);
} }

View file

@ -19,6 +19,7 @@ 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.ModelAccess;
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 {
@ -43,7 +44,7 @@ public class Classes2ClassesRetryController extends BaseEditController {
action = epo.getAction(); action = epo.getAction();
} }
VClassDao vcDao = request.getUnfilteredWebappDaoFactory().getVClassDao(); VClassDao vcDao = ModelAccess.on(getServletContext()).getWebappDaoFactory().getVClassDao();
epo.setDataAccessObject(vcDao); epo.setDataAccessObject(vcDao);
Classes2Classes objectForEditing = new Classes2Classes(); Classes2Classes objectForEditing = new Classes2Classes();

View file

@ -22,6 +22,7 @@ import edu.cornell.mannlib.vedit.forwarder.impl.UrlForwarder;
import edu.cornell.mannlib.vedit.util.FormUtils; import edu.cornell.mannlib.vedit.util.FormUtils;
import edu.cornell.mannlib.vedit.validator.Validator; import edu.cornell.mannlib.vedit.validator.Validator;
import edu.cornell.mannlib.vedit.validator.impl.RequiredFieldValidator; import edu.cornell.mannlib.vedit.validator.impl.RequiredFieldValidator;
import edu.cornell.mannlib.vedit.validator.impl.UrlValidator;
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.Ontology; import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers; import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
@ -47,7 +48,13 @@ public class OntologyRetryController extends BaseEditController {
epo.setBeanClass(Ontology.class); epo.setBeanClass(Ontology.class);
epo.setBeanMask(testMask); epo.setBeanMask(testMask);
String action = "insert"; String action = null;
if (epo.getAction() == null) {
action = "insert";
epo.setAction("insert");
} else {
action = epo.getAction();
}
OntologyDao oDao = request.getUnfilteredWebappDaoFactory().getOntologyDao(); OntologyDao oDao = request.getUnfilteredWebappDaoFactory().getOntologyDao();
epo.setDataAccessObject(oDao); epo.setDataAccessObject(oDao);
@ -67,13 +74,12 @@ public class OntologyRetryController extends BaseEditController {
epo.setOriginalBean(ontologyForEditing); epo.setOriginalBean(ontologyForEditing);
} else { } else {
ontologyForEditing = (Ontology) epo.getNewBean(); ontologyForEditing = (Ontology) epo.getNewBean();
action = "update";
log.error("using newBean");
} }
//validators //validators
List<Validator> validatorList = new ArrayList<Validator>(); List<Validator> validatorList = new ArrayList<Validator>();
validatorList.add(new RequiredFieldValidator()); validatorList.add(new RequiredFieldValidator());
validatorList.add(new UrlValidator());
epo.getValidatorMap().put("URI", validatorList); epo.getValidatorMap().put("URI", validatorList);
//make a simple mask for the class's id //make a simple mask for the class's id

View file

@ -37,6 +37,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass;
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.controller.edit.utils.RoleLevelOptionsSetup; import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
@ -69,7 +70,8 @@ public class PropertyRetryController extends BaseEditController {
action = epo.getAction(); action = epo.getAction();
} }
ObjectPropertyDao propDao = request.getUnfilteredWebappDaoFactory().getObjectPropertyDao(); ObjectPropertyDao propDao = ModelAccess.on(getServletContext()).getWebappDaoFactory().getObjectPropertyDao();
//getUnfilteredWebappDaoFactory().getObjectPropertyDao();
epo.setDataAccessObject(propDao); epo.setDataAccessObject(propDao);
OntologyDao ontDao = request.getUnfilteredWebappDaoFactory().getOntologyDao(); OntologyDao ontDao = request.getUnfilteredWebappDaoFactory().getOntologyDao();
VClassDao vclassDao = request.getUnfilteredWebappDaoFactory().getVClassDao(); VClassDao vclassDao = request.getUnfilteredWebappDaoFactory().getVClassDao();

View file

@ -24,6 +24,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup; import edu.cornell.mannlib.vitro.webapp.beans.VClassGroup;
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.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassGroupDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
@ -44,7 +45,7 @@ public class VclassEditController extends BaseEditController {
EditProcessObject epo = super.createEpo(request, FORCE_NEW); EditProcessObject epo = super.createEpo(request, FORCE_NEW);
request.setAttribute("epoKey", epo.getKey()); request.setAttribute("epoKey", epo.getKey());
VClassDao vcwDao = request.getUnfilteredWebappDaoFactory().getVClassDao(); VClassDao vcwDao = ModelAccess.on(getServletContext()).getBaseWebappDaoFactory().getVClassDao();
VClass vcl = (VClass)vcwDao.getVClassByURI(request.getParameter("uri")); VClass vcl = (VClass)vcwDao.getVClassByURI(request.getParameter("uri"));
if (vcl == null) { if (vcl == null) {
@ -140,8 +141,8 @@ public class VclassEditController extends BaseEditController {
HashMap formSelect = new HashMap(); // tells the JSP what select lists are populated, and thus should be displayed HashMap formSelect = new HashMap(); // tells the JSP what select lists are populated, and thus should be displayed
request.setAttribute("formSelect",formSelect); request.setAttribute("formSelect",formSelect);
// if supported, we want to show only the asserted superclasses and subclasses. Don't want to see anonymous classes, restrictions, etc. // if supported, we want to show only the asserted superclasses and subclasses.
VClassDao vcDao = request.getUnfilteredAssertionsWebappDaoFactory().getVClassDao(); VClassDao vcDao = ModelAccess.on(getServletContext()).getBaseWebappDaoFactory().getVClassDao();
List superURIs = vcDao.getSuperClassURIs(vcl.getURI(),false); List superURIs = vcDao.getSuperClassURIs(vcl.getURI(),false);
List superVClasses = new ArrayList(); List superVClasses = new ArrayList();
Iterator superURIit = superURIs.iterator(); Iterator superURIit = superURIs.iterator();

View file

@ -23,6 +23,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectP
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; 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.UrlBuilder.ParamMap; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
@ -146,20 +147,23 @@ public class ImageUploadController extends FreemarkerHttpServlet {
String action = vreq.getParameter(PARAMETER_ACTION); String action = vreq.getParameter(PARAMETER_ACTION);
Individual entity = validateEntityUri(vreq); Individual entity = validateEntityUri(vreq);
String imageUri = entity.getMainImageUri(); String imageUri = entity.getMainImageUri();
Property indMainImage = new Property();
indMainImage.setURI(VitroVocabulary.IND_MAIN_IMAGE);
RequestedAction ra; RequestedAction ra;
if (ACTION_DELETE.equals(action) if (ACTION_DELETE.equals(action)
|| ACTION_DELETE_EDIT.equals(action)) { || ACTION_DELETE_EDIT.equals(action)) {
ra = new DropObjectPropertyStatement(vreq.getJenaOntModel(), ra = new DropObjectPropertyStatement(vreq.getJenaOntModel(),
entity.getURI(), VitroVocabulary.IND_MAIN_IMAGE, entity.getURI(), indMainImage,
imageUri); imageUri);
} else if (imageUri != null) { } else if (imageUri != null) {
ra = new EditObjectPropertyStatement(vreq.getJenaOntModel(), ra = new EditObjectPropertyStatement(vreq.getJenaOntModel(),
entity.getURI(), VitroVocabulary.IND_MAIN_IMAGE, entity.getURI(), indMainImage,
imageUri); imageUri);
} else { } else {
ra = new AddObjectPropertyStatement(vreq.getJenaOntModel(), ra = new AddObjectPropertyStatement(vreq.getJenaOntModel(),
entity.getURI(), VitroVocabulary.IND_MAIN_IMAGE, entity.getURI(), indMainImage,
RequestActionConstants.SOME_URI); RequestActionConstants.SOME_URI);
} }
return new Actions(ra); return new Actions(ra);

View file

@ -132,10 +132,11 @@ public class IndividualRequestAnalyzer {
* only provide a set of bytes. * only provide a set of bytes.
*/ */
protected ContentType checkAcceptHeaderForLinkedDataRequest() { protected ContentType checkAcceptHeaderForLinkedDataRequest() {
String acceptHeader = vreq.getHeader("accept"); String acceptHeader = vreq.getHeader("Accept");
if (acceptHeader == null) { if (acceptHeader == null)
return null; acceptHeader = vreq.getHeader("accept");
} if (acceptHeader == null)
return null;
try { try {
Map<String, Float> typesAndQ = ContentType Map<String, Float> typesAndQ = ContentType

View file

@ -77,11 +77,16 @@ public class RDFUploadController extends JenaIngestController {
VitroRequest request = new VitroRequest(req); VitroRequest request = new VitroRequest(req);
LoginStatusBean loginBean = LoginStatusBean.getBean(request); LoginStatusBean loginBean = LoginStatusBean.getBean(request);
String modelName = req.getParameter("modelName"); try {
if(modelName!=null){ String modelName = req.getParameter("modelName");
loadRDF(req,request,response); if(modelName!=null){
return; loadRDF(req,request,response);
} return;
}
} catch (Exception e) {
log.error(e,e);
throw new RuntimeException(e);
}
boolean remove = "remove".equals(request.getParameter("mode")); boolean remove = "remove".equals(request.getParameter("mode"));
String verb = remove?"Removed":"Added"; String verb = remove?"Removed":"Added";

View file

@ -15,7 +15,7 @@ public interface ObjectPropertyDao extends PropertyDao {
public ObjectProperty getObjectPropertyByURI(String objectPropertyURI); public ObjectProperty getObjectPropertyByURI(String objectPropertyURI);
public ObjectProperty getObjectPropertyByURIAndRangeURI(String objectPropertyURI, String rangeURI); public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI);
public List <ObjectProperty> getObjectPropertiesForObjectPropertyStatements(List /*of ObjectPropertyStatement */ objectPropertyStatements); public List <ObjectProperty> getObjectPropertiesForObjectPropertyStatements(List /*of ObjectPropertyStatement */ objectPropertyStatements);

View file

@ -41,8 +41,8 @@ public interface ObjectPropertyStatementDao {
public Map<String, String> getMostSpecificTypesInClassgroupsForIndividual(String subjectUri); public Map<String, String> getMostSpecificTypesInClassgroupsForIndividual(String subjectUri);
List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty( List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri, String propertyUri, String objectKey, String rangeUri, String subjectUri, String propertyUri, String objectKey, String domainUri,
String queryString, Set<String> constructQueryStrings, String rangeUri, String queryString, Set<String> constructQueryStrings,
String sortDirection); String sortDirection);

View file

@ -7,10 +7,13 @@ public class VitroVocabulary {
public static final String vitroURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#"; public static final String vitroURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#";
public static final String configURI= "http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#";
public static final String VITRO_AUTH = "http://vitro.mannlib.cornell.edu/ns/vitro/authorization#"; public static final String VITRO_AUTH = "http://vitro.mannlib.cornell.edu/ns/vitro/authorization#";
public static final String VITRO_PUBLIC = "http://vitro.mannlib.cornell.edu/ns/vitro/public#"; public static final String VITRO_PUBLIC = "http://vitro.mannlib.cornell.edu/ns/vitro/public#";
public static final String VITRO_PUBLIC_ONTOLOGY = "http://vitro.mannlib.cornell.edu/ns/vitro/public"; public static final String VITRO_PUBLIC_ONTOLOGY = "http://vitro.mannlib.cornell.edu/ns/vitro/public";
// TODO change the following before 1.6 release
public static final String PROPERTY_CONFIG_DATA = "http://example.org/appConfig/";
/** BJL23 2008-02-25: /** BJL23 2008-02-25:
@ -95,6 +98,9 @@ public class VitroVocabulary {
public static final String PROPERTY_CUSTOM_LIST_VIEW_ANNOT = vitroURI + "customListViewAnnot"; public static final String PROPERTY_CUSTOM_LIST_VIEW_ANNOT = vitroURI + "customListViewAnnot";
public static final String PROPERTY_SELECTFROMEXISTINGANNOT = vitroURI+"selectFromExistingAnnot"; public static final String PROPERTY_SELECTFROMEXISTINGANNOT = vitroURI+"selectFromExistingAnnot";
public static final String PROPERTY_OFFERCREATENEWOPTIONANNOT = vitroURI+"offerCreateNewOptionAnnot"; public static final String PROPERTY_OFFERCREATENEWOPTIONANNOT = vitroURI+"offerCreateNewOptionAnnot";
public static final String PROPERTY_EDITLINKSUPPRESSED = configURI + "editLinkSuppressed";
public static final String PROPERTY_ADDLINKSUPPRESSED = configURI + "addLinkSuppressed";
public static final String PROPERTY_DELETELINKSUPPRESSED = configURI + "deleteLinkSuppressed";
public static final String PROPERTY_INPROPERTYGROUPANNOT = vitroURI+"inPropertyGroupAnnot"; public static final String PROPERTY_INPROPERTYGROUPANNOT = vitroURI+"inPropertyGroupAnnot";
public static final String PROPERTYGROUP = vitroURI + "PropertyGroup"; public static final String PROPERTYGROUP = vitroURI + "PropertyGroup";
public static final String MASKS_PROPERTY = vitroURI + "masksProperty"; public static final String MASKS_PROPERTY = vitroURI + "masksProperty";

View file

@ -49,8 +49,8 @@ class ObjectPropertyDaoFiltering extends BaseFiltering implements ObjectProperty
return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters); return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters);
} }
public ObjectProperty getObjectPropertyByURIAndRangeURI(String objectPropertyURI, String rangeURI) { public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI) {
ObjectProperty newOprop=innerObjectPropertyDao.getObjectPropertyByURIAndRangeURI(objectPropertyURI, rangeURI); ObjectProperty newOprop=innerObjectPropertyDao.getObjectPropertyByURIs(objectPropertyURI, domainURI, rangeURI);
return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters); return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters);
} }

View file

@ -523,6 +523,36 @@ public class ObjectPropertyFiltering extends ObjectProperty {
public void setCollateBySubclass(boolean collate) { public void setCollateBySubclass(boolean collate) {
innerObjectProperty.setCollateBySubclass(collate); innerObjectProperty.setCollateBySubclass(collate);
} }
@Override
public boolean isEditLinkSuppressed() {
return innerObjectProperty.isEditLinkSuppressed();
}
@Override
public boolean isAddLinkSuppressed() {
return innerObjectProperty.isAddLinkSuppressed();
}
@Override
public boolean isDeleteLinkSuppressed() {
return innerObjectProperty.isDeleteLinkSuppressed();
}
@Override
public void setEditLinkSuppressed(boolean editLinkSuppressed) {
innerObjectProperty.setEditLinkSuppressed(editLinkSuppressed);
}
@Override
public void setAddLinkSuppressed(boolean addLinkSuppressed) {
innerObjectProperty.setAddLinkSuppressed(addLinkSuppressed);
}
@Override
public void setDeleteLinkSuppressed(boolean deleteLinkSuppressed) {
innerObjectProperty.setDeleteLinkSuppressed(deleteLinkSuppressed);
}
} }

View file

@ -86,12 +86,13 @@ class ObjectPropertyStatementDaoFiltering extends BaseFiltering implements Objec
@Override @Override
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty( public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri, String propertyUri, String objectKey, String rangeUri, String subjectUri, String propertyUri, String objectKey, String domainUri,
String query, Set<String> queryStrings, String sortDirection) { String rangeUri, String query, Set<String> queryStrings, String sortDirection) {
List<Map<String, String>> data = List<Map<String, String>> data =
innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty( innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty(
subjectUri, propertyUri, objectKey, rangeUri, query, queryStrings,sortDirection); subjectUri, propertyUri, objectKey, domainUri, rangeUri, query,
queryStrings,sortDirection);
/* Filter the data /* Filter the data
* *
@ -107,6 +108,7 @@ class ObjectPropertyStatementDaoFiltering extends BaseFiltering implements Objec
ObjectPropertyStatement statement = new ObjectPropertyStatementImpl(subjectUri, propertyUri, objectUri); ObjectPropertyStatement statement = new ObjectPropertyStatementImpl(subjectUri, propertyUri, objectUri);
ObjectProperty op = new ObjectProperty(); ObjectProperty op = new ObjectProperty();
op.setURI(propertyUri); op.setURI(propertyUri);
op.setDomainVClassURI(domainUri);
op.setRangeVClassURI(rangeUri); op.setRangeVClassURI(rangeUri);
statement.setProperty(op); statement.setProperty(op);
stmtsToData.put(statement, map); stmtsToData.put(statement, map);

View file

@ -834,7 +834,11 @@ public class JenaBaseDao extends JenaBaseDaoCon {
try { try {
String localName = r.getLocalName(); String localName = r.getLocalName();
if (localName != null) { if (localName != null) {
label = localName; if(localName.trim().length() > 0) {
label = localName;
} else {
label = r.getURI();
}
} else if (r.isAnon()) { } else if (r.isAnon()) {
label = r.getId().toString(); label = r.getId().toString();
} else { } else {
@ -925,8 +929,10 @@ public class JenaBaseDao extends JenaBaseDaoCon {
return null; return null;
if (vitroURIStr.indexOf(PSEUDO_BNODE_NS)==0) { if (vitroURIStr.indexOf(PSEUDO_BNODE_NS)==0) {
String idStr = vitroURIStr.split("#")[1]; String idStr = vitroURIStr.split("#")[1];
log.debug("Trying to get bnode " + idStr);
RDFNode rdfNode = ontModel.getRDFNode(Node.createAnon(AnonId.create(idStr))); RDFNode rdfNode = ontModel.getRDFNode(Node.createAnon(AnonId.create(idStr)));
if ( (rdfNode != null) && (rdfNode.canAs(OntClass.class)) ) { if ( (rdfNode != null) && (rdfNode.canAs(OntClass.class)) ) {
log.debug("found it");
cls = rdfNode.as(OntClass.class); cls = rdfNode.as(OntClass.class);
} }
} else { } else {

View file

@ -75,6 +75,9 @@ public class JenaBaseDaoCon {
protected AnnotationProperty PROPERTY_INPROPERTYGROUPANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_INPROPERTYGROUPANNOT); protected AnnotationProperty PROPERTY_INPROPERTYGROUPANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_INPROPERTYGROUPANNOT);
protected AnnotationProperty PROPERTY_COLLATEBYSUBCLASSANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_COLLATEBYSUBCLASSANNOT); protected AnnotationProperty PROPERTY_COLLATEBYSUBCLASSANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_COLLATEBYSUBCLASSANNOT);
protected AnnotationProperty PROPERTY_STUBOBJECTPROPERTYANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_STUBOBJECTPROPERTYANNOT); protected AnnotationProperty PROPERTY_STUBOBJECTPROPERTYANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_STUBOBJECTPROPERTYANNOT);
protected AnnotationProperty PROPERTY_EDITLINKSUPPRESSED = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_EDITLINKSUPPRESSED);
protected AnnotationProperty PROPERTY_ADDLINKSUPPRESSED = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_ADDLINKSUPPRESSED);
protected AnnotationProperty PROPERTY_DELETELINKSUPPRESSED = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_DELETELINKSUPPRESSED);
protected OntClass PROPERTYGROUP = _constModel.createClass(VitroVocabulary.PROPERTYGROUP); protected OntClass PROPERTYGROUP = _constModel.createClass(VitroVocabulary.PROPERTYGROUP);

View file

@ -37,6 +37,7 @@ import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement; 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.expr.NodeValue;
import com.hp.hpl.jena.util.iterator.ClosableIterator; 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.RDF; import com.hp.hpl.jena.vocabulary.RDF;
@ -224,6 +225,13 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
Boolean collateBySubclass = getPropertyBooleanValue(op,PROPERTY_COLLATEBYSUBCLASSANNOT); Boolean collateBySubclass = getPropertyBooleanValue(op,PROPERTY_COLLATEBYSUBCLASSANNOT);
p.setCollateBySubclass(collateBySubclass==null ? false : collateBySubclass); p.setCollateBySubclass(collateBySubclass==null ? false : collateBySubclass);
Boolean editLinkSuppressed = getPropertyBooleanValue(op, PROPERTY_EDITLINKSUPPRESSED);
p.setEditLinkSuppressed(editLinkSuppressed == null ? false : editLinkSuppressed);
Boolean addLinkSuppressed = getPropertyBooleanValue(op, PROPERTY_ADDLINKSUPPRESSED);
p.setAddLinkSuppressed(addLinkSuppressed == null ? false : addLinkSuppressed);
Boolean deleteLinkSuppressed = getPropertyBooleanValue(op, PROPERTY_DELETELINKSUPPRESSED);
p.setDeleteLinkSuppressed(deleteLinkSuppressed == null ? false : deleteLinkSuppressed);
Resource groupRes = (Resource) op.getPropertyValue(PROPERTY_INPROPERTYGROUPANNOT); Resource groupRes = (Resource) op.getPropertyValue(PROPERTY_INPROPERTYGROUPANNOT);
if (groupRes != null) { if (groupRes != null) {
p.setGroupURI(groupRes.getURI()); p.setGroupURI(groupRes.getURI());
@ -284,21 +292,39 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
} }
} }
public ObjectProperty getObjectPropertyByURIAndRangeURI(String propertyURI, String rangeURI) { public ObjectProperty getObjectPropertyByURIs(String propertyURI, String domainURI, String rangeURI) {
if(log.isDebugEnabled()) {
log.debug("Getting " + propertyURI + " with domain " + domainURI + " and range " + rangeURI);
}
ObjectProperty op = getObjectPropertyByURI(propertyURI); ObjectProperty op = getObjectPropertyByURI(propertyURI);
if (op == null) { if (op == null || rangeURI == null) {
return op; return op;
} }
op.setDomainVClassURI(domainURI);
op.setRangeVClassURI(rangeURI); op.setRangeVClassURI(rangeURI);
String propQuery = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" + String propQuery = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" + "PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" + "PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
"SELECT ?range ?label ?group ?customForm ?displayLevel ?updateLevel WHERE { \n" + "SELECT ?range ?label ?group ?customForm ?displayRank ?displayLevel " +
" ?context config:configContextFor <" + propertyURI + "> . \n" + " ?updateLevel ?editLinkSuppressed ?addLinkSuppressed ?deleteLinkSuppressed \n" +
" ?context config:qualifiedBy <" + rangeURI + "> . \n" + " WHERE { \n" +
" ?context config:hasConfiguration ?configuration . \n" + " ?context config:configContextFor <" + propertyURI + "> . \n";
if (domainURI != null) {
propQuery += " ?context config:qualifiedByDomain <" + domainURI + "> . \n";
} else {
propQuery += " FILTER NOT EXISTS { ?context config:qualifiedByDomain ?domainURI } \n";
}
if (rangeURI != null) {
propQuery += " ?context config:qualifiedBy <" + rangeURI + "> . \n";
};
propQuery += " ?context config:hasConfiguration ?configuration . \n" +
" ?configuration a config:ObjectPropertyDisplayConfig . \n" +
" OPTIONAL { ?configuration config:propertyGroup ?group } \n" + " OPTIONAL { ?configuration config:propertyGroup ?group } \n" +
" OPTIONAL { ?configuration config:displayName ?label } \n" + " OPTIONAL { ?configuration config:displayName ?label } \n" +
" OPTIONAL { ?configuration config:editLinkSuppressed ?editLinkSuppressed } \n" +
" OPTIONAL { ?configuration config:addLinkSuppressed ?addLinkSuppressed } \n" +
" OPTIONAL { ?configuration config:deleteLinkSuppressed ?deleteLinkSuppressed } \n" +
" OPTIONAL { ?configuration vitro:displayRankAnnot ?displayRank } \n" +
" OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" + " OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" +
" OPTIONAL { ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" + " OPTIONAL { ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" +
" OPTIONAL { ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n" + " OPTIONAL { ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n" +
@ -314,6 +340,11 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
if (groupRes != null) { if (groupRes != null) {
op.setGroupURI(groupRes.getURI()); op.setGroupURI(groupRes.getURI());
} }
Literal displayRankLit = qsoln.getLiteral("displayRank");
if(displayRankLit != null) {
op.setDomainDisplayTier(
Integer.parseInt(displayRankLit.getLexicalForm()));
}
Resource displayLevelRes = qsoln.getResource("displayLevel"); Resource displayLevelRes = qsoln.getResource("displayLevel");
if (displayLevelRes != null) { if (displayLevelRes != null) {
op.setHiddenFromDisplayBelowRoleLevel( op.setHiddenFromDisplayBelowRoleLevel(
@ -334,6 +365,18 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
if (customFormLit != null) { if (customFormLit != null) {
op.setCustomEntryForm(customFormLit.getLexicalForm()); op.setCustomEntryForm(customFormLit.getLexicalForm());
} }
Literal editLinkSuppressedLit = qsoln.getLiteral("editLinkSuppressed");
if (editLinkSuppressedLit != null ) {
op.setEditLinkSuppressed(editLinkSuppressedLit.getBoolean());
}
Literal addLinkSuppressedLit = qsoln.getLiteral("addLinkSuppressed");
if (addLinkSuppressedLit != null ) {
op.setAddLinkSuppressed(addLinkSuppressedLit.getBoolean());
}
Literal deleteLinkSuppressedLit = qsoln.getLiteral("deleteLinkSuppressed");
if (deleteLinkSuppressedLit != null ) {
op.setDeleteLinkSuppressed(deleteLinkSuppressedLit.getBoolean());
}
} }
} finally { } finally {
qe.close(); qe.close();
@ -902,14 +945,14 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
protected static final String LIST_VIEW_CONFIG_FILE_QUERY_STRING = protected static final String LIST_VIEW_CONFIG_FILE_QUERY_STRING =
"PREFIX display: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> \n" + "PREFIX display: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> \n" +
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" + "PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
"SELECT ?property ?range ?filename WHERE { \n" + "SELECT ?property ?range ?domain ?filename WHERE { \n" +
" { ?property display:listViewConfigFile ?filename \n" + " { ?property display:listViewConfigFile ?filename \n" +
" } UNION { \n" + " } UNION { \n" +
" ?lv config:listViewConfigFile ?filename . \n " + " ?configuration config:listViewConfigFile ?filename . \n " +
" ?configuration config:hasListView ?lv . " +
" ?context config:hasConfiguration ?configuration . \n" + " ?context config:hasConfiguration ?configuration . \n" +
" ?context config:configContextFor ?property . \n" + " ?context config:configContextFor ?property . \n" +
" ?context config:qualifiedBy ?range . \n" + " ?context config:qualifiedBy ?range . \n" +
" OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" +
" } \n" + " } \n" +
"}"; "}";
@ -925,14 +968,15 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
//TODO private void addPropertyClassCombinationsToListViewMap(HashMap) //TODO private void addPropertyClassCombinationsToListViewMap(HashMap)
// Map key is pair of object property and range class URI // Map key is inner pair of object property and range class URI,
// If range is unspecified, OWL.Thing.getURI() is used in the key. // with first member of outer pair being a domain class URI.
Map<Pair<ObjectProperty, String>, String> customListViewConfigFileMap = null; // If domain or range is unspecified, OWL.Thing.getURI() is used in the key.
Map<Pair<String,Pair<ObjectProperty, String>>, String> customListViewConfigFileMap = null;
@Override @Override
public String getCustomListViewConfigFileName(ObjectProperty op) { public String getCustomListViewConfigFileName(ObjectProperty op) {
if (customListViewConfigFileMap == null) { if (customListViewConfigFileMap == null) {
customListViewConfigFileMap = new HashMap<Pair<ObjectProperty, String>, String>(); customListViewConfigFileMap = new HashMap<Pair<String,Pair<ObjectProperty, String>>, String>();
OntModel displayModel = getOntModelSelector().getDisplayModel(); OntModel displayModel = getOntModelSelector().getDisplayModel();
//Get all property to list view config file mappings in the system //Get all property to list view config file mappings in the system
QueryExecution qexec = QueryExecutionFactory.create(listViewConfigFileQuery, displayModel); QueryExecution qexec = QueryExecutionFactory.create(listViewConfigFileQuery, displayModel);
@ -945,6 +989,10 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
String rangeUri = (rangeNode != null) String rangeUri = (rangeNode != null)
? ((Resource) rangeNode).getURI() ? ((Resource) rangeNode).getURI()
: OWL.Thing.getURI(); : OWL.Thing.getURI();
RDFNode domainNode = soln.get("domain");
String domainUri = (domainNode != null)
? ((Resource) domainNode).getURI()
: OWL.Thing.getURI();
ObjectProperty prop = getObjectPropertyByURI(propertyUri); ObjectProperty prop = getObjectPropertyByURI(propertyUri);
if (prop == null) { if (prop == null) {
//This is a warning only if this property is the one for which we're searching //This is a warning only if this property is the one for which we're searching
@ -955,15 +1003,24 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
} }
} else { } else {
String filename = soln.getLiteral("filename").getLexicalForm(); String filename = soln.getLiteral("filename").getLexicalForm();
customListViewConfigFileMap.put(new Pair<ObjectProperty, String>(prop, rangeUri), filename); log.debug("putting " + domainUri + " " + prop.getURI() + " " + rangeUri + " " + filename + " into list view map");
customListViewConfigFileMap.put(
new Pair<String,Pair<ObjectProperty,String>>(
domainUri, new Pair<ObjectProperty, String>(
prop, rangeUri)), filename);
} }
} }
qexec.close(); qexec.close();
} }
String customListViewConfigFileName = customListViewConfigFileMap.get(new Pair<ObjectProperty, String>(op, op.getRangeVClassURI())); String customListViewConfigFileName = customListViewConfigFileMap.get(new Pair<String, Pair<ObjectProperty, String>>(op.getDomainVClassURI(), new Pair<ObjectProperty,String>(op, op.getRangeVClassURI())));
if (customListViewConfigFileName == null) { if (customListViewConfigFileName == null) {
customListViewConfigFileName = customListViewConfigFileMap.get(new Pair<ObjectProperty, String>(op, OWL.Thing.getURI())); log.debug("no list view found for " + op.getURI() + " qualified by range " + op.getRangeVClassURI() + " and domain " + op.getDomainVClassURI());
customListViewConfigFileName = customListViewConfigFileMap.get(new Pair<String, Pair<ObjectProperty, String>>(OWL.Thing.getURI(), new Pair<ObjectProperty,String>(op, op.getRangeVClassURI())));
}
if (customListViewConfigFileName == null) {
log.debug("no list view found for " + op.getURI() + " qualified by range " + op.getRangeVClassURI());
customListViewConfigFileName = customListViewConfigFileMap.get(new Pair<String, Pair<ObjectProperty, String>>(OWL.Thing.getURI(), new Pair<ObjectProperty,String>(op, OWL.Thing.getURI())));
} }
return customListViewConfigFileName; return customListViewConfigFileName;

View file

@ -273,8 +273,7 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty( public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri, String subjectUri,
String propertyUri, String propertyUri,
String objectKey, String objectKey, String domainUri, String rangeUri,
String rangeUri,
String queryString, String queryString,
Set<String> constructQueryStrings, Set<String> constructQueryStrings,
String sortDirection) { String sortDirection) {
@ -282,11 +281,13 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
Model constructedModel = constructModelForSelectQueries( Model constructedModel = constructModelForSelectQueries(
subjectUri, propertyUri, constructQueryStrings); subjectUri, propertyUri, constructQueryStrings);
if(log.isDebugEnabled()) {
log.debug("Constructed model has " + constructedModel.size() + " statements.");
}
if("desc".equalsIgnoreCase( sortDirection ) ){ if("desc".equalsIgnoreCase( sortDirection ) ){
queryString = queryString.replaceAll(" ASC\\(", " DESC("); queryString = queryString.replaceAll(" ASC\\(", " DESC(");
} }
log.debug("Query string for object property " + propertyUri + ": " + queryString);
Query query = null; Query query = null;
try { try {
@ -300,10 +301,15 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
QuerySolutionMap initialBindings = new QuerySolutionMap(); QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("subject", ResourceFactory.createResource(subjectUri)); initialBindings.add("subject", ResourceFactory.createResource(subjectUri));
initialBindings.add("property", ResourceFactory.createResource(propertyUri)); initialBindings.add("property", ResourceFactory.createResource(propertyUri));
if (rangeUri != null) { if (domainUri != null && !domainUri.startsWith(VitroVocabulary.PSEUDO_BNODE_NS)) {
initialBindings.add("subjectType", ResourceFactory.createResource(domainUri));
}
if (rangeUri != null && !rangeUri.startsWith(VitroVocabulary.PSEUDO_BNODE_NS)) {
initialBindings.add("objectType", ResourceFactory.createResource(rangeUri)); initialBindings.add("objectType", ResourceFactory.createResource(rangeUri));
} }
log.debug("Query string for object property " + propertyUri + ": " + queryString);
// Run the SPARQL query to get the properties // Run the SPARQL query to get the properties
List<Map<String, String>> list = new ArrayList<Map<String, String>>(); List<Map<String, String>> list = new ArrayList<Map<String, String>>();
DatasetWrapper w = dwf.getDatasetWrapper(); DatasetWrapper w = dwf.getDatasetWrapper();
@ -353,13 +359,13 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
Model constructedModel = ModelFactory.createDefaultModel(); Model constructedModel = ModelFactory.createDefaultModel();
for (String queryString : constructQueries) { for (String queryString : constructQueries) {
queryString = queryString.replace("?subject", "<" + subjectUri + ">");
queryString = queryString.replace("?property", "<" + propertyUri + ">");
log.debug("CONSTRUCT query string for object property " + log.debug("CONSTRUCT query string for object property " +
propertyUri + ": " + queryString); propertyUri + ": " + queryString);
queryString = queryString.replace("?subject", "<" + subjectUri + ">");
queryString = queryString.replace("?property", "<" + propertyUri + ">");
// we no longer need this query object, but we might want to do this // we no longer need this query object, but we might want to do this
// query parse step to improve debugging, depending on the error returned // query parse step to improve debugging, depending on the error returned
// through the RDF API // through the RDF API

View file

@ -16,6 +16,7 @@ import java.util.Set;
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.ontology.IntersectionClass;
import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntProperty; import com.hp.hpl.jena.ontology.OntProperty;
@ -33,6 +34,7 @@ import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement; 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.sdb.util.Pair;
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.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.OWL;
@ -51,7 +53,8 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.event.EditEvent;
public class PropertyDaoJena extends JenaBaseDao implements PropertyDao { public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
protected static final Log log = LogFactory.getLog(PropertyDaoJena.class.getName()); protected static final Log log = LogFactory.getLog(PropertyDaoJena.class.getName());
protected static final String FAUX_PROPERTY_FLAG = "FAUX";
private static final Map<String, String> NAMESPACES = new HashMap<String, String>() {{ private static final Map<String, String> NAMESPACES = new HashMap<String, String>() {{
put("afn", VitroVocabulary.AFN); put("afn", VitroVocabulary.AFN);
put("owl", VitroVocabulary.OWL); put("owl", VitroVocabulary.OWL);
@ -328,7 +331,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
public List <VClass> getClassesWithRestrictionOnProperty(String propertyURI) { public List <VClass> getClassesWithRestrictionOnProperty(String propertyURI) {
if (propertyURI == null) { if (propertyURI == null) {
log.info("getClassesWithRestrictionOnProperty: called with null propertyURI"); log.warn("getClassesWithRestrictionOnProperty: called with null propertyURI");
return null; return null;
} }
@ -348,7 +351,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
Statement statement = stmtIter.next(); Statement statement = stmtIter.next();
if ( statement.getSubject().canAs(OntClass.class) ) { if ( statement.getSubject().canAs(OntClass.class) ) {
classURISet.addAll(getRelatedClasses(statement.getSubject().as(OntClass.class))); classURISet.addAll(getRestrictedClasses(statement.getSubject().as(OntClass.class)));
} else { } else {
log.warn("getClassesWithRestrictionOnProperty: Unexpected use of onProperty: it is not applied to a class"); log.warn("getClassesWithRestrictionOnProperty: Unexpected use of onProperty: it is not applied to a class");
} }
@ -381,9 +384,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
} }
/** /**
* Finds all named superclasses, subclasses and equivalent classes of * Find named classes to which a restriction "applies"
* the given class.
*
* @param resourceURI identifier of a class * @param resourceURI identifier of a class
* @return set of class URIs * @return set of class URIs
* *
@ -391,13 +392,12 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
* the ontology model. * the ontology model.
*/ */
public HashSet<String> getRelatedClasses(OntClass ontClass) { public HashSet<String> getRestrictedClasses(OntClass ontClass) {
HashSet<String> classSet = new HashSet<String>(); HashSet<String> classSet = new HashSet<String>();
List<OntClass> classList = ontClass.listEquivalentClasses().toList(); List<OntClass> classList = ontClass.listEquivalentClasses().toList();
classList.addAll(ontClass.listSubClasses().toList()); classList.addAll(ontClass.listSubClasses().toList());
classList.addAll(ontClass.listSuperClasses().toList());
Iterator<OntClass> it = classList.iterator(); Iterator<OntClass> it = classList.iterator();
@ -406,6 +406,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
if (!oc.isAnon()) { if (!oc.isAnon()) {
classSet.add(oc.getURI()); classSet.add(oc.getURI());
} else {
classSet.addAll(getRestrictedClasses(oc));
} }
} }
@ -524,15 +526,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
} }
} }
List<PropertyInstance> piList = getAllPropInstByVClasses(vclasses); return getAllPropInstByVClasses(vclasses);
for (PropertyInstance pi : piList) {
pi.setDomainClassURI(ind.getVClassURI());
// TODO: improve. This is so the DWR property editing passes the
// individual's VClass to get the right restrictions
}
return piList;
} }
/* /*
@ -621,6 +616,42 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
return classes; return classes;
} }
private static final int DEPTH_LIMIT = 20;
private List<Restriction> getRelatedRestrictions(OntClass ontClass) {
return getRelatedRestrictions(ontClass, new ArrayList<Restriction>(), DEPTH_LIMIT);
}
private List<Restriction> getRelatedRestrictions(OntClass ontClass,
List<Restriction> relatedRestrictions, int limit) {
limit--;
if (ontClass.isRestriction()) {
relatedRestrictions.add(ontClass.as(Restriction.class));
} else if (ontClass.isIntersectionClass()) {
IntersectionClass inter = ontClass.as(IntersectionClass.class);
Iterator<? extends OntClass> operIt = inter.listOperands();
while (operIt.hasNext()) {
OntClass operand = operIt.next();
if (!relatedRestrictions.contains(operand) && limit > 0) {
relatedRestrictions.addAll(
getRelatedRestrictions(
operand, relatedRestrictions, limit));
}
}
} else {
List<OntClass> superClasses = listSuperClasses(ontClass);
superClasses.addAll(listEquivalentClasses(ontClass));
for (OntClass sup : superClasses) {
if (sup.isAnon() && !sup.equals(ontClass)
&& !relatedRestrictions.contains(ontClass) && limit > 0) {
relatedRestrictions.addAll(
getRelatedRestrictions(sup, relatedRestrictions, limit));
}
}
}
return relatedRestrictions;
}
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>();
@ -651,55 +682,52 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
String VClassURI = vclass.getURI(); String VClassURI = vclass.getURI();
OntClass ontClass = getOntClass(ontModel,VClassURI); OntClass ontClass = getOntClass(ontModel,VClassURI);
if (ontClass != null) { if (ontClass == null) {
List<OntClass> relatedClasses = new ArrayList<OntClass>(); continue;
relatedClasses.addAll(listEquivalentClasses(ontClass));
relatedClasses.addAll(listSuperClasses(ontClass));
for (OntClass relatedClass : relatedClasses) {
// find properties in restrictions
if (relatedClass.isRestriction() && relatedClass.canAs(Restriction.class)) {
// TODO: check if restriction is something like
// maxCardinality 0 or allValuesFrom owl:Nothing,
// in which case the property is NOT applicable!
Restriction rest = relatedClass.as(Restriction.class);
OntProperty onProperty = rest.getOnProperty();
if (onProperty != null) {
Resource[] ranges = new Resource[2];
if (rest.isAllValuesFromRestriction()) {
ranges[0] = (rest.asAllValuesFromRestriction()).getAllValuesFrom();
} else if (rest.isSomeValuesFromRestriction()) {
ranges[1] = (rest.asSomeValuesFromRestriction()).getSomeValuesFrom();
}
updatePropertyRangeMap(applicableProperties, onProperty.getURI(), ranges);
}
}
}
List<Resource> propertyList =
getPropertiesWithAppropriateDomainFor(VClassURI);
for (Resource prop : propertyList) {
if (prop.getNameSpace() != null
&& !NONUSER_NAMESPACES.contains(
prop.getNameSpace()) ) {
StmtIterator rangeSit = prop.listProperties(
RDFS.range);
Resource rangeRes = null;
while (rangeSit.hasNext()) {
Statement s = rangeSit.nextStatement();
if (s.getObject().isURIResource()) {
rangeRes = (Resource) s.getObject();
}
}
Resource[] ranges = new Resource[2];
ranges[0] = rangeRes;
updatePropertyRangeMap(
applicableProperties, prop.getURI(), ranges);
}
}
} }
} List<Restriction> relatedRestrictions = getRelatedRestrictions(ontClass);
for (Restriction rest : relatedRestrictions) {
// find properties in restrictions
// TODO: check if restriction is something like
// maxCardinality 0 or allValuesFrom owl:Nothing,
// in which case the property is NOT applicable!
OntProperty onProperty = rest.getOnProperty();
if (onProperty != null) {
Resource[] ranges = new Resource[2];
if (rest.isAllValuesFromRestriction()) {
ranges[0] = (rest.asAllValuesFromRestriction()).getAllValuesFrom();
} else if (rest.isSomeValuesFromRestriction()) {
ranges[1] = (rest.asSomeValuesFromRestriction()).getSomeValuesFrom();
}
updatePropertyRangeMap(applicableProperties, onProperty.getURI(), ranges);
}
}
List<Resource> propertyList =
getPropertiesWithAppropriateDomainFor(VClassURI);
for (Resource prop : propertyList) {
if (prop.getNameSpace() != null
&& !NONUSER_NAMESPACES.contains(
prop.getNameSpace()) ) {
StmtIterator rangeSit = prop.listProperties(
RDFS.range);
Resource rangeRes = null;
while (rangeSit.hasNext()) {
Statement s = rangeSit.nextStatement();
if (s.getObject().isURIResource()) {
rangeRes = (Resource) s.getObject();
}
}
Resource[] ranges = new Resource[2];
ranges[0] = rangeRes;
updatePropertyRangeMap(
applicableProperties, prop.getURI(), ranges);
}
}
}
} catch (Exception e) { } catch (Exception e) {
log.error("Unable to get applicable properties " + log.error("Unable to get applicable properties " +
"by examining property restrictions and domains", e); "by examining property restrictions and domains", e);
@ -718,12 +746,36 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
: (op.getRange() == null && foundRanges[1] != null) : (op.getRange() == null && foundRanges[1] != null)
? foundRanges[1] ? foundRanges[1]
: op.getRange(); : op.getRange();
propInsts.add(getPropInstForPropertyAndRange(op, rangeRes, applicableProperties)); Resource domainRes = op.getDomain();
List<String> additionalFauxSubpropertyRangeURIs = getAdditionalFauxSubpropertyRangeURIsForPropertyURI(propertyURI); propInsts.add(getPropInst(
for (String rangeURI : additionalFauxSubpropertyRangeURIs) { op, domainRes, rangeRes, applicableProperties));
if (getWebappDaoFactory().getVClassDao().isSubClassOf(rangeURI, rangeRes.getURI())) { List<Pair<String,String>> additionalFauxSubpropertyDomainAndRangeURIs =
propInsts.add(getPropInstForPropertyAndRange( getAdditionalFauxSubpropertyDomainAndRangeURIsForPropertyURI(
op, ResourceFactory.createResource(rangeURI), applicableProperties)); propertyURI);
for (Pair<String,String> domainAndRangeURIs :
additionalFauxSubpropertyDomainAndRangeURIs) {
boolean applicablePropInst = false;
if (rangeRes == null ||
!getWebappDaoFactory().getVClassDao().isSubClassOf(
rangeRes.getURI(), domainAndRangeURIs.getRight())) {
if (domainAndRangeURIs.getLeft() == null) {
applicablePropInst = true;
} else {
for(VClass vclass : vclasses) {
if (vclass.getURI() != null && vclass.getURI().equals(
domainAndRangeURIs.getLeft())) {
applicablePropInst = true;
break;
}
}
}
if (applicablePropInst) {
propInsts.add(getPropInst(
op,
ResourceFactory.createResource(domainAndRangeURIs.getLeft()),
ResourceFactory.createResource(domainAndRangeURIs.getRight()),
applicableProperties));
}
} }
} }
} }
@ -736,11 +788,19 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
} }
private PropertyInstance getPropInstForPropertyAndRange(OntProperty op, Resource rangeRes, private PropertyInstance getPropInst(OntProperty op, Resource domainRes, Resource rangeRes,
Map<String, Resource[]> applicableProperties) { Map<String, Resource[]> applicableProperties) {
if (log.isDebugEnabled() && domainRes != null && rangeRes != null) {
log.debug("getPropInst() op: " + op.getURI() + " domain: " +
domainRes.getURI() + " range: " + rangeRes.getURI());
}
PropertyInstance pi = new PropertyInstance(); PropertyInstance pi = new PropertyInstance();
String domainURIStr = getURIStr(op.getDomain()); String domainURIStr = (domainRes != null && !domainRes.isAnon()) ?
if (rangeRes != null) { domainURIStr = domainRes.getURI()
: null;
if (rangeRes == null) {
pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above
} else {
String rangeClassURI; String rangeClassURI;
if (rangeRes.isAnon()) { if (rangeRes.isAnon()) {
rangeClassURI = PSEUDO_BNODE_NS + rangeRes.getId() rangeClassURI = PSEUDO_BNODE_NS + rangeRes.getId()
@ -757,18 +817,18 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
range.setName(range.getLocalName()); range.setName(range.getLocalName());
} }
pi.setRangeClassName(range.getName()); pi.setRangeClassName(range.getName());
} else {
pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above
} }
pi.setDomainClassURI(domainURIStr); pi.setDomainClassURI(domainURIStr);
VClass domain = getWebappDaoFactory().getVClassDao() if (domainURIStr != null) {
.getVClassByURI(domainURIStr); VClass domain = getWebappDaoFactory().getVClassDao()
if (domain == null) { .getVClassByURI(domainURIStr);
domain = new VClass(); if (domain == null) {
domain.setURI(domainURIStr); domain = new VClass();
domain.setName(domain.getLocalName()); domain.setURI(domainURIStr);
domain.setName(domain.getLocalName());
}
pi.setDomainClassName(domain.getName());
} }
pi.setDomainClassName(domain.getName());
pi.setSubjectSide(true); pi.setSubjectSide(true);
pi.setPropertyURI(op.getURI()); pi.setPropertyURI(op.getURI());
pi.setPropertyName(getLabelOrId(op)); // TODO pi.setPropertyName(getLabelOrId(op)); // TODO
@ -777,14 +837,15 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
return pi; return pi;
} }
private List<String> getAdditionalFauxSubpropertyRangeURIsForPropertyURI(String propertyURI) { private List<Pair<String,String>> getAdditionalFauxSubpropertyDomainAndRangeURIsForPropertyURI(String propertyURI) {
List<String> rangeURIs = new ArrayList<String>(); List<Pair<String,String>> domainAndRangeURIs = new ArrayList<Pair<String,String>>();
String propQuery = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" + String propQuery = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" + "PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" + "PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
"SELECT ?range WHERE { \n" + "SELECT ?domain ?range WHERE { \n" +
" ?context config:configContextFor <" + propertyURI + "> . \n" + " ?context config:configContextFor <" + propertyURI + "> . \n" +
" ?context config:qualifiedBy ?range . \n" + " ?context config:qualifiedBy ?range . \n" +
" OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" +
"}"; "}";
Query q = QueryFactory.create(propQuery); Query q = QueryFactory.create(propQuery);
@ -794,12 +855,18 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
while (rs.hasNext()) { while (rs.hasNext()) {
QuerySolution qsoln = rs.nextSolution(); QuerySolution qsoln = rs.nextSolution();
Resource rangeRes = qsoln.getResource("range"); Resource rangeRes = qsoln.getResource("range");
rangeURIs.add(rangeRes.getURI()); String rangeURI = rangeRes.getURI();
Resource domainRes = qsoln.getResource("domain");
String domainURI = null;
if (domainRes != null && !domainRes.isAnon()) {
domainURI = domainRes.getURI();
}
domainAndRangeURIs.add(new Pair<String,String>(domainURI, rangeURI));
} }
} finally { } finally {
qe.close(); qe.close();
} }
return rangeURIs; return domainAndRangeURIs;
} }
private String getURIStr(Resource res) { private String getURIStr(Resource res) {

View file

@ -462,9 +462,11 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao {
while (classIt.hasNext()) { while (classIt.hasNext()) {
try { try {
Individual classInd = classIt.next(); Individual classInd = classIt.next();
OntClass cls = classInd.as(OntClass.class); if(classInd.canAs(OntClass.class)) {
if (!cls.isAnon() && !(NONUSER_NAMESPACES.contains(cls.getNameSpace()))) { OntClass cls = classInd.as(OntClass.class);
classes.add(new VClassJena(cls,getWebappDaoFactory())); if (!cls.isAnon() && !(NONUSER_NAMESPACES.contains(cls.getNameSpace()))) {
classes.add(new VClassJena(cls,getWebappDaoFactory()));
}
} }
} catch (ClassCastException cce) { } catch (ClassCastException cce) {
log.error(cce, cce); log.error(cce, cce);
@ -1091,11 +1093,8 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao {
OntModel ontModel = getOntModel(); OntModel ontModel = getOntModel();
try { try {
ontModel.enterCriticalSection(Lock.READ); ontModel.enterCriticalSection(Lock.READ);
OntClass oc1 = getOntClass(ontModel, vclassURI1); Resource oc1 = ontModel.getResource(vclassURI1);
OntClass oc2 = getOntClass(ontModel, vclassURI2); Resource oc2 = ontModel.getResource(vclassURI2);
if (oc1 == null || oc2 == null) {
return false;
}
return ontModel.contains(oc1, RDFS.subClassOf, oc2); return ontModel.contains(oc1, RDFS.subClassOf, oc2);
} finally { } finally {
ontModel.leaveCriticalSection(); ontModel.leaveCriticalSection();

View file

@ -2,10 +2,15 @@
package edu.cornell.mannlib.vitro.webapp.dao.jena; package edu.cornell.mannlib.vitro.webapp.dao.jena;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
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.ontology.OntClass; import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.UnionClass;
import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.Statement;
@ -376,4 +381,27 @@ public class VClassJena extends VClass {
} }
} }
} }
@Override
public boolean isUnion() {
return this.cls.isUnionClass();
}
//TODO consider anonymous components
@Override
public List<VClass> getUnionComponents() {
List<VClass> unionComponents = new ArrayList<VClass>();
if (isUnion()) {
UnionClass union = this.cls.as(UnionClass.class);
Iterator<? extends OntClass> opIt = union.listOperands();
while(opIt.hasNext()) {
OntClass component = opIt.next();
if (!component.isAnon()) {
unionComponents.add(new VClassJena(component, this.webappDaoFactory));
}
}
}
return unionComponents;
}
} }

View file

@ -624,8 +624,10 @@ public class PelletListener implements ModelChangedListener {
if ( (additionModel.size() > 0) || (removalModel.size()>0) ) { if ( (additionModel.size() > 0) || (removalModel.size()>0) ) {
if (!isSynchronizing) { if (!isSynchronizing) {
if (foreground) { if (foreground) {
log.debug("Running Pellet in foreground.");
(new PelletSynchronizer()).run(); (new PelletSynchronizer()).run();
} else { } else {
log.debug("Running Pellet in background.");
new Thread(new PelletSynchronizer(), "PelletListener.PelletSynchronizer").start(); new Thread(new PelletSynchronizer(), "PelletListener.PelletSynchronizer").start();
} }
} }

View file

@ -30,8 +30,7 @@ public class ReasonerConfiguration {
/** /**
* The default reasoner configuration is designed to provide acceptable performance on larger knowledge bases. * The default reasoner configuration is designed to provide acceptable performance on larger knowledge bases.
* It will classify and realize, and add inferred disjointWith statements. * It will classify and realize, and add inferred disjointWith statements.
* It ignores domain and range "axioms," on the assumption that they are not truly axioms but editing constraints. * It ignores domain and range "axioms," on the assumption that they are not truly axioms but editing constraints.
* It also ignores "owl:inverseOf."
*/ */
public static ReasonerConfiguration DEFAULT; public static ReasonerConfiguration DEFAULT;
@ -78,6 +77,7 @@ public class ReasonerConfiguration {
defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,RDF.first,null)); defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,RDF.first,null));
defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,RDF.rest,null)); defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,RDF.rest,null));
defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,OWL.disjointWith,null)); defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,OWL.disjointWith,null));
defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,OWL.inverseOf,null));
DEFAULT.setInferenceDrivingPatternAllowSet(defaultInferenceDrivingPatternAllowSet); DEFAULT.setInferenceDrivingPatternAllowSet(defaultInferenceDrivingPatternAllowSet);
Set<ObjectPropertyStatementPattern> defaultInferenceReceivingPatternAllowSet = new HashSet<ObjectPropertyStatementPattern>(); Set<ObjectPropertyStatementPattern> defaultInferenceReceivingPatternAllowSet = new HashSet<ObjectPropertyStatementPattern>();
defaultInferenceReceivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,RDF.type,null)); defaultInferenceReceivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,RDF.type,null));

View file

@ -53,12 +53,22 @@ public class EditConfigurationUtils {
return vreq.getParameter("objectUri"); return vreq.getParameter("objectUri");
} }
public static String getDomainUri(VitroRequest vreq) {
return vreq.getParameter("domainUri");
}
public static String getRangeUri(VitroRequest vreq) { public static String getRangeUri(VitroRequest vreq) {
return vreq.getParameter("rangeUri"); return vreq.getParameter("rangeUri");
} }
public static VClass getRangeVClass(VitroRequest vreq) { public static VClass getRangeVClass(VitroRequest vreq) {
return vreq.getWebappDaoFactory().getVClassDao().getVClassByURI(getRangeUri(vreq)); // This needs a WebappDaoFactory with no filtering/RDFService
// funny business because it needs to be able to retrieve anonymous union
// classes by their "pseudo-bnode URIs".
// Someday we'll need to figure out a different way of doing this.
WebappDaoFactory ctxDaoFact = ModelAccess.on(
vreq.getSession().getServletContext()).getWebappDaoFactory();
return ctxDaoFact.getVClassDao().getVClassByURI(getRangeUri(vreq));
} }
//get individual //get individual

View file

@ -27,13 +27,13 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
private static final String LEFT_BLANK = ""; private static final String LEFT_BLANK = "";
private String subjectUri; private String subjectUri;
private String predicateUri; private String predicateUri;
private String rangeUri; private List<VClass> rangeTypes;
private String objectUri; private String objectUri;
private String defaultOptionLabel; private String defaultOptionLabel;
public IndividualsViaObjectPropetyOptions(String subjectUri, public IndividualsViaObjectPropetyOptions(String subjectUri,
String predicateUri, String rangeUri, String objectUri) throws Exception { String predicateUri, List<VClass> rangeTypes, String objectUri) throws Exception {
super(); super();
if (subjectUri == null || subjectUri.equals("")) { if (subjectUri == null || subjectUri.equals("")) {
@ -45,7 +45,7 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
this.subjectUri = subjectUri; this.subjectUri = subjectUri;
this.predicateUri = predicateUri; this.predicateUri = predicateUri;
this.rangeUri = rangeUri; this.rangeTypes = rangeTypes;
this.objectUri = objectUri; this.objectUri = objectUri;
} }
@ -78,8 +78,8 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
//get all vclasses applicable to the individual subject //get all vclasses applicable to the individual subject
HashSet<String> vclassesURIs = getApplicableVClassURIs(subject, wDaoFact); HashSet<String> vclassesURIs = getApplicableVClassURIs(subject, wDaoFact);
if (rangeUri != null) { if (!rangeTypes.isEmpty()) {
vclassesURIs = filterToSubclassesOfRange(vclassesURIs, rangeUri, wDaoFact); vclassesURIs = filterToSubclassesOfRange(vclassesURIs, rangeTypes, wDaoFact);
} }
if (vclassesURIs.size() == 0) { if (vclassesURIs.size() == 0) {
@ -117,9 +117,13 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
private HashSet<String> getApplicableVClassURIs(Individual subject, WebappDaoFactory wDaoFact) { private HashSet<String> getApplicableVClassURIs(Individual subject, WebappDaoFactory wDaoFact) {
HashSet<String> vclassesURIs = new HashSet<String>(); HashSet<String> vclassesURIs = new HashSet<String>();
if (rangeUri != null) { if (!rangeTypes.isEmpty()) {
log.debug("individualsViaObjectProperty using rangeUri " + rangeUri); StringBuffer rangeBuff = new StringBuffer();
vclassesURIs.add(rangeUri); for (VClass rangeType : rangeTypes) {
vclassesURIs.add(rangeType.getURI());
rangeBuff.append(rangeType.getURI()).append(", ");
}
log.debug("individualsViaObjectProperty using rangeUri " + rangeBuff.toString());
return vclassesURIs; return vclassesURIs;
} }
@ -144,13 +148,15 @@ public class IndividualsViaObjectPropetyOptions implements FieldOptions {
} }
private HashSet<String> filterToSubclassesOfRange(HashSet<String> vclassesURIs, private HashSet<String> filterToSubclassesOfRange(HashSet<String> vclassesURIs,
String rangeUri, List<VClass> rangeTypes,
WebappDaoFactory wDaoFact) { WebappDaoFactory wDaoFact) {
HashSet<String> filteredVClassesURIs = new HashSet<String>(); HashSet<String> filteredVClassesURIs = new HashSet<String>();
VClassDao vcDao = wDaoFact.getVClassDao(); VClassDao vcDao = wDaoFact.getVClassDao();
for (String vclass : vclassesURIs) { for (String vclass : vclassesURIs) {
if (vclass.equals(rangeUri) || vcDao.isSubClassOf(vclass, rangeUri)) { for (VClass rangeType : rangeTypes) {
filteredVClassesURIs.add(vclass); if (vclass.equals(rangeType.getURI()) || vcDao.isSubClassOf(vclass, rangeType.getURI())) {
filteredVClassesURIs.add(vclass);
}
} }
} }
return filteredVClassesURIs; return filteredVClassesURIs;

View file

@ -99,41 +99,60 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
return getDefaultObjectEditConfiguration(vreq, session); return getDefaultObjectEditConfiguration(vreq, session);
} }
protected List<String> getRangeTypes(VitroRequest vreq) { protected List<VClass> getRangeTypes(VitroRequest vreq) {
WebappDaoFactory wDaoFact = vreq.getWebappDaoFactory(); // This first part needs a WebappDaoFactory with no filtering/RDFService
List<String> types = new ArrayList<String>(); // funny business because it needs to be able to retrieve anonymous union
// classes by their "pseudo-bnode URIs".
// Someday we'll need to figure out a different way of doing this.
WebappDaoFactory ctxDaoFact = ModelAccess.on(
vreq.getSession().getServletContext()).getWebappDaoFactory();
List<VClass> types = new ArrayList<VClass>();
Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq); Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq);
String predicateUri = EditConfigurationUtils.getPredicateUri(vreq); String predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
String rangeUri = EditConfigurationUtils.getRangeUri(vreq); String rangeUri = EditConfigurationUtils.getRangeUri(vreq);
if (rangeUri != null) { if (rangeUri != null) {
types.add(rangeUri); VClass rangeVClass = ctxDaoFact.getVClassDao().getVClassByURI(rangeUri);
if (!rangeVClass.isUnion()) {
types.add(rangeVClass);
} else {
for (VClass unionComponent : rangeVClass.getUnionComponents()) {
types.add(unionComponent);
}
}
return types; return types;
} }
WebappDaoFactory wDaoFact = vreq.getWebappDaoFactory();
//Get all vclasses applicable to subject //Get all vclasses applicable to subject
List<VClass> vClasses = subject.getVClasses(); List<VClass> vClasses = subject.getVClasses();
HashSet<String> typesHash = new HashSet<String>(); HashMap<String, VClass> typesHash = new HashMap<String, VClass>();
for(VClass vclass: vClasses) { for(VClass vclass: vClasses) {
List<VClass> rangeVclasses = wDaoFact.getVClassDao().getVClassesForProperty(vclass.getURI(),predicateUri); List<VClass> rangeVclasses = wDaoFact.getVClassDao().getVClassesForProperty(vclass.getURI(),predicateUri);
if(rangeVclasses != null) { if(rangeVclasses != null) {
for(VClass range: rangeVclasses) { for(VClass range: rangeVclasses) {
//a hash will keep a unique list of types and so prevent duplicates //a hash will keep a unique list of types and so prevent duplicates
typesHash.add(range.getURI()); typesHash.put(range.getURI(), range);
} }
} }
} }
types.addAll(typesHash); types.addAll(typesHash.values());
return types; return types;
} }
private boolean tooManyRangeOptions(VitroRequest vreq, HttpSession session ) throws SolrServerException { private boolean tooManyRangeOptions(VitroRequest vreq, HttpSession session ) throws SolrServerException {
List<String> types = getRangeTypes(vreq); List<VClass> rangeTypes = getRangeTypes(vreq);
SolrServer solrServer = SolrSetup.getSolrServer(session.getServletContext()); SolrServer solrServer = SolrSetup.getSolrServer(session.getServletContext());
List<String> types = new ArrayList<String>();
//empty list means the range is not set to anything, force Thing //empty list means the range is not set to anything, force Thing
if(types.size() == 0 ){ if(types.size() == 0 ){
types = new ArrayList<String>(); types.add(VitroVocabulary.OWL_THING);
types.add(VitroVocabulary.OWL_THING); } else {
} for (VClass vclass : rangeTypes) {
if (vclass.getURI() != null) {
types.add(vclass.getURI());
}
}
}
long count = 0; long count = 0;
for( String type:types){ for( String type:types){
@ -184,7 +203,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
this.setSparqlQueries(editConfiguration); this.setSparqlQueries(editConfiguration);
//set fields //set fields
setFields(editConfiguration, vreq, EditConfigurationUtils.getPredicateUri(vreq), EditConfigurationUtils.getRangeUri(vreq)); setFields(editConfiguration, vreq, EditConfigurationUtils.getPredicateUri(vreq), getRangeTypes(vreq));
// No need to put in session here b/c put in session within edit request dispatch controller instead // No need to put in session here b/c put in session within edit request dispatch controller instead
//placing in session depends on having edit key which is handled in edit request dispatch controller //placing in session depends on having edit key which is handled in edit request dispatch controller
@ -358,7 +377,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
setFields(editConfiguration, vreq, predicateUri, null); setFields(editConfiguration, vreq, predicateUri, null);
} }
protected void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri, String rangeUri) throws Exception { protected void setFields(EditConfigurationVTwo editConfiguration, VitroRequest vreq, String predicateUri, List<VClass> rangeTypes) throws Exception {
FieldVTwo field = new FieldVTwo(); FieldVTwo field = new FieldVTwo();
field.setName("objectVar"); field.setName("objectVar");
@ -370,7 +389,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
field.setOptions( new IndividualsViaObjectPropetyOptions( field.setOptions( new IndividualsViaObjectPropetyOptions(
subjectUri, subjectUri,
predicateUri, predicateUri,
rangeUri, rangeTypes,
objectUri)); objectUri));
}else{ }else{
field.setOptions(null); field.setOptions(null);
@ -441,14 +460,22 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
formSpecificData.put("editMode", getEditMode(vreq).toString().toLowerCase()); formSpecificData.put("editMode", getEditMode(vreq).toString().toLowerCase());
//We also need the type of the object itself //We also need the type of the object itself
List<String> types = getRangeTypes(vreq); List<VClass> types = getRangeTypes(vreq);
//if types array contains only owl:Thing, the search will not return any results //if types array contains only owl:Thing, the search will not return any results
//In this case, set an empty array //In this case, set an empty array
if(types.size() == 1 && types.get(0).equals(VitroVocabulary.OWL_THING) ){ if(types.size() == 1 && types.get(0).getURI().equals(VitroVocabulary.OWL_THING) ){
types = new ArrayList<String>(); types = new ArrayList<VClass>();
} }
formSpecificData.put("objectTypes", StringUtils.join(types, ",")); StringBuffer typesBuff = new StringBuffer();
for (VClass type : types) {
if (type.getURI() != null) {
typesBuff.append(type.getURI()).append(",");
}
}
formSpecificData.put("objectTypes", typesBuff.toString());
log.debug("autocomplete object types : " + formSpecificData.get("objectTypes"));
//Get label for individual if it exists //Get label for individual if it exists
if(EditConfigurationUtils.getObjectIndividual(vreq) != null) { if(EditConfigurationUtils.getObjectIndividual(vreq) != null) {
@ -464,15 +491,15 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
editConfiguration.setFormSpecificData(formSpecificData); editConfiguration.setFormSpecificData(formSpecificData);
} }
private Object rangeIndividualsExist(HttpSession session, List<String> types) throws SolrServerException { private Object rangeIndividualsExist(HttpSession session, List<VClass> types) throws SolrServerException {
SolrServer solrServer = SolrSetup.getSolrServer(session.getServletContext()); SolrServer solrServer = SolrSetup.getSolrServer(session.getServletContext());
boolean rangeIndividualsFound = false; boolean rangeIndividualsFound = false;
for( String type:types){ for( VClass type:types){
//solr for type count. //solr for type count.
SolrQuery query = new SolrQuery(); SolrQuery query = new SolrQuery();
query.setQuery( VitroSearchTermNames.RDFTYPE + ":" + type); query.setQuery( VitroSearchTermNames.RDFTYPE + ":" + type.getURI());
query.setRows(0); query.setRows(0);
QueryResponse rsp = solrServer.query(query); QueryResponse rsp = solrServer.query(query);

View file

@ -28,8 +28,10 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestActio
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClass;
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.jena.QueryUtils; import edu.cornell.mannlib.vitro.webapp.dao.jena.QueryUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
@ -272,7 +274,7 @@ public class ManageLabelsForIndividualGenerator extends BaseEditConfigurationGen
RequestActionConstants.SOME_URI); RequestActionConstants.SOME_URI);
AddObjectPropertyStatement aops = new AddObjectPropertyStatement( AddObjectPropertyStatement aops = new AddObjectPropertyStatement(
vreq.getJenaOntModel(), individual.getURI(), vreq.getJenaOntModel(), individual.getURI(),
RequestActionConstants.SOME_URI, RequestActionConstants.SOME_PREDICATE,
RequestActionConstants.SOME_URI); RequestActionConstants.SOME_URI);
return PolicyHelper.isAuthorizedForActions(vreq, new Actions(adps).or(aops)); return PolicyHelper.isAuthorizedForActions(vreq, new Actions(adps).or(aops));
} }
@ -317,8 +319,8 @@ public class ManageLabelsForIndividualGenerator extends BaseEditConfigurationGen
//This should put the label in the list //This should put the label in the list
//Create label information instance with the required information //Create label information instance with the required information
//To generate link //To generate link
DataPropertyStatementTemplateModel dpstm = new DataPropertyStatementTemplateModel(subjectUri, propertyUri, l, DataPropertyStatementTemplateModel dpstm = new DataPropertyStatementTemplateModel(
template, vreq); subjectUri, new Property(propertyUri), l, template, vreq);
labelsList.add(new LabelInformation( labelsList.add(new LabelInformation(
l, dpstm.getEditUrl(), dpstm.getDeleteUrl(), languageTag, languageName)); l, dpstm.getEditUrl(), dpstm.getDeleteUrl(), languageTag, languageName));
} }

View file

@ -171,6 +171,9 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
makeEditConfigurationVTwo( editConfGeneratorName, vreq, session); makeEditConfigurationVTwo( editConfGeneratorName, vreq, session);
} }
if(editConfig == null) {
log.error("editConfig is null! How did this happen?");
}
String editKey = EditConfigurationUtils.getEditKey(vreq); String editKey = EditConfigurationUtils.getEditKey(vreq);
editConfig.setEditKey(editKey); editConfig.setEditKey(editKey);
@ -199,6 +202,7 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
String editConfGeneratorName = null; String editConfGeneratorName = null;
String predicateUri = getPredicateUri(vreq); String predicateUri = getPredicateUri(vreq);
String domainUri = EditConfigurationUtils.getDomainUri(vreq);
String rangeUri = EditConfigurationUtils.getRangeUri(vreq); String rangeUri = EditConfigurationUtils.getRangeUri(vreq);
// *** handle the case where the form is specified as a request parameter *** // *** handle the case where the form is specified as a request parameter ***
@ -215,9 +219,9 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
// *** check for a predicate URI in the request // *** check for a predicate URI in the request
}else if( predicateUri != null && !predicateUri.isEmpty() ){ }else if( predicateUri != null && !predicateUri.isEmpty() ){
Property prop = getProperty( predicateUri, vreq); Property prop = getProperty( predicateUri, domainUri, rangeUri, vreq);
if (prop != null && rangeUri != null) { if (prop != null && rangeUri != null) {
editConfGeneratorName = getCustomEntryFormForPropertyAndRange(prop, rangeUri); editConfGeneratorName = getCustomEntryForm(prop);
} else if( prop != null && prop.getCustomEntryForm() != null ){ } else if( prop != null && prop.getCustomEntryForm() != null ){
//there is a custom form, great! let's use it. //there is a custom form, great! let's use it.
editConfGeneratorName = prop.getCustomEntryForm(); editConfGeneratorName = prop.getCustomEntryForm();
@ -247,25 +251,19 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
return editConfGeneratorName; return editConfGeneratorName;
} }
private String getCustomEntryFormForPropertyAndRange(Property prop, String rangeUri){ private String getCustomEntryForm(Property prop){
String entryFormName = null; if (prop.getCustomEntryForm() == null) {
// = ApplicationConfigurationOntologyUtils.getEntryForm(prop.getURI(), rangeUri); return DEFAULT_OBJ_FORM;
if (entryFormName == null) {
if (prop.getCustomEntryForm() != null) {
return prop.getCustomEntryForm();
} else {
return DEFAULT_OBJ_FORM;
}
} else { } else {
prop.setCustomEntryForm(entryFormName); return prop.getCustomEntryForm();
return entryFormName;
} }
} }
private Property getProperty(String predicateUri, VitroRequest vreq) { private Property getProperty(String predicateUri, String domainUri, String rangeUri, VitroRequest vreq) {
Property p = null; Property p = null;
try{ try{
p = vreq.getWebappDaoFactory().getObjectPropertyDao().getObjectPropertyByURI(predicateUri); p = vreq.getWebappDaoFactory().getObjectPropertyDao().getObjectPropertyByURIs(
predicateUri, domainUri, rangeUri);
if(p == null) { if(p == null) {
p = vreq.getWebappDaoFactory().getDataPropertyDao().getDataPropertyByURI(predicateUri); p = vreq.getWebappDaoFactory().getDataPropertyDao().getDataPropertyByURI(predicateUri);
} }

View file

@ -4,14 +4,17 @@ package edu.cornell.mannlib.vitro.webapp.ontology.update;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntClass; import com.hp.hpl.jena.ontology.OntClass;
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.ontology.OntProperty; import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.rdf.model.Literal; 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;
@ -24,9 +27,10 @@ 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.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.AtomicChangeType; import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.AtomicChangeType;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
/** /**
* Performs knowledge base updates to the abox to align with a new ontology version * Performs knowledge base updates to the abox to align with a new ontology version
@ -34,10 +38,13 @@ import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.Ato
*/ */
public class ABoxUpdater { public class ABoxUpdater {
private final Log log = LogFactory.getLog(ABoxUpdater.class);
private OntModel oldTboxModel; private OntModel oldTboxModel;
private OntModel newTboxModel; private OntModel newTboxModel;
private OntModel aboxModel; private Dataset dataset;
private RDFService rdfService;
private OntModel newTBoxAnnotationsModel; private OntModel newTBoxAnnotationsModel;
private TBoxUpdater tboxUpdater;
private ChangeLogger logger; private ChangeLogger logger;
private ChangeRecord record; private ChangeRecord record;
private OntClass OWL_THING = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createClass(OWL.Thing.getURI()); private OntClass OWL_THING = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createClass(OWL.Thing.getURI());
@ -55,19 +62,19 @@ public class ABoxUpdater {
* and the retractions model. * and the retractions model.
* *
*/ */
public ABoxUpdater(OntModel oldTboxModel, public ABoxUpdater(UpdateSettings settings,
OntModel newTboxModel,
OntModel aboxModel,
OntModel newAnnotationsModel,
ChangeLogger logger, ChangeLogger logger,
ChangeRecord record) { ChangeRecord record) {
this.oldTboxModel = oldTboxModel; this.oldTboxModel = settings.getOldTBoxModel();
this.newTboxModel = newTboxModel; this.newTboxModel = settings.getNewTBoxModel();
this.aboxModel = aboxModel; RDFService rdfService = settings.getRDFService();
this.newTBoxAnnotationsModel = newAnnotationsModel; this.dataset = new RDFServiceDataset(rdfService);
this.rdfService = rdfService;
this.newTBoxAnnotationsModel = settings.getNewTBoxAnnotationsModel();
this.logger = logger; this.logger = logger;
this.record = record; this.record = record;
this.tboxUpdater = new TBoxUpdater(settings, logger, record);
} }
/** /**
@ -124,68 +131,75 @@ public class ABoxUpdater {
public void renameClass(AtomicOntologyChange change) throws IOException { public void renameClass(AtomicOntologyChange change) throws IOException {
//logger.log("Processing a class rename from: " + change.getSourceURI() + " to " + change.getDestinationURI()); //logger.log("Processing a class rename from: " + change.getSourceURI() + " to " + change.getDestinationURI());
aboxModel.enterCriticalSection(Lock.WRITE);
Iterator<String> graphIt = dataset.listNames();
try { while(graphIt.hasNext()) {
String graph = graphIt.next();
Model additions = ModelFactory.createDefaultModel(); if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
Model retractions = ModelFactory.createDefaultModel(); continue;
}
//TODO - look for these in the models and log error if not found Model aboxModel = dataset.getNamedModel(graph);
Resource oldClass = ResourceFactory.createResource(change.getSourceURI()); aboxModel.enterCriticalSection(Lock.WRITE);
Resource newClass = ResourceFactory.createResource(change.getDestinationURI()); try {
// Change class references in the subjects of statements Model additions = ModelFactory.createDefaultModel();
Model retractions = ModelFactory.createDefaultModel();
// BJL 2010-04-09 : In future versions we need to keep track of
// the difference between true direct renamings and "use-insteads." //TODO - look for these in the models and log error if not found
// For now, the best behavior is to remove any remaining statements Resource oldClass = ResourceFactory.createResource(change.getSourceURI());
// where the old class is the subject, *unless* the statements Resource newClass = ResourceFactory.createResource(change.getDestinationURI());
// is part of the new annotations file (see comment below) or the
// predicate is vitro:autolinkedToTab. In the latter case, // Change class references in the subjects of statements
// the autolinking annotation should be rewritten using the
// new class name. // BJL 2010-04-09 : In future versions we need to keep track of
// the difference between true direct renamings and "use-insteads."
StmtIterator iter = aboxModel.listStatements(oldClass, (Property) null, (RDFNode) null); // For now, the best behavior is to remove any remaining statements
// where the old class is the subject, *unless* the statements
int removeCount = 0; // is part of the new annotations file (see comment below) or the
while (iter.hasNext()) { // predicate is vitro:autolinkedToTab. In the latter case,
Statement oldStatement = iter.next(); // the autolinking annotation should be rewritten using the
removeCount++; // new class name.
retractions.add(oldStatement);
} StmtIterator iter = aboxModel.listStatements(oldClass, (Property) null, (RDFNode) null);
//log summary of changes int removeCount = 0;
if (removeCount > 0) { while (iter.hasNext()) {
logger.log("Removed " + removeCount + " subject reference" + ((removeCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class"); Statement oldStatement = iter.next();
} removeCount++;
retractions.add(oldStatement);
// Change class references in the objects of rdf:type statements }
iter = aboxModel.listStatements((Resource) null, RDF.type, oldClass);
//log summary of changes
int renameCount = 0; if (removeCount > 0) {
while (iter.hasNext()) { logger.log("Removed " + removeCount + " subject reference" + ((removeCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class");
renameCount++; }
Statement oldStatement = iter.next();
Statement newStatement = ResourceFactory.createStatement(oldStatement.getSubject(), RDF.type, newClass); // Change class references in the objects of rdf:type statements
retractions.add(oldStatement); iter = aboxModel.listStatements((Resource) null, RDF.type, oldClass);
additions.add(newStatement);
} int renameCount = 0;
while (iter.hasNext()) {
//log summary of changes renameCount++;
if (renameCount > 0) { Statement oldStatement = iter.next();
logger.log("Retyped " + renameCount + " individual" + ((renameCount > 1) ? "s" : "") + " from type " + oldClass.getURI() + " to type " + newClass.getURI()); Statement newStatement = ResourceFactory.createStatement(oldStatement.getSubject(), RDF.type, newClass);
} retractions.add(oldStatement);
additions.add(newStatement);
aboxModel.remove(retractions); }
record.recordRetractions(retractions);
aboxModel.add(additions); //log summary of changes
record.recordAdditions(additions); if (renameCount > 0) {
logger.log("Retyped " + renameCount + " individual" + ((renameCount > 1) ? "s" : "") + " from type " + oldClass.getURI() + " to type " + newClass.getURI());
} finally { }
aboxModel.leaveCriticalSection();
} aboxModel.remove(retractions);
record.recordRetractions(retractions);
aboxModel.add(additions);
record.recordAdditions(additions);
} finally {
aboxModel.leaveCriticalSection();
}
}
} }
/** /**
@ -231,24 +245,26 @@ public class ABoxUpdater {
if (!parentOfAddedClass.equals(OWL.Thing)) { if (!parentOfAddedClass.equals(OWL.Thing)) {
StmtIterator stmtIter = aboxModel.listStatements(null, RDF.type, parentOfAddedClass); Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
int count = stmtIter.toList().size(); String graph = graphIt.next();
if (count > 0) { if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
String indList = ""; }
while (stmtIter.hasNext()) { Model aboxModel = dataset.getNamedModel(graph);
Statement stmt = stmtIter.next();
indList += "\n\t" + stmt.getSubject().getURI(); StmtIterator stmtIter = aboxModel.listStatements(null, RDF.type, parentOfAddedClass);
}
int count = stmtIter.toList().size();
if (count > 0) { if (count > 0) {
//TODO - take out the detailed logging after our internal testing is completed. //TODO - take out the detailed logging after our internal testing is completed.
logger.log("There " + ((count > 1) ? "are" : "is") + " " + count + " individual" + ((count > 1) ? "s" : "") + " in the model that " + ((count > 1) ? "are" : "is") + " of type " + parentOfAddedClass.getURI() + "," + logger.log("There " + ((count > 1) ? "are" : "is") + " " + count + " individual" + ((count > 1) ? "s" : "") + " in the model that " + ((count > 1) ? "are" : "is") + " of type " + parentOfAddedClass.getURI() + "," +
" and a new subclass of that class has been added: " + addedClass.getURI() + ". " + " and a new subclass of that class has been added: " + addedClass.getURI() + ". " +
"Please review " + ((count > 1) ? "these" : "this") + " individual" + ((count > 1) ? "s" : "") + " to see whether " + ((count > 1) ? "they" : "it") + " should be of type: " + addedClass.getURI() ); "Please review " + ((count > 1) ? "these" : "this") + " individual" + ((count > 1) ? "s" : "") + " to see whether " + ((count > 1) ? "they" : "it") + " should be of type: " + addedClass.getURI() );
} }
}
}
} }
} }
} }
@ -330,25 +346,33 @@ public class ABoxUpdater {
} }
// Remove instances of the deleted class // Remove instances of the deleted class
aboxModel.enterCriticalSection(Lock.WRITE); Iterator<String> graphIt = dataset.listNames();
try { while(graphIt.hasNext()) {
int count = 0; String graph = graphIt.next();
int refCount = 0; if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
StmtIterator iter = aboxModel.listStatements((Resource) null, RDF.type, deletedClass); continue;
}
while (iter.hasNext()) { Model aboxModel = dataset.getNamedModel(graph);
count++; aboxModel.enterCriticalSection(Lock.WRITE);
Statement typeStmt = iter.next(); try {
refCount = deleteIndividual(typeStmt.getSubject()); int count = 0;
} int refCount = 0;
StmtIterator iter = aboxModel.listStatements((Resource) null, RDF.type, deletedClass);
if (count > 0) {
logger.log("Removed " + count + " individual" + (((count > 1) ? "s" : "") + " of type " + deletedClass.getURI()) + " (refs = " + refCount + ")"); while (iter.hasNext()) {
} count++;
Statement typeStmt = iter.next();
} finally { refCount = deleteIndividual(typeStmt.getSubject());
aboxModel.leaveCriticalSection(); }
}
if (count > 0) {
logger.log("Removed " + count + " individual" + (((count > 1) ? "s" : "") + " of type " + deletedClass.getURI()) + " (refs = " + refCount + ")");
}
} finally {
aboxModel.leaveCriticalSection();
}
}
} }
protected int deleteIndividual(Resource individual) throws IOException { protected int deleteIndividual(Resource individual) throws IOException {
@ -356,29 +380,37 @@ public class ABoxUpdater {
Model retractions = ModelFactory.createDefaultModel(); Model retractions = ModelFactory.createDefaultModel();
int refCount = 0; int refCount = 0;
aboxModel.enterCriticalSection(Lock.WRITE); Iterator<String> graphIt = dataset.listNames();
try { while(graphIt.hasNext()) {
StmtIterator iter = aboxModel.listStatements(individual, (Property) null, (RDFNode) null); String graph = graphIt.next();
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
while (iter.hasNext()) { continue;
Statement subjstmt = iter.next(); }
retractions.add(subjstmt); Model aboxModel = dataset.getNamedModel(graph);
} aboxModel.enterCriticalSection(Lock.WRITE);
try {
iter = aboxModel.listStatements((Resource) null, (Property) null, individual); StmtIterator iter = aboxModel.listStatements(individual, (Property) null, (RDFNode) null);
while (iter.hasNext()) { while (iter.hasNext()) {
Statement objstmt = iter.next(); Statement subjstmt = iter.next();
retractions.add(objstmt); retractions.add(subjstmt);
refCount++; }
}
iter = aboxModel.listStatements((Resource) null, (Property) null, individual);
aboxModel.remove(retractions);
record.recordRetractions(retractions); while (iter.hasNext()) {
Statement objstmt = iter.next();
} finally { retractions.add(objstmt);
aboxModel.leaveCriticalSection(); refCount++;
} }
aboxModel.remove(retractions);
record.recordRetractions(retractions);
} finally {
aboxModel.leaveCriticalSection();
}
}
return refCount; return refCount;
} }
@ -388,20 +420,33 @@ public class ABoxUpdater {
Iterator<AtomicOntologyChange> propItr = changes.iterator(); Iterator<AtomicOntologyChange> propItr = changes.iterator();
while(propItr.hasNext()){ while(propItr.hasNext()){
AtomicOntologyChange propChangeObj = propItr.next(); AtomicOntologyChange propChangeObj = propItr.next();
switch (propChangeObj.getAtomicChangeType()){ log.debug("processing " + propChangeObj);
case ADD: try {
addProperty(propChangeObj); if (propChangeObj.getAtomicChangeType() == null) {
break; log.error("Missing change type; skipping " + propChangeObj);
case DELETE: continue;
deleteProperty(propChangeObj); }
break; switch (propChangeObj.getAtomicChangeType()){
case RENAME: case ADD:
renameProperty(propChangeObj); log.debug("add");
break; addProperty(propChangeObj);
default: break;
logger.logError("unexpected change type indicator: " + propChangeObj.getAtomicChangeType()); case DELETE:
break; log.debug("delete");
} deleteProperty(propChangeObj);
break;
case RENAME:
log.debug("rename");
renameProperty(propChangeObj);
break;
default:
log.debug("unknown");
logger.logError("unexpected change type indicator: " + propChangeObj.getAtomicChangeType());
break;
}
} catch (Exception e) {
log.error(e,e);
}
} }
} }
@ -424,37 +469,45 @@ public class ABoxUpdater {
if (inverseOfAddedProperty != null) { if (inverseOfAddedProperty != null) {
Model additions = ModelFactory.createDefaultModel(); Model additions = ModelFactory.createDefaultModel();
aboxModel.enterCriticalSection(Lock.WRITE); Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
try { String graph = graphIt.next();
StmtIterator iter = aboxModel.listStatements((Resource) null, inverseOfAddedProperty, (RDFNode) null); if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
while (iter.hasNext()) { }
Model aboxModel = dataset.getNamedModel(graph);
Statement stmt = iter.next(); aboxModel.enterCriticalSection(Lock.WRITE);
if (stmt.getObject().isResource()) { try {
Statement newStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), addedProperty, stmt.getSubject()); StmtIterator iter = aboxModel.listStatements((Resource) null, inverseOfAddedProperty, (RDFNode) null);
additions.add(newStmt);
} else { while (iter.hasNext()) {
logger.log("WARNING: expected the object of this statement to be a Resource but it is not. No inverse has been asserted: " + stmtString(stmt));
} Statement stmt = iter.next();
}
if (stmt.getObject().isResource()) {
aboxModel.add(additions); Statement newStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), addedProperty, stmt.getSubject());
record.recordAdditions(additions); additions.add(newStmt);
} else {
if (additions.size() > 0) { logger.log("WARNING: expected the object of this statement to be a Resource but it is not. No inverse has been asserted: " + stmtString(stmt));
logger.log("Added " + additions.size() + " statement" + }
((additions.size() > 1) ? "s" : "") + }
" with predicate " + addedProperty.getURI() +
" (as an inverse to existing " + inverseOfAddedProperty.getURI() + aboxModel.add(additions);
" statement" + ((additions.size() > 1) ? "s" : "") + ")"); record.recordAdditions(additions);
}
if (additions.size() > 0) {
} finally { logger.log("Added " + additions.size() + " statement" +
aboxModel.leaveCriticalSection(); ((additions.size() > 1) ? "s" : "") +
} " with predicate " + addedProperty.getURI() +
" (as an inverse to existing " + inverseOfAddedProperty.getURI() +
" statement" + ((additions.size() > 1) ? "s" : "") + ")");
}
} finally {
aboxModel.leaveCriticalSection();
}
}
} }
} }
@ -492,33 +545,41 @@ public class ABoxUpdater {
} }
} }
Model deletePropModel = ModelFactory.createDefaultModel(); Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
if (replacementProperty == null) { String graph = graphIt.next();
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
aboxModel.enterCriticalSection(Lock.WRITE); continue;
try { }
deletePropModel.add(aboxModel.listStatements((Resource) null, deletedProperty, (RDFNode) null)); Model aboxModel = dataset.getNamedModel(graph);
aboxModel.remove(deletePropModel); Model deletePropModel = ModelFactory.createDefaultModel();
} finally {
aboxModel.leaveCriticalSection(); if (replacementProperty == null) {
}
record.recordRetractions(deletePropModel); aboxModel.enterCriticalSection(Lock.WRITE);
boolean plural = (deletePropModel.size() > 1); try {
if (deletePropModel.size() > 0) { deletePropModel.add(aboxModel.listStatements((Resource) null, deletedProperty, (RDFNode) null));
logger.log("Removed " + deletePropModel.size() + " statement" + (plural ? "s" : "") + " with predicate " + aboxModel.remove(deletePropModel);
propObj.getSourceURI()); } finally {
} aboxModel.leaveCriticalSection();
} else { }
AtomicOntologyChange chg = new AtomicOntologyChange(deletedProperty.getURI(), replacementProperty.getURI(), AtomicChangeType.RENAME, propObj.getNotes()); record.recordRetractions(deletePropModel);
renameProperty(chg); boolean plural = (deletePropModel.size() > 1);
} if (deletePropModel.size() > 0) {
logger.log("Removed " + deletePropModel.size() + " statement" + (plural ? "s" : "") + " with predicate " +
propObj.getSourceURI());
}
} else {
AtomicOntologyChange chg = new AtomicOntologyChange(deletedProperty.getURI(), replacementProperty.getURI(), AtomicChangeType.RENAME, propObj.getNotes());
renameProperty(chg);
}
}
} }
private void renameProperty(AtomicOntologyChange propObj) throws IOException { private void renameProperty(AtomicOntologyChange propObj) throws IOException {
//logger.log("Processing a property rename from: " + propObj.getSourceURI() + " to " + propObj.getDestinationURI()); logger.log("Processing a property rename from: " + propObj.getSourceURI() + " to " + propObj.getDestinationURI());
OntProperty oldProperty = oldTboxModel.getOntProperty(propObj.getSourceURI()); OntProperty oldProperty = oldTboxModel.getOntProperty(propObj.getSourceURI());
OntProperty newProperty = newTboxModel.getOntProperty(propObj.getDestinationURI()); OntProperty newProperty = newTboxModel.getOntProperty(propObj.getDestinationURI());
@ -533,35 +594,46 @@ public class ABoxUpdater {
return; return;
} }
Model renamePropAddModel = ModelFactory.createDefaultModel(); Iterator<String> graphIt = dataset.listNames();
Model renamePropRetractModel = ModelFactory.createDefaultModel(); while(graphIt.hasNext()) {
String graph = graphIt.next();
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
}
Model aboxModel = dataset.getNamedModel(graph);
aboxModel.enterCriticalSection(Lock.WRITE); Model renamePropAddModel = ModelFactory.createDefaultModel();
try { Model renamePropRetractModel = ModelFactory.createDefaultModel();
renamePropRetractModel.add( aboxModel.listStatements(
(Resource) null, oldProperty, (RDFNode) null)); aboxModel.enterCriticalSection(Lock.WRITE);
StmtIterator stmItr = renamePropRetractModel.listStatements(); try {
while(stmItr.hasNext()) { renamePropRetractModel.add( aboxModel.listStatements(
Statement tempStatement = stmItr.nextStatement(); (Resource) null, oldProperty, (RDFNode) null));
renamePropAddModel.add( tempStatement.getSubject(), StmtIterator stmItr = renamePropRetractModel.listStatements();
newProperty, while(stmItr.hasNext()) {
tempStatement.getObject() ); Statement tempStatement = stmItr.nextStatement();
} renamePropAddModel.add( tempStatement.getSubject(),
aboxModel.remove(renamePropRetractModel); newProperty,
aboxModel.add(renamePropAddModel); tempStatement.getObject() );
} finally { }
aboxModel.leaveCriticalSection(); aboxModel.remove(renamePropRetractModel);
} aboxModel.add(renamePropAddModel);
} finally {
record.recordAdditions(renamePropAddModel); aboxModel.leaveCriticalSection();
record.recordRetractions(renamePropRetractModel); }
if (renamePropRetractModel.size() > 0) { record.recordAdditions(renamePropAddModel);
logger.log("Changed " + renamePropRetractModel.size() + " statement" + record.recordRetractions(renamePropRetractModel);
((renamePropRetractModel.size() > 1) ? "s" : "") +
" with predicate " + propObj.getSourceURI() + " to use " + if (renamePropRetractModel.size() > 0) {
propObj.getDestinationURI() + " instead"); logger.log("Changed " + renamePropRetractModel.size() + " statement" +
} ((renamePropRetractModel.size() > 1) ? "s" : "") +
" with predicate " + propObj.getSourceURI() + " to use " +
propObj.getDestinationURI() + " instead");
}
}
tboxUpdater.renameProperty(propObj);
} }
public void logChanges(Statement oldStatement, Statement newStatement) throws IOException { public void logChanges(Statement oldStatement, Statement newStatement) throws IOException {

View file

@ -30,6 +30,11 @@ public class AtomicOntologyChange {
this.notes = notes; this.notes = notes;
} }
@Override
public String toString() {
return "Source: " + sourceURI + "; Destination: " + destinationURI +
"; Type: " + atomicChangeType + "; Notes:" + notes;
}
/** /**
* Contains the URI of a class or property in the previous version of * Contains the URI of a class or property in the previous version of

View file

@ -12,4 +12,6 @@ public interface ChangeRecord {
public void writeChanges(); public void writeChanges();
public boolean hasRecordedChanges();
} }

View file

@ -11,6 +11,8 @@ import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -22,19 +24,16 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; 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.query.Query; import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Statement; 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 edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
@ -58,14 +57,13 @@ public class KnowledgeBaseUpdater {
this.record = new SimpleChangeRecord(settings.getAddedDataFile(), settings.getRemovedDataFile()); this.record = new SimpleChangeRecord(settings.getAddedDataFile(), settings.getRemovedDataFile());
} }
public void update(ServletContext servletContext) throws IOException { public boolean update(ServletContext servletContext) throws IOException {
if (this.logger == null) { if (this.logger == null) {
this.logger = new SimpleChangeLogger(settings.getLogFile(), settings.getErrorLogFile()); this.logger = new SimpleChangeLogger(settings.getLogFile(), settings.getErrorLogFile());
} }
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
System.out.println("Migrating the knowledge base");
log.info("Migrating the knowledge base"); log.info("Migrating the knowledge base");
logger.log("Started knowledge base migration"); logger.log("Started knowledge base migration");
@ -73,7 +71,7 @@ public class KnowledgeBaseUpdater {
performUpdate(servletContext); performUpdate(servletContext);
} catch (Exception e) { } catch (Exception e) {
logger.logError(e.getMessage()); logger.logError(e.getMessage());
e.printStackTrace(); log.error(e,e);
} }
if (!logger.errorsWritten()) { if (!logger.errorsWritten()) {
@ -85,10 +83,9 @@ public class KnowledgeBaseUpdater {
logger.closeLogs(); logger.closeLogs();
long elapsedSecs = (System.currentTimeMillis() - startTime)/1000; long elapsedSecs = (System.currentTimeMillis() - startTime)/1000;
System.out.println("Finished knowledge base migration in " + elapsedSecs + " second" + (elapsedSecs != 1 ? "s" : ""));
log.info("Finished knowledge base migration in " + elapsedSecs + " second" + (elapsedSecs != 1 ? "s" : "")); log.info("Finished knowledge base migration in " + elapsedSecs + " second" + (elapsedSecs != 1 ? "s" : ""));
return; return record.hasRecordedChanges();
} }
private void performUpdate(ServletContext servletContext) throws Exception { private void performUpdate(ServletContext servletContext) throws Exception {
@ -98,136 +95,153 @@ public class KnowledgeBaseUpdater {
AtomicOntologyChangeLists changes = new AtomicOntologyChangeLists(rawChanges,settings.getNewTBoxModel(),settings.getOldTBoxModel()); AtomicOntologyChangeLists changes = new AtomicOntologyChangeLists(rawChanges,settings.getNewTBoxModel(),settings.getOldTBoxModel());
//process the TBox before the ABox //process the TBox before the ABox
log.info("\tupdating tbox annotations"); try {
updateTBoxAnnotations(); log.debug("\tupdating tbox annotations");
updateTBoxAnnotations();
} catch (Exception e) {
log.error(e,e);
}
try { try {
migrateMigrationMetadata(servletContext); migrateMigrationMetadata(servletContext);
logger.log("Migrated migration metadata"); logger.log("Migrated migration metadata");
} catch (Exception e) { } catch (Exception e) {
log.debug("unable to migrate migration metadata " + e.getMessage()); log.error("unable to migrate migration metadata " + e.getMessage());
} }
log.info("\tupdating the abox"); log.info("performing SPARQL CONSTRUCT additions");
updateABox(changes); performSparqlConstructs(settings.getSparqlConstructAdditionsDir(), settings.getRDFService(), ADD);
}
log.info("performing SPARQL CONSTRUCT retractions");
private void performSparqlConstructAdditions(String sparqlConstructDir, OntModel readModel, OntModel writeModel) throws IOException { performSparqlConstructs(settings.getSparqlConstructDeletionsDir(), settings.getRDFService(), RETRACT);
Model anonModel = performSparqlConstructs(sparqlConstructDir, readModel, true); log.info("\tupdating the abox");
updateABox(changes);
if (anonModel == null) {
return; log.info("performing post-processing SPARQL CONSTRUCT additions");
} performSparqlConstructs(settings.getSparqlConstructAdditionsDir() + "/post/",
settings.getRDFService(), ADD);
writeModel.enterCriticalSection(Lock.WRITE);
try { log.info("performing post-processing SPARQL CONSTRUCT retractions");
JenaIngestUtils jiu = new JenaIngestUtils(); performSparqlConstructs(settings.getSparqlConstructDeletionsDir() + "/post/",
Model additions = jiu.renameBNodes(anonModel, settings.getDefaultNamespace() + "n", writeModel); settings.getRDFService(), RETRACT);
Model actualAdditions = ModelFactory.createDefaultModel();
StmtIterator stmtIt = additions.listStatements();
while (stmtIt.hasNext()) {
Statement stmt = stmtIt.nextStatement();
if (!writeModel.contains(stmt)) {
actualAdditions.add(stmt);
}
}
writeModel.add(actualAdditions);
record.recordAdditions(actualAdditions);
} finally {
writeModel.leaveCriticalSection();
}
} }
private void performSparqlConstructRetractions(String sparqlConstructDir, OntModel readModel, OntModel writeModel) throws IOException { private static final boolean ADD = true;
private static final boolean RETRACT = !ADD;
Model retractions = performSparqlConstructs(sparqlConstructDir, readModel, false);
if (retractions == null) {
return;
}
writeModel.enterCriticalSection(Lock.WRITE);
try {
writeModel.remove(retractions);
record.recordRetractions(retractions);
} finally {
writeModel.leaveCriticalSection();
}
}
/** /**
* Performs a set of arbitrary SPARQL CONSTRUCT queries on the * Performs a set of arbitrary SPARQL CONSTRUCT queries on the
* data, for changes that cannot be expressed as simple property * data, for changes that cannot be expressed as simple property
* or class additions, deletions, or renamings. * or class additions, deletions, or renamings.
* Blank nodes created by the queries are given random URIs. * Blank nodes created by the queries are given random URIs.
* @param sparqlConstructDir * @param sparqlConstructDir
* @param aboxModel * @param readModel
*/ * @param writeModel
private Model performSparqlConstructs(String sparqlConstructDir, * @param add (add = true; retract = false)
OntModel readModel, */
boolean add) throws IOException { private void performSparqlConstructs(String sparqlConstructDir,
RDFService rdfService,
Model anonModel = ModelFactory.createDefaultModel(); boolean add) throws IOException {
File sparqlConstructDirectory = new File(sparqlConstructDir); Dataset dataset = new RDFServiceDataset(rdfService);
File sparqlConstructDirectory = new File(sparqlConstructDir);
if (!sparqlConstructDirectory.isDirectory()) { log.info("Using SPARQL CONSTRUCT directory " + sparqlConstructDirectory);
logger.logError(this.getClass().getName() + if (!sparqlConstructDirectory.isDirectory()) {
"performSparqlConstructs() expected to find a directory " + String logMsg = this.getClass().getName() +
" at " + sparqlConstructDir + ". Unable to execute " + "performSparqlConstructs() expected to find a directory " +
" SPARQL CONSTRUCTS."); " at " + sparqlConstructDir + ". Unable to execute " +
return null; " SPARQL CONSTRUCTS.";
} logger.logError(logMsg);
log.error(logMsg);
File[] sparqlFiles = sparqlConstructDirectory.listFiles(); return;
for (int i = 0; i < sparqlFiles.length; i ++) { }
File sparqlFile = sparqlFiles[i]; List<File> sparqlFiles = Arrays.asList(sparqlConstructDirectory.listFiles());
try { Collections.sort(sparqlFiles); // queries may depend on being run in a certain order
BufferedReader reader = new BufferedReader(new FileReader(sparqlFile)); JenaIngestUtils jiu = new JenaIngestUtils();
StringBuffer fileContents = new StringBuffer(); for (File sparqlFile : sparqlFiles) {
String ln; if(sparqlFile.isDirectory()) {
continue;
while ( (ln = reader.readLine()) != null) { }
fileContents.append(ln).append('\n'); StringBuffer fileContents = new StringBuffer();
} try {
BufferedReader reader = new BufferedReader(new FileReader(sparqlFile));
try { String ln;
log.debug("\t\tprocessing SPARQL construct query from file " + sparqlFiles[i].getName()); while ( (ln = reader.readLine()) != null) {
Query q = QueryFactory.create(fileContents.toString(), Syntax.syntaxARQ); fileContents.append(ln).append('\n');
readModel.enterCriticalSection(Lock.READ); }
try { } catch (FileNotFoundException fnfe) {
QueryExecution qe = QueryExecutionFactory.create(q, readModel); String logMsg = "WARNING: performSparqlConstructs() could not find " +
long numBefore = anonModel.size(); " SPARQL CONSTRUCT file " + sparqlFile + ". Skipping.";
qe.execConstruct(anonModel); logger.log(logMsg);
long numAfter = anonModel.size(); log.info(logMsg);
long num = numAfter - numBefore; continue;
}
if (num > 0) { Model anonModel = ModelFactory.createDefaultModel();
logger.log((add ? "Added " : "Removed ") + num + try {
" statement" + ((num > 1) ? "s" : "") + log.info("\t\tprocessing SPARQL construct query from file " + sparqlFile.getName());
" using the SPARQL construct query from file " + sparqlFiles[i].getParentFile().getName() + "/" + sparqlFiles[i].getName());
anonModel = RDFServiceUtils.parseModel(
rdfService.sparqlConstructQuery(fileContents.toString(),
RDFService.ModelSerializationFormat.NTRIPLE),
ModelSerializationFormat.NTRIPLE);
long num = anonModel.size();
if (num > 0) {
String logMsg = (add ? "Added " : "Removed ") + num +
" statement" + ((num > 1) ? "s" : "") +
" using the SPARQL construct query from file " +
sparqlFile.getParentFile().getName() +
"/" + sparqlFile.getName();
logger.log(logMsg);
log.info(logMsg);
}
} catch (Exception e) {
logger.logError(this.getClass().getName() +
".performSparqlConstructs() unable to execute " +
"query at " + sparqlFile + ". Error message is: " + e.getMessage());
log.error(e,e);
}
if(!add) {
StmtIterator sit = anonModel.listStatements();
while (sit.hasNext()) {
Statement stmt = sit.nextStatement();
Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
String graph = graphIt.next();
if(!isUpdatableABoxGraph(graph)) {
continue;
} }
qe.close(); Model writeModel = dataset.getNamedModel(graph);
} finally { if (writeModel.contains(stmt)) {
readModel.leaveCriticalSection(); writeModel.remove(stmt);
} }
} catch (Exception e) { }
logger.logError(this.getClass().getName() + }
".performSparqlConstructs() unable to execute " + record.recordRetractions(anonModel);
"query at " + sparqlFile + ". Error message is: " + e.getMessage()); //log.info("removed " + anonModel.size() + " statements from SPARQL CONSTRUCTs");
} } else {
} catch (FileNotFoundException fnfe) { Model writeModel = dataset.getNamedModel(JenaDataSourceSetupBase.JENA_DB_MODEL);
logger.log("WARNING: performSparqlConstructs() could not find " + Model additions = jiu.renameBNodes(
" SPARQL CONSTRUCT file " + sparqlFile + ". Skipping."); anonModel, settings.getDefaultNamespace() + "n", writeModel);
} Model actualAdditions = ModelFactory.createDefaultModel();
} StmtIterator stmtIt = additions.listStatements();
while (stmtIt.hasNext()) {
return anonModel; Statement stmt = stmtIt.nextStatement();
} if (!writeModel.contains(stmt)) {
actualAdditions.add(stmt);
}
}
writeModel.add(actualAdditions);
//log.info("added " + actualAdditions.size() + " statements from SPARQL CONSTRUCTs");
record.recordAdditions(actualAdditions);
}
}
}
private List<AtomicOntologyChange> getAtomicOntologyChanges() private List<AtomicOntologyChange> getAtomicOntologyChanges()
@ -240,10 +254,8 @@ public class KnowledgeBaseUpdater {
private void updateABox(AtomicOntologyChangeLists changes) private void updateABox(AtomicOntologyChangeLists changes)
throws IOException { throws IOException {
OntModel oldTBoxModel = settings.getOldTBoxModel();
OntModel newTBoxModel = settings.getNewTBoxModel(); ABoxUpdater aboxUpdater = new ABoxUpdater(settings, logger, record);
OntModel ABoxModel = settings.getAssertionOntModelSelector().getABoxModel();
ABoxUpdater aboxUpdater = new ABoxUpdater(oldTBoxModel, newTBoxModel, ABoxModel,settings.getNewTBoxAnnotationsModel(), logger, record);
aboxUpdater.processPropertyChanges(changes.getAtomicPropertyChanges()); aboxUpdater.processPropertyChanges(changes.getAtomicPropertyChanges());
aboxUpdater.processClassChanges(changes.getAtomicClassChanges()); aboxUpdater.processClassChanges(changes.getAtomicClassChanges());
} }
@ -281,14 +293,18 @@ public class KnowledgeBaseUpdater {
rdfService.changeSetUpdate(removeChangeSet); rdfService.changeSetUpdate(removeChangeSet);
} }
private void updateTBoxAnnotations() throws IOException { private void updateTBoxAnnotations() {
TBoxUpdater tboxUpdater = new TBoxUpdater(settings, logger, record);
TBoxUpdater tboxUpdater = new TBoxUpdater(settings.getOldTBoxAnnotationsModel(), try {
settings.getNewTBoxAnnotationsModel(), tboxUpdater.modifyPropertyQualifications();
settings.getAssertionOntModelSelector().getTBoxModel(), logger, record); } catch (Exception e) {
log.error("Unable to modify qualified property config file ", e);
tboxUpdater.updateDefaultAnnotationValues(); }
//tboxUpdater.updateAnnotationModel(); try {
tboxUpdater.updateDefaultAnnotationValues();
} catch (Exception e) {
log.error("Unable to update default annotation values ", e);
}
} }
/** /**
@ -296,7 +312,7 @@ public class KnowledgeBaseUpdater {
* needs to be updated to conform to a new ontology version * needs to be updated to conform to a new ontology version
*/ */
public boolean updateRequired(ServletContext servletContext) throws IOException { public boolean updateRequired(ServletContext servletContext) throws IOException {
boolean required = false; boolean required = true;
String sparqlQueryStr = loadSparqlQuery(settings.getAskUpdatedQueryFile()); String sparqlQueryStr = loadSparqlQuery(settings.getAskUpdatedQueryFile());
if (sparqlQueryStr == null) { if (sparqlQueryStr == null) {
@ -338,7 +354,7 @@ public class KnowledgeBaseUpdater {
File file = new File(filePath); File file = new File(filePath);
if (!file.exists()) { if (!file.exists()) {
return null; throw new RuntimeException("SPARQL file not found at " + filePath);
} }
BufferedReader reader = new BufferedReader(new FileReader(file)); BufferedReader reader = new BufferedReader(new FileReader(file));
StringBuffer fileContents = new StringBuffer(); StringBuffer fileContents = new StringBuffer();
@ -363,8 +379,10 @@ public class KnowledgeBaseUpdater {
" update to new ontology version: ", e); " update to new ontology version: ", e);
} }
} }
public static boolean isUpdatableABoxGraph(String graphName) {
return (!graphName.contains("tbox") && !graphName.contains("filegraph"));
}
/** /**
* A class that allows to access two different ontology change lists, * A class that allows to access two different ontology change lists,
@ -390,11 +408,13 @@ public class KnowledgeBaseUpdater {
while(listItr.hasNext()) { while(listItr.hasNext()) {
AtomicOntologyChange changeObj = listItr.next(); AtomicOntologyChange changeObj = listItr.next();
if (changeObj.getSourceURI() != null){ if (changeObj.getSourceURI() != null){
log.debug("triaging " + changeObj);
if (oldTboxModel.getOntProperty(changeObj.getSourceURI()) != null){ if (oldTboxModel.getOntProperty(changeObj.getSourceURI()) != null){
atomicPropertyChanges.add(changeObj); atomicPropertyChanges.add(changeObj);
log.debug("added to property changes");
} else if (oldTboxModel.getOntClass(changeObj.getSourceURI()) != null) { } else if (oldTboxModel.getOntClass(changeObj.getSourceURI()) != null) {
atomicClassChanges.add(changeObj); atomicClassChanges.add(changeObj);
log.debug("added to class changes");
} else if ("Prop".equals(changeObj.getNotes())) { } else if ("Prop".equals(changeObj.getNotes())) {
atomicPropertyChanges.add(changeObj); atomicPropertyChanges.add(changeObj);
} else if ("Class".equals(changeObj.getNotes())) { } else if ("Class".equals(changeObj.getNotes())) {
@ -429,5 +449,6 @@ public class KnowledgeBaseUpdater {
public List<AtomicOntologyChange> getAtomicPropertyChanges() { public List<AtomicOntologyChange> getAtomicPropertyChanges() {
return atomicPropertyChanges; return atomicPropertyChanges;
} }
} }
} }

View file

@ -9,6 +9,8 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.skife.csv.CSVReader; import org.skife.csv.CSVReader;
import org.skife.csv.SimpleReader; import org.skife.csv.SimpleReader;
@ -23,6 +25,8 @@ import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.Ato
public class OntologyChangeParser { public class OntologyChangeParser {
private final Log log = LogFactory.getLog(OntologyChangeParser.class);
private ChangeLogger logger; private ChangeLogger logger;
public OntologyChangeParser(ChangeLogger logger) { public OntologyChangeParser(ChangeLogger logger) {
@ -85,6 +89,8 @@ public class OntologyChangeParser {
} }
log.debug(changeObj);
changeObjects.add(changeObj); changeObjects.add(changeObj);
} }

View file

@ -26,6 +26,9 @@ public class SimpleChangeRecord implements ChangeRecord {
private File additionsFile; private File additionsFile;
private File retractionsFile; private File retractionsFile;
private int additionsCount = 0;
private int retractionsCount = 0;
public SimpleChangeRecord( public SimpleChangeRecord(
String additionsFile, String retractionsFile) { String additionsFile, String retractionsFile) {
this.additionsFile = new File(additionsFile); this.additionsFile = new File(additionsFile);
@ -46,11 +49,12 @@ public class SimpleChangeRecord implements ChangeRecord {
public void recordAdditions(Model incrementalAdditions) { public void recordAdditions(Model incrementalAdditions) {
additionsModel.add(incrementalAdditions); additionsModel.add(incrementalAdditions);
additionsCount += incrementalAdditions.size();
} }
public void recordRetractions(Model incrementalRetractions) { public void recordRetractions(Model incrementalRetractions) {
retractionsModel.add(incrementalRetractions); retractionsModel.add(incrementalRetractions);
retractionsCount += incrementalRetractions.size();
} }
private void write(Model model, File file) { private void write(Model model, File file) {
@ -71,5 +75,9 @@ public class SimpleChangeRecord implements ChangeRecord {
write(retractionsModel, retractionsFile); write(retractionsModel, retractionsFile);
} }
} }
public boolean hasRecordedChanges() {
return additionsCount > 0 || retractionsCount > 0;
}
} }

View file

@ -2,11 +2,22 @@
package edu.cornell.mannlib.vitro.webapp.ontology.update; package edu.cornell.mannlib.vitro.webapp.ontology.update;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
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 com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.rdf.model.Literal; 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;
@ -14,6 +25,7 @@ import com.hp.hpl.jena.rdf.model.NodeIterator;
import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource; 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.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;
@ -21,398 +33,542 @@ import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS; import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
/** /**
* Performs knowledge base updates to the tbox to align with a new ontology version * Performs knowledge base updates to the tbox to align with a new ontology version
* *
*/ */
public class TBoxUpdater { public class TBoxUpdater {
private OntModel oldTboxAnnotationsModel; private static final Log log = LogFactory.getLog(TBoxUpdater.class);
private OntModel newTboxAnnotationsModel;
private OntModel siteModel;
private ChangeLogger logger;
private ChangeRecord record;
private boolean detailLogs = false;
private static final String classGroupURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#ClassGroup";
private Resource classGroupClass = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource(classGroupURI);
private static final String inClassGroupURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#inClassGroup";
private Property inClassGroupProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty(inClassGroupURI);
/** private UpdateSettings settings;
* private OntModel oldTboxAnnotationsModel;
* Constructor private OntModel newTboxAnnotationsModel;
* private OntModel siteModel;
* @param oldTboxAnnotationsModel - previous version of the annotations in the ontology private ChangeLogger logger;
* @param newTboxAnnotationsModel - new version of the annotations in the ontology private ChangeRecord record;
* @param siteModel - the knowledge base to be updated private boolean detailLogs = false;
* @param logger - for writing to the change log
* and the error log. private static final String classGroupURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#ClassGroup";
* @param record - for writing to the additions model private Resource classGroupClass = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource(classGroupURI);
* and the retractions model. private static final String inClassGroupURI = "http://vitro.mannlib.cornell.edu/ns/vitro/0.7#inClassGroup";
* private Property inClassGroupProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty(inClassGroupURI);
*/
public TBoxUpdater(OntModel oldTboxAnnotationsModel, /**
OntModel newTboxAnnotationsModel, *
OntModel siteModel, * Constructor
ChangeLogger logger, *
ChangeRecord record) { * @param oldTboxAnnotationsModel - previous version of the annotations in the ontology
* @param newTboxAnnotationsModel - new version of the annotations in the ontology
this.oldTboxAnnotationsModel = oldTboxAnnotationsModel; * @param siteModel - the knowledge base to be updated
this.newTboxAnnotationsModel = newTboxAnnotationsModel; * @param logger - for writing to the change log
this.siteModel = siteModel; * and the error log.
this.logger = logger; * @param record - for writing to the additions model
this.record = record; * and the retractions model.
} *
*/
/** public TBoxUpdater(UpdateSettings settings,
* ChangeLogger logger,
* Update a knowledge base to align with changes to vitro annotation property default ChangeRecord record) {
* values in a new version of the ontology. The two versions of the ontology and the this.settings = settings;
* knowledge base to be updated are provided in the class constructor and are this.oldTboxAnnotationsModel = settings.getOldTBoxAnnotationsModel();
* referenced via class level variables. this.newTboxAnnotationsModel = settings.getNewTBoxAnnotationsModel();
* this.siteModel = settings.getAssertionOntModelSelector().getTBoxModel();
* If the default value (i.e. the value that is provided in the vivo-core this.logger = logger;
* annotations files) of a vitro annotation property has been changed for a vivo this.record = record;
* core class, and that default value has not been changed in the site knowledge }
* base, then update the value in the site knowledge base to be the new default.
* Also, if a new vitro annotation property setting (i.e. either an existing /**
* setting applied to an existing class where it wasn't applied before, or * Update application ontology data for domain and range-qualified properties
* an existing setting applied to a new class) has been applied to a vivo * to use any applicable settings from obsolete subproperties
* core class then copy that new property statement into the site model. */
* If a property setting for a class exists in the old ontology but public void modifyPropertyQualifications() throws IOException {
* not in the new one, then that statement will be removed from the
* site knowledge base. }
*
* Writes to the change log file, the error log file, and the incremental change private Model mergeConfigurations(Model oldConfig, Model newConfig) {
* knowledge base. return null;
* }
* Note: as specified, this method for now assumes that no new vitro annotation
* properties have been introduced. This should be updated for future versions. public void updateDefaultAnnotationValues() throws IOException {
*/ updateDefaultAnnotationValues(null);
public void updateDefaultAnnotationValues() throws IOException { }
siteModel.enterCriticalSection(Lock.WRITE); /**
*
try { * Update a knowledge base to align with changes to vitro annotation property default
* values in a new version of the ontology. The two versions of the ontology and the
Model additions = ModelFactory.createDefaultModel(); * knowledge base to be updated are provided in the class constructor and are
Model retractions = ModelFactory.createDefaultModel(); * referenced via class level variables.
*
// Update defaults values for vitro annotation properties in the site model * If the default value (i.e. the value that is provided in the vivo-core
// if the default has changed in the new version of the ontology AND if * annotations files) of a vitro annotation property has been changed for a vivo
// the site hasn't overidden the previous default in their knowledge base. * core class, and that default value has not been changed in the site knowledge
* base, then update the value in the site knowledge base to be the new default.
StmtIterator iter = oldTboxAnnotationsModel.listStatements(); * Also, if a new vitro annotation property setting (i.e. either an existing
* setting applied to an existing class where it wasn't applied before, or
while (iter.hasNext()) { * an existing setting applied to a new class) has been applied to a vivo
* core class then copy that new property statement into the site model.
Statement stmt = iter.next(); * If a property setting for a class exists in the old ontology but
Resource subject = stmt.getSubject(); * not in the new one, then that statement will be removed from the
Property predicate = stmt.getPredicate(); * site knowledge base.
RDFNode oldObject = stmt.getObject(); *
* Writes to the change log file, the error log file, and the incremental change
if (! ( (RDFS.getURI().equals(predicate.getNameSpace())) || * knowledge base.
(VitroVocabulary.vitroURI.equals(predicate.getNameSpace())) *
) ) { * Note: as specified, this method for now assumes that no new vitro annotation
// this annotation updater is only concerned with properties * properties have been introduced. This should be updated for future versions.
// such as rdfs:comment and properties in the vitro application */
// namespace public void updateDefaultAnnotationValues(String subjectURI) throws IOException {
continue;
} siteModel.enterCriticalSection(Lock.WRITE);
NodeIterator newObjects = newTboxAnnotationsModel.listObjectsOfProperty(subject, predicate); try {
if ((newObjects == null) || (!newObjects.hasNext()) ) { Model additions = ModelFactory.createDefaultModel();
// first check to see if the site has a local value change Model retractions = ModelFactory.createDefaultModel();
// that should override the deletion
List<RDFNode> siteObjects = siteModel.listObjectsOfProperty(subject, predicate).toList(); // Update defaults values for vitro annotation properties in the site model
// if the default has changed in the new version of the ontology AND if
if (siteObjects.size() > 1) { // the site hasn't overidden the previous default in their knowledge base.
/*
if(oldTboxAnnotationsModel == null) {
logger.log("oldTboxAnnotationModel is null; aborting update of annotation values");
return;
}
Resource subj = (subjectURI == null) ? null : ResourceFactory.createResource(subjectURI);
StmtIterator iter = oldTboxAnnotationsModel.listStatements(subj, null, (RDFNode) null);
while (iter.hasNext()) {
Statement stmt = iter.next();
Resource subject = stmt.getSubject();
Property predicate = stmt.getPredicate();
RDFNode oldObject = stmt.getObject();
if (! ( (RDFS.getURI().equals(predicate.getNameSpace())) ||
(VitroVocabulary.vitroURI.equals(predicate.getNameSpace()))
) ) {
// this annotation updater is only concerned with properties
// such as rdfs:comment and properties in the vitro application
// namespace
continue;
}
NodeIterator newObjects = newTboxAnnotationsModel.listObjectsOfProperty(subject, predicate);
if ((newObjects == null) || (!newObjects.hasNext()) ) {
// first check to see if the site has a local value change
// that should override the deletion
List<RDFNode> siteObjects = siteModel.listObjectsOfProperty(subject, predicate).toList();
if (siteObjects.size() > 1) {
/*
logger.log("WARNING: found " + siteObjects.size() + logger.log("WARNING: found " + siteObjects.size() +
" statements with subject = " + subject.getURI() + " statements with subject = " + subject.getURI() +
" and property = " + predicate.getURI() + " and property = " + predicate.getURI() +
" in the site database (maximum of one is expected)"); " in the site database (maximum of one is expected)");
*/ */
} }
if (siteObjects.size() > 0) { if (siteObjects.size() > 0) {
RDFNode siteNode = siteObjects.get(0); RDFNode siteNode = siteObjects.get(0);
if (siteNode.equals(oldObject)) { if (siteNode.equals(oldObject)) {
retractions.add(siteModel.listStatements(subject, predicate, (RDFNode) null)); retractions.add(siteModel.listStatements(subject, predicate, (RDFNode) null));
} }
} }
continue; continue;
} }
RDFNode newObject = newObjects.next(); RDFNode newObject = newObjects.next();
int i = 1; int i = 1;
while (newObjects.hasNext()) { while (newObjects.hasNext()) {
i++; i++;
newObjects.next(); newObjects.next();
} }
if (i > 1) { if (i > 1) {
/* /*
logger.log("WARNING: found " + i + logger.log("WARNING: found " + i +
" statements with subject = " + subject.getURI() + " statements with subject = " + subject.getURI() +
" and property = " + predicate.getURI() + " and property = " + predicate.getURI() +
" in the new version of the annotations ontology (maximum of one is expected)"); " in the new version of the annotations ontology (maximum of one is expected)");
*/ */
continue; continue;
} }
// If a subject-property pair occurs in the old annotation TBox and the new annotations
// TBox, but not in the site model, then it is considered an erroneous deletion and
// the value from the new TBox is added into the site model.
// sjm: 7-16-2010. We want this here now to add back in annotations mistakenly dropped
// in the .9 to 1.0 migration, but I'm not sure we would want this here permanently.
// Shouldn't a site be allowed to delete annotations if they want to?
NodeIterator siteObjects = siteModel.listObjectsOfProperty(subject,predicate);
if (siteObjects == null || !siteObjects.hasNext()) {
try {
additions.add(subject, predicate, newObject);
if (detailLogs) {
logger.log( "adding Statement: subject = " + subject.getURI() +
" property = " + predicate.getURI() +
" object = " + (newObject.isLiteral() ? ((Literal)newObject).getLexicalForm()
: ((Resource)newObject).getURI()));
}
} catch (Exception e) {
logger.logError("Error trying to add statement with property " + predicate.getURI() +
" of class = " + subject.getURI() + " in the knowledge base:\n" + e.getMessage());
}
continue;
}
if (!newObject.equals(oldObject)) {
RDFNode siteObject = siteObjects.next(); // If a subject-property pair occurs in the old annotation TBox and the new annotations
// TBox, but not in the site model, then it is considered an erroneous deletion and
// the value from the new TBox is added into the site model.
// sjm: 7-16-2010. We want this here now to add back in annotations mistakenly dropped
// in the .9 to 1.0 migration, but I'm not sure we would want this here permanently.
// Shouldn't a site be allowed to delete annotations if they want to?
i = 1; NodeIterator siteObjects = siteModel.listObjectsOfProperty(subject,predicate);
while (siteObjects.hasNext()) {
i++;
siteObjects.next();
}
if (i > 1) { if (siteObjects == null || !siteObjects.hasNext()) {
/* try {
additions.add(subject, predicate, newObject);
if (detailLogs) {
logger.log( "adding Statement: subject = " + subject.getURI() +
" property = " + predicate.getURI() +
" object = " + (newObject.isLiteral() ? ((Literal)newObject).getLexicalForm()
: ((Resource)newObject).getURI()));
}
} catch (Exception e) {
logger.logError("Error trying to add statement with property " + predicate.getURI() +
" of class = " + subject.getURI() + " in the knowledge base:\n" + e.getMessage());
}
continue;
}
if (!newObject.equals(oldObject)) {
RDFNode siteObject = siteObjects.next();
i = 1;
while (siteObjects.hasNext()) {
i++;
siteObjects.next();
}
if (i > 1) {
/*
logger.log("WARNING: found " + i + logger.log("WARNING: found " + i +
" statements with subject = " + subject.getURI() + " statements with subject = " + subject.getURI() +
" and property = " + predicate.getURI() + " and property = " + predicate.getURI() +
" in the site annotations model (maximum of one is expected) "); " in the site annotations model (maximum of one is expected) ");
*/ */
continue; continue;
} }
if (siteObject.equals(oldObject)) {
try {
StmtIterator it = siteModel.listStatements(subject, predicate, (RDFNode)null);
while (it.hasNext()) {
retractions.add(it.next());
}
} catch (Exception e) {
logger.logError("Error removing statement for subject = " + subject.getURI() +
"and property = " + predicate.getURI() +
"from the knowledge base:\n" + e.getMessage());
}
try { if (siteObject.equals(oldObject)) {
additions.add(subject, predicate, newObject); try {
StmtIterator it = siteModel.listStatements(subject, predicate, (RDFNode)null);
if (detailLogs) { while (it.hasNext()) {
logger.log("Changed the value of property " + predicate.getURI() + retractions.add(it.next());
" of subject = " + subject.getURI() + }
" from " + } catch (Exception e) {
(oldObject.isResource() ? ((Resource)oldObject).getURI() : ((Literal)oldObject).getLexicalForm()) + logger.logError("Error removing statement for subject = " + subject.getURI() +
" to " + "and property = " + predicate.getURI() +
(newObject.isResource() ? ((Resource)newObject).getURI() : ((Literal)newObject).getLexicalForm()) + "from the knowledge base:\n" + e.getMessage());
" in the knowledge base:\n"); }
}
} catch (Exception e) {
logger.logError("Error trying to change the value of property " + predicate.getURI() +
" of class = " + subject.getURI() + " in the knowledge base:\n" + e.getMessage());
}
}
}
}
Model actualAdditions = additions.difference(retractions);
siteModel.add(actualAdditions);
record.recordAdditions(actualAdditions);
Model actualRetractions = retractions.difference(additions);
siteModel.remove(actualRetractions);
record.recordRetractions(actualRetractions);
long numAdded = actualAdditions.size();
long numRemoved = actualRetractions.size();
// log summary of changes
if (numAdded > 0) {
logger.log("Updated the default vitro annotation value for " +
numAdded + " statements in the knowledge base");
}
if (numRemoved > 0) {
logger.log("Removed " + numRemoved +
" outdated vitro annotation property setting" + ((numRemoved > 1) ? "s" : "") + " from the knowledge base");
}
// Copy annotation property settings that were introduced in the new ontology
// into the site model.
//
Model newAnnotationSettings = newTboxAnnotationsModel.difference(oldTboxAnnotationsModel); try {
Model newAnnotationSettingsToAdd = ModelFactory.createDefaultModel(); additions.add(subject, predicate, newObject);
StmtIterator newStmtIt = newAnnotationSettings.listStatements();
while (newStmtIt.hasNext()) {
Statement stmt = newStmtIt.next();
if (!siteModel.contains(stmt)) {
newAnnotationSettingsToAdd.add(stmt);
if (detailLogs) {
logger.log( "adding Statement: subject = " + stmt.getSubject().getURI() +
" property = " + stmt.getPredicate().getURI() +
" object = " + (stmt.getObject().isLiteral() ? ((Literal)stmt.getObject()).getLexicalForm()
: ((Resource)stmt.getObject()).getURI()));
}
}
}
siteModel.add(newAnnotationSettingsToAdd);
record.recordAdditions(newAnnotationSettingsToAdd);
// log the additions - summary
if (newAnnotationSettingsToAdd.size() > 0) {
boolean plural = (newAnnotationSettingsToAdd.size() > 1);
logger.log("Added " + newAnnotationSettingsToAdd.size() + " new annotation property setting" + (plural ? "s" : "") + " to the knowledge base. This includes only " +
"existing annotation properties applied to existing classes where they weren't applied before, or existing " +
"properties applied to new classes.");
}
} finally {
siteModel.leaveCriticalSection();
}
}
/**
*
* Update a knowledge base to align with changes to the vitro annotation model
* in a new version of the ontology. The two versions of the ontology and the
* knowledge base to be updated are provided in the class constructor and are
* referenced via class level variables.
*
* Currently, this method only handles deletions of a ClassGroup
*
* Writes to the change log file, the error log file, and the incremental change
* knowledge base.
*
*/
public void updateAnnotationModel() throws IOException {
// for each ClassGroup in the old vitro annotations model: if it is not in
// the new vitro annotations model and the site has no classes asserted to
// be in that class group then delete it.
removeObsoleteAnnotations();
siteModel.enterCriticalSection(Lock.WRITE);
try {
Model retractions = ModelFactory.createDefaultModel();
StmtIterator iter = oldTboxAnnotationsModel.listStatements((Resource) null, RDF.type, classGroupClass);
while (iter.hasNext()) {
Statement stmt = iter.next();
if (!newTboxAnnotationsModel.contains(stmt) && !usesGroup(siteModel, stmt.getSubject())) {
long pre = retractions.size();
retractions.add(siteModel.listStatements(stmt.getSubject(),(Property) null,(RDFNode)null));
long post = retractions.size();
if ((post - pre) > 0) {
logger.log("Removed the " + stmt.getSubject().getURI() + " ClassGroup from the annotations model");
}
}
}
if (retractions.size() > 0) {
siteModel.remove(retractions);
record.recordRetractions(retractions);
}
} finally {
siteModel.leaveCriticalSection();
}
// If we were going to handle add, this is the logic: if (detailLogs) {
// for each ClassGroup in new old vitro annotations model: if it is not in logger.log("Changed the value of property " + predicate.getURI() +
// the old vitro annotations and it is not in the site model, then " of subject = " + subject.getURI() +
// add it. " from " +
(oldObject.isResource() ? ((Resource)oldObject).getURI() : ((Literal)oldObject).getLexicalForm()) +
} " to " +
(newObject.isResource() ? ((Resource)newObject).getURI() : ((Literal)newObject).getLexicalForm()) +
" in the knowledge base:\n");
}
} catch (Exception e) {
logger.logError("Error trying to change the value of property " + predicate.getURI() +
" of class = " + subject.getURI() + " in the knowledge base:\n" + e.getMessage());
}
}
}
}
public boolean usesGroup(Model model, Resource theClassGroup) throws IOException { Model actualAdditions = additions.difference(retractions);
siteModel.add(actualAdditions);
model.enterCriticalSection(Lock.READ); record.recordAdditions(actualAdditions);
Model actualRetractions = retractions.difference(additions);
try { siteModel.remove(actualRetractions);
return (model.contains((Resource) null, inClassGroupProp, theClassGroup) ? true : false); record.recordRetractions(actualRetractions);
} finally {
model.leaveCriticalSection();
}
}
public void removeObsoleteAnnotations() throws IOException { long numAdded = actualAdditions.size();
long numRemoved = actualRetractions.size();
Resource subj1 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology/florida#StatewideGoalAndFocusArea");
Resource obj1 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology#vitroClassGrouptopics"); // log summary of changes
if (numAdded > 0) {
Property subj2 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty("http://vivoweb.org/ontology/florida#divisionOfSponsoredResearchNumber"); logger.log("Updated the default vitro annotation value for " +
Resource obj2 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology#vitroPropertyGroupidentifiers"); numAdded + " statements in the knowledge base");
}
Property subj3 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty("http://vivoweb.org/ontology/florida#statewideGoalAndFocusArea");
Resource obj3 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology#vitroPropertyGroupoutreach"); if (numRemoved > 0) {
logger.log("Removed " + numRemoved +
Property inPropertyGroupProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty("http://vitro.mannlib.cornell.edu/ns/vitro/0.7#inPropertyGroup"); " outdated vitro annotation property setting" + ((numRemoved > 1) ? "s" : "") + " from the knowledge base");
}
siteModel.enterCriticalSection(Lock.WRITE);
// Copy annotation property settings that were introduced in the new ontology
try { // into the site model.
Model retractions = ModelFactory.createDefaultModel(); //
if (siteModel.contains(subj1, inClassGroupProp, obj1) ) { Model newAnnotationSettings = newTboxAnnotationsModel.difference(oldTboxAnnotationsModel);
retractions.add(subj1, inClassGroupProp, obj1); Model newAnnotationSettingsToAdd = ModelFactory.createDefaultModel();
logger.log("Removed statement " + ABoxUpdater.stmtString(subj1, inClassGroupProp, obj1) + " from the knowledge base (assumed to be obsolete)"); StmtIterator newStmtIt = newAnnotationSettings.listStatements();
while (newStmtIt.hasNext()) {
Statement stmt = newStmtIt.next();
if (!siteModel.contains(stmt)) {
newAnnotationSettingsToAdd.add(stmt);
if (detailLogs) {
logger.log( "adding Statement: subject = " + stmt.getSubject().getURI() +
" property = " + stmt.getPredicate().getURI() +
" object = " + (stmt.getObject().isLiteral() ? ((Literal)stmt.getObject()).getLexicalForm()
: ((Resource)stmt.getObject()).getURI()));
}
}
}
siteModel.add(newAnnotationSettingsToAdd);
record.recordAdditions(newAnnotationSettingsToAdd);
// log the additions - summary
if (newAnnotationSettingsToAdd.size() > 0) {
boolean plural = (newAnnotationSettingsToAdd.size() > 1);
logger.log("Added " + newAnnotationSettingsToAdd.size() + " new annotation property setting" + (plural ? "s" : "") + " to the knowledge base. This includes only " +
"existing annotation properties applied to existing classes where they weren't applied before, or existing " +
"properties applied to new classes.");
}
} finally {
siteModel.leaveCriticalSection();
}
}
/**
*
* Update a knowledge base to align with changes to the vitro annotation model
* in a new version of the ontology. The two versions of the ontology and the
* knowledge base to be updated are provided in the class constructor and are
* referenced via class level variables.
*
* Currently, this method only handles deletions of a ClassGroup
*
* Writes to the change log file, the error log file, and the incremental change
* knowledge base.
*
*/
public void updateAnnotationModel() throws IOException {
// for each ClassGroup in the old vitro annotations model: if it is not in
// the new vitro annotations model and the site has no classes asserted to
// be in that class group then delete it.
removeObsoleteAnnotations();
siteModel.enterCriticalSection(Lock.WRITE);
try {
Model retractions = ModelFactory.createDefaultModel();
StmtIterator iter = oldTboxAnnotationsModel.listStatements((Resource) null, RDF.type, classGroupClass);
while (iter.hasNext()) {
Statement stmt = iter.next();
if (!newTboxAnnotationsModel.contains(stmt) && !usesGroup(siteModel, stmt.getSubject())) {
long pre = retractions.size();
retractions.add(siteModel.listStatements(stmt.getSubject(),(Property) null,(RDFNode)null));
long post = retractions.size();
if ((post - pre) > 0) {
logger.log("Removed the " + stmt.getSubject().getURI() + " ClassGroup from the annotations model");
}
}
}
if (retractions.size() > 0) {
siteModel.remove(retractions);
record.recordRetractions(retractions);
}
} finally {
siteModel.leaveCriticalSection();
} }
if (siteModel.contains(subj2, inPropertyGroupProp, obj2) ) { // If we were going to handle add, this is the logic:
retractions.add(subj2, inPropertyGroupProp, obj2); // for each ClassGroup in new old vitro annotations model: if it is not in
logger.log("Removed statement " + ABoxUpdater.stmtString(subj2, inPropertyGroupProp, obj2) + " from the knowledge base (assumed to be obsolete)"); // the old vitro annotations and it is not in the site model, then
} // add it.
if (siteModel.contains(subj3, inPropertyGroupProp, obj3) ) { }
retractions.add(subj3, inPropertyGroupProp, obj3);
logger.log("Removed statement " + ABoxUpdater.stmtString(subj3, inPropertyGroupProp, obj3) + " from the knowledge base (assumed to be obsolete)"); public boolean usesGroup(Model model, Resource theClassGroup) throws IOException {
model.enterCriticalSection(Lock.READ);
try {
return (model.contains((Resource) null, inClassGroupProp, theClassGroup) ? true : false);
} finally {
model.leaveCriticalSection();
} }
}
if (retractions.size() > 0) {
siteModel.remove(retractions); public void removeObsoleteAnnotations() throws IOException {
record.recordRetractions(retractions);
} Resource subj1 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology/florida#StatewideGoalAndFocusArea");
Resource obj1 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology#vitroClassGrouptopics");
} finally {
siteModel.leaveCriticalSection(); Property subj2 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty("http://vivoweb.org/ontology/florida#divisionOfSponsoredResearchNumber");
} Resource obj2 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology#vitroPropertyGroupidentifiers");
}
Property subj3 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty("http://vivoweb.org/ontology/florida#statewideGoalAndFocusArea");
Resource obj3 = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createResource("http://vivoweb.org/ontology#vitroPropertyGroupoutreach");
Property inPropertyGroupProp = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createProperty("http://vitro.mannlib.cornell.edu/ns/vitro/0.7#inPropertyGroup");
siteModel.enterCriticalSection(Lock.WRITE);
try {
Model retractions = ModelFactory.createDefaultModel();
if (siteModel.contains(subj1, inClassGroupProp, obj1) ) {
retractions.add(subj1, inClassGroupProp, obj1);
logger.log("Removed statement " + ABoxUpdater.stmtString(subj1, inClassGroupProp, obj1) + " from the knowledge base (assumed to be obsolete)");
}
if (siteModel.contains(subj2, inPropertyGroupProp, obj2) ) {
retractions.add(subj2, inPropertyGroupProp, obj2);
logger.log("Removed statement " + ABoxUpdater.stmtString(subj2, inPropertyGroupProp, obj2) + " from the knowledge base (assumed to be obsolete)");
}
if (siteModel.contains(subj3, inPropertyGroupProp, obj3) ) {
retractions.add(subj3, inPropertyGroupProp, obj3);
logger.log("Removed statement " + ABoxUpdater.stmtString(subj3, inPropertyGroupProp, obj3) + " from the knowledge base (assumed to be obsolete)");
}
if (retractions.size() > 0) {
siteModel.remove(retractions);
record.recordRetractions(retractions);
}
} finally {
siteModel.leaveCriticalSection();
}
}
public void renameProperty(AtomicOntologyChange changeObj) throws IOException {
Dataset dataset = new RDFServiceDataset(settings.getRDFService());
Model userAnnotationsModel = dataset.getNamedModel(
JenaDataSourceSetupBase.JENA_TBOX_ASSERTIONS_MODEL);
if(changeObj.getNotes() != null && changeObj.getNotes().startsWith("cc:")) {
mergePropertyAnnotationsToPropertyConfig(changeObj, userAnnotationsModel);
}
Resource renamedProperty = userAnnotationsModel.getResource(changeObj.getSourceURI());
userAnnotationsModel.removeAll(renamedProperty, null, (RDFNode) null);
userAnnotationsModel.removeAll(null, null, renamedProperty);
}
private void mergePropertyAnnotationsToPropertyConfig(AtomicOntologyChange changeObj,
Model userAnnotationsModel) throws IOException {
String contextURI = VitroVocabulary.PROPERTY_CONFIG_DATA + changeObj.getNotes().substring(3);
String oldPropertyURI = changeObj.getSourceURI();
Model oldAnnotationsModel = settings.getOldTBoxAnnotationsModel();
String propertyAnnotationsQuery =
"PREFIX config: <" + VitroVocabulary.configURI + "> \n" +
"PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" +
"CONSTRUCT { \n" +
" <" + oldPropertyURI + "> vitro:inPropertyGroupAnnot ?group . \n" +
" <" + oldPropertyURI + "> <" + RDFS.label.getURI() + "> ?label . \n" +
" <" + oldPropertyURI + "> vitro:displayRankAnnot ?displayRank . \n" +
" <" + oldPropertyURI + "> vitro:customEntryFormAnnot ?customForm . \n" +
" <" + oldPropertyURI + "> vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel . \n" +
" <" + oldPropertyURI + "> vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel . \n " +
"} WHERE { \n" +
" { <" + oldPropertyURI + "> vitro:inPropertyGroupAnnot ?group } \n" +
" UNION { <" + oldPropertyURI + "> <" + RDFS.label.getURI() + "> ?label } \n" +
" UNION { <" + oldPropertyURI + "> vitro:displayRankAnnot ?displayRank } \n" +
" UNION { <" + oldPropertyURI + "> vitro:customEntryFormAnnot ?customForm } \n" +
" UNION { <" + oldPropertyURI + "> vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" +
" UNION { <" + oldPropertyURI + "> vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n " +
"} \n" ;
Model userChangesModel = construct(
propertyAnnotationsQuery, userAnnotationsModel).difference(
construct(propertyAnnotationsQuery, oldAnnotationsModel));
String addQuery = "PREFIX config: <" + VitroVocabulary.configURI + "> \n" +
"PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" +
"CONSTRUCT { \n" +
" ?configuration config:propertyGroup ?group . \n" +
" ?configuration config:displayName ?label . \n" +
" ?configuration vitro:displayRankAnnot ?displayRank . \n" +
" ?configuration vitro:customEntryFormAnnot ?customForm . \n" +
" ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel . \n" +
" ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel . \n " +
"} WHERE { \n" +
" <" + contextURI + "> config:hasConfiguration ?configuration . \n" +
" OPTIONAL { <" + oldPropertyURI + "> vitro:inPropertyGroupAnnot ?group } \n" +
" OPTIONAL { <" + oldPropertyURI + "> <" + RDFS.label.getURI() + "> ?label } \n" +
" OPTIONAL { <" + oldPropertyURI + "> vitro:displayRankAnnot ?displayRank } \n" +
" OPTIONAL { <" + oldPropertyURI + "> vitro:customEntryFormAnnot ?customForm } \n" +
" OPTIONAL { <" + oldPropertyURI + "> vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" +
" OPTIONAL { <" + oldPropertyURI + "> vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n " +
"} \n" ;
String retractQuery = "PREFIX config: <" + VitroVocabulary.configURI + "> \n" +
"PREFIX vitro: <" + VitroVocabulary.vitroURI + "> \n" +
"CONSTRUCT { \n" +
" <" + oldPropertyURI + "> config:propertyGroup ?rgroup . \n" +
" ?configuration config:displayName ?rlabel . \n" +
" ?configuration vitro:displayRankAnnot ?rdisplayRank . \n" +
" ?configuration vitro:customEntryFormAnnot ?rcustomForm . \n" +
" ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?rdisplayLevel . \n" +
" ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?rupdateLevel . \n " +
"} WHERE { \n" +
" <" + contextURI + "> config:hasConfiguration ?configuration . \n" +
" OPTIONAL { <" + oldPropertyURI + "> vitro:inPropertyGroupAnnot ?group . \n" +
" ?configuration config:propertyGroup ?rgroup } \n" +
" OPTIONAL { <" + oldPropertyURI + "> <" + RDFS.label.getURI() + "> ?label . \n" +
" ?configuration config:displayName ?rlabel } \n " +
" OPTIONAL { <" + oldPropertyURI + "> vitro:displayRankAnnot ?displayRank . \n" +
" ?configuration vitro:displayRantAnnot ?rdisplayRank } \n " +
" OPTIONAL { <" + oldPropertyURI + "> vitro:customEntryFormAnnot ?customForm . \n" +
" ?configuration vitro:customEntryFormAnnot ?rcustomForm } \n" +
" OPTIONAL { <" + oldPropertyURI + "> vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel . \n" +
" ?configuration vitro:hiddenFromDisplayBelowRoleLevelAnnot ?rdisplayLevel } \n" +
" OPTIONAL { <" + oldPropertyURI + "> vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel . \n " +
" ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } " +
"} \n" ;
Model configModel = ModelFactory.createDefaultModel();
String configFileName = settings.getQualifiedPropertyConfigFile();
File file = new File(configFileName);
FileInputStream fis = new FileInputStream(file);
configModel.read(fis, null, "N3");
Model union = ModelFactory.createUnion(configModel,
userChangesModel);
Model additions = construct(addQuery, union);
Model retractions = construct(retractQuery, union);
if (additions.size() > 0 || retractions.size() > 0) {
configModel.remove(retractions);
log.info("Removing " + retractions.size() + " statements from " + contextURI);
configModel.add(additions);
log.info("Adding " + additions.size() + " statements from " + contextURI);
FileOutputStream fos = new FileOutputStream(file);
configModel.write(fos, "N3");
}
}
private Model construct(String queryStr, Model model) {
Query query = QueryFactory.create(queryStr);
QueryExecution qe = QueryExecutionFactory.create(query, model);
try {
return qe.execConstruct();
} finally {
qe.close();
}
}
} }

View file

@ -5,6 +5,7 @@ package edu.cornell.mannlib.vitro.webapp.ontology.update;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
public class UpdateSettings { public class UpdateSettings {
@ -20,6 +21,7 @@ public class UpdateSettings {
private String errorLogFile; private String errorLogFile;
private String addedDataFile; private String addedDataFile;
private String removedDataFile; private String removedDataFile;
private String qualifiedPropertyConfigFile;
private String defaultNamespace; private String defaultNamespace;
private OntModelSelector assertionOntModelSelector; private OntModelSelector assertionOntModelSelector;
private OntModelSelector inferenceOntModelSelector; private OntModelSelector inferenceOntModelSelector;
@ -37,6 +39,8 @@ public class UpdateSettings {
private OntModel newDisplayModelFromFile; private OntModel newDisplayModelFromFile;
private OntModel loadedAtStartupDisplayModel; private OntModel loadedAtStartupDisplayModel;
private OntModel oldDisplayModelVivoListViewConfig; private OntModel oldDisplayModelVivoListViewConfig;
private RDFService rdfService;
public String getDataDir() { public String getDataDir() {
return dataDir; return dataDir;
} }
@ -118,7 +122,13 @@ public class UpdateSettings {
public void setRemovedDataFile(String removedDataFile) { public void setRemovedDataFile(String removedDataFile) {
this.removedDataFile = removedDataFile; this.removedDataFile = removedDataFile;
} }
public String getDefaultNamespace() { public String getQualifiedPropertyConfigFile() {
return qualifiedPropertyConfigFile;
}
public void setQualifiedPropertyConfigFile(String qualifiedPropertyConfigFile) {
this.qualifiedPropertyConfigFile = qualifiedPropertyConfigFile;
}
public String getDefaultNamespace() {
return defaultNamespace; return defaultNamespace;
} }
public void setDefaultNamespace(String defaultNamespace) { public void setDefaultNamespace(String defaultNamespace) {
@ -223,6 +233,13 @@ public class UpdateSettings {
return this.oldDisplayModelVivoListViewConfig; return this.oldDisplayModelVivoListViewConfig;
} }
public RDFService getRDFService() {
return this.rdfService;
}
public void setRDFService(RDFService rdfService) {
this.rdfService = rdfService;
}
} }

View file

@ -6,13 +6,16 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
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.Node;
import com.hp.hpl.jena.graph.Triple; import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.query.DataSource; import com.hp.hpl.jena.query.DataSource;
import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.query.Dataset;
@ -21,11 +24,9 @@ import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QueryParseException;
import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter; import com.hp.hpl.jena.query.ResultSetFormatter;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.RDFNode;
@ -129,6 +130,7 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic
Resource s2 = (Resource) n; Resource s2 = (Resource) n;
// now run yet another describe query // now run yet another describe query
String smallerTree = makeDescribe(s2); String smallerTree = makeDescribe(s2);
log.debug(smallerTree);
Query smallerTreeQuery = QueryFactory.create(smallerTree); Query smallerTreeQuery = QueryFactory.create(smallerTree);
QueryExecution qe3 = QueryExecutionFactory.create( QueryExecution qe3 = QueryExecutionFactory.create(
smallerTreeQuery, tree); smallerTreeQuery, tree);
@ -172,13 +174,17 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic
StringBuffer queryBuff = new StringBuffer(); StringBuffer queryBuff = new StringBuffer();
queryBuff.append("CONSTRUCT { \n"); queryBuff.append("CONSTRUCT { \n");
addStatementPatterns(stmtIt, queryBuff, !WHERE_CLAUSE); List<Statement> stmts = stmtIt.toList();
stmts = sort(stmts);
addStatementPatterns(stmts, queryBuff, !WHERE_CLAUSE);
queryBuff.append("} WHERE { \n"); queryBuff.append("} WHERE { \n");
if (graphURI != null) { if (graphURI != null) {
queryBuff.append(" GRAPH <" + graphURI + "> { \n"); queryBuff.append(" GRAPH <" + graphURI + "> { \n");
} }
stmtIt = model.listStatements(); stmtIt = model.listStatements();
addStatementPatterns(stmtIt, queryBuff, WHERE_CLAUSE); stmts = stmtIt.toList();
stmts = sort(stmts);
addStatementPatterns(stmts, queryBuff, WHERE_CLAUSE);
if (graphURI != null) { if (graphURI != null) {
queryBuff.append(" } \n"); queryBuff.append(" } \n");
} }
@ -208,11 +214,61 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic
} }
} }
private List<Statement> sort(List<Statement> stmts) {
List<Statement> output = new ArrayList<Statement>();
int originalSize = stmts.size();
List <Statement> remaining = stmts;
ConcurrentLinkedQueue<Resource> subjQueue = new ConcurrentLinkedQueue<Resource>();
for(Statement stmt : remaining) {
if(stmt.getSubject().isURIResource()) {
subjQueue.add(stmt.getSubject());
break;
}
}
if (subjQueue.isEmpty()) {
throw new RuntimeException("No named subject in statement patterns");
}
while(remaining.size() > 0) {
if(subjQueue.isEmpty()) {
subjQueue.add(remaining.get(0).getSubject());
}
while(!subjQueue.isEmpty()) {
Resource subj = subjQueue.poll();
List<Statement> temp = new ArrayList<Statement>();
for (Statement stmt : remaining) {
if(stmt.getSubject().equals(subj)) {
output.add(stmt);
if (stmt.getObject().isResource()) {
subjQueue.add((Resource) stmt.getObject());
}
} else {
temp.add(stmt);
}
}
remaining = temp;
}
}
if(output.size() != originalSize) {
throw new RuntimeException("original list size was " + originalSize +
" but sorted size is " + output.size());
}
return output;
}
private String getHexString(Node node) {
String label = node.getBlankNodeLabel().replaceAll("\\W", "").toUpperCase();
if (label.length() > 7) {
return label.substring(label.length() - 7);
} else {
return label;
}
}
private static final boolean WHERE_CLAUSE = true; private static final boolean WHERE_CLAUSE = true;
private void addStatementPatterns(StmtIterator stmtIt, StringBuffer patternBuff, boolean whereClause) { private void addStatementPatterns(List<Statement> stmts, StringBuffer patternBuff, boolean whereClause) {
while(stmtIt.hasNext()) { for(Statement stmt : stmts) {
Triple t = stmtIt.next().asTriple(); Triple t = stmt.asTriple();
patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getSubject(), null)); patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getSubject(), null));
patternBuff.append(" "); patternBuff.append(" ");
patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getPredicate(), null)); patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getPredicate(), null));

View file

@ -9,6 +9,7 @@ import java.io.StringWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
@ -715,7 +716,9 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService {
if (graphURI != null) { if (graphURI != null) {
queryBuff.append(" GRAPH <" + graphURI + "> { \n"); queryBuff.append(" GRAPH <" + graphURI + "> { \n");
} }
addStatementPatterns(stmtIt, queryBuff, !WHERE_CLAUSE); List<Statement> stmts = stmtIt.toList();
sort(stmts);
addStatementPatterns(stmts, queryBuff, !WHERE_CLAUSE);
if (graphURI != null) { if (graphURI != null) {
queryBuff.append(" } \n"); queryBuff.append(" } \n");
} }
@ -724,7 +727,9 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService {
queryBuff.append(" GRAPH <" + graphURI + "> { \n"); queryBuff.append(" GRAPH <" + graphURI + "> { \n");
} }
stmtIt = model.listStatements(); stmtIt = model.listStatements();
addStatementPatterns(stmtIt, queryBuff, WHERE_CLAUSE); stmts = stmtIt.toList();
sort(stmts);
addStatementPatterns(stmts, queryBuff, WHERE_CLAUSE);
if (graphURI != null) { if (graphURI != null) {
queryBuff.append(" } \n"); queryBuff.append(" } \n");
} }
@ -736,11 +741,53 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService {
executeUpdate(queryBuff.toString()); executeUpdate(queryBuff.toString());
} }
private List<Statement> sort(List<Statement> stmts) {
List<Statement> output = new ArrayList<Statement>();
int originalSize = stmts.size();
List <Statement> remaining = stmts;
ConcurrentLinkedQueue<com.hp.hpl.jena.rdf.model.Resource> subjQueue =
new ConcurrentLinkedQueue<com.hp.hpl.jena.rdf.model.Resource>();
for(Statement stmt : remaining) {
if(stmt.getSubject().isURIResource()) {
subjQueue.add(stmt.getSubject());
break;
}
}
if (subjQueue.isEmpty()) {
throw new RuntimeException("No named subject in statement patterns");
}
while(remaining.size() > 0) {
if(subjQueue.isEmpty()) {
subjQueue.add(remaining.get(0).getSubject());
}
while(!subjQueue.isEmpty()) {
com.hp.hpl.jena.rdf.model.Resource subj = subjQueue.poll();
List<Statement> temp = new ArrayList<Statement>();
for (Statement stmt : remaining) {
if(stmt.getSubject().equals(subj)) {
output.add(stmt);
if (stmt.getObject().isResource()) {
subjQueue.add((com.hp.hpl.jena.rdf.model.Resource) stmt.getObject());
}
} else {
temp.add(stmt);
}
}
remaining = temp;
}
}
if(output.size() != originalSize) {
throw new RuntimeException("original list size was " + originalSize +
" but sorted size is " + output.size());
}
return output;
}
private static final boolean WHERE_CLAUSE = true; private static final boolean WHERE_CLAUSE = true;
private void addStatementPatterns(StmtIterator stmtIt, StringBuffer patternBuff, boolean whereClause) { private void addStatementPatterns(List<Statement> stmts, StringBuffer patternBuff, boolean whereClause) {
while(stmtIt.hasNext()) { for(Statement stmt : stmts) {
Triple t = stmtIt.next().asTriple(); Triple t = stmt.asTriple();
patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getSubject(), null)); patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getSubject(), null));
patternBuff.append(" "); patternBuff.append(" ");
patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getPredicate(), null)); patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getPredicate(), null));

View file

@ -251,18 +251,24 @@ public class SimpleReasoner extends StatementListener {
return; return;
} }
OntClass subject = tboxModel.getOntClass((stmt.getSubject()).getURI()); OntClass subject, object;
if (subject == null) { tboxModel.enterCriticalSection(Lock.READ);
log.debug("didn't find subject class in the tbox: " try {
+ (stmt.getSubject()).getURI()); subject = tboxModel.getOntClass((stmt.getSubject()).getURI());
return; if (subject == null) {
} log.debug("didn't find subject class in the tbox: "
+ (stmt.getSubject()).getURI());
OntClass object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI()); return;
if (object == null) { }
log.debug("didn't find object class in the tbox: "
+ ((Resource)stmt.getObject()).getURI()); object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI());
return; if (object == null) {
log.debug("didn't find object class in the tbox: "
+ ((Resource)stmt.getObject()).getURI());
return;
}
} finally {
tboxModel.leaveCriticalSection();
} }
if (stmt.getPredicate().equals(RDFS.subClassOf)) { if (stmt.getPredicate().equals(RDFS.subClassOf)) {
@ -1672,6 +1678,10 @@ public class SimpleReasoner extends StatementListener {
typeURIs = getRemainingAssertedTypeURIs(stmt.getSubject()); typeURIs = getRemainingAssertedTypeURIs(stmt.getSubject());
} }
removedABoxTypeAssertion(stmt, inferenceModel, typeURIs); removedABoxTypeAssertion(stmt, inferenceModel, typeURIs);
} else if (doSameAs && stmt.getPredicate().equals(OWL.sameAs)) {
removedABoxSameAsAssertion(stmt, inferenceModel);
} else {
removedABoxAssertion(stmt, inferenceModel);
} }
doPlugins(ModelUpdate.Operation.RETRACT,stmt); doPlugins(ModelUpdate.Operation.RETRACT,stmt);
} catch (NullPointerException npe) { } catch (NullPointerException npe) {

View file

@ -1,85 +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.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
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.assembler.Assembler;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.vocabulary.RDF;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelSynchronizer;
/**
* This is the beginning of a more sane and flexible model management system,
* especially necessary for DataStaR.
* Don't use it yet; it's going to change.
* (That part is still insane, I know.)
* @author bjl23
*/
public class AssembleModelsSetup implements ServletContextListener {
private static final Log log = LogFactory.getLog(AssembleModelsSetup.class);
private List<Model> assembledModels = new LinkedList<Model>();
private String ASSEMBLERS_DIR_PATH = "/WEB-INF/assemblers/";
private Resource ASSEMBLER_OBJECT = ResourceFactory.createProperty("http://jena.hpl.hp.com/2005/11/Assembler#Object");
private String SYNTAX = "N3";
public void contextInitialized(ServletContextEvent sce) {
OntModel jenaOntModel = ModelAccess.on(sce.getServletContext()).getBaseOntModel();
// read assemblers out of assemblers directory
Set pathSet = sce.getServletContext().getResourcePaths(ASSEMBLERS_DIR_PATH);
for (String path : (Set<String>)pathSet) {
InputStream assemblerInputStream = sce.getServletContext().getResourceAsStream(path);
Model assemblerModel = ModelFactory.createDefaultModel();
try {
assemblerModel.read(assemblerInputStream, null, SYNTAX);
ExtendedIterator assemblerIt = assemblerModel.listResourcesWithProperty(RDF.type,ASSEMBLER_OBJECT);
while (assemblerIt.hasNext()) {
Resource assemblerObj = (Resource) assemblerIt.next();
Model assembledModel = Assembler.general.openModel(assemblerObj);
/* special stuff here */
Model memModel = ModelFactory.createDefaultModel();
memModel.add(assembledModel);
memModel.register(new ModelSynchronizer(assembledModel));
/* end special stuff */
if (assembledModel != null) {
jenaOntModel.addSubModel(memModel);
}
}
if (assemblerIt != null) {
assemblerIt.close();
}
} catch (Exception e) {
log.error("Unable to use assembler at "+path);
}
}
System.out.println("ContextListener AssembleModelsSetup done");
}
public void contextDestroyed(ServletContextEvent sce) {
for (Model model : assembledModels) {
if (model != null) {
model.close();
}
}
}
}

View file

@ -56,7 +56,7 @@ public class SimpleReasonerSetup implements ServletContextListener {
OntModelSelector inferencesOms = ModelAccess.on(ctx).getInferenceOntModelSelector(); OntModelSelector inferencesOms = ModelAccess.on(ctx).getInferenceOntModelSelector();
OntModelSelector unionOms = ModelAccess.on(ctx).getUnionOntModelSelector(); OntModelSelector unionOms = ModelAccess.on(ctx).getUnionOntModelSelector();
WebappDaoFactoryJena wadf = (WebappDaoFactoryJena) ModelAccess.on(ctx).getWebappDaoFactory(); WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory();
if (!assertionsOms.getTBoxModel().getProfile().NAMESPACE().equals(OWL.NAMESPACE.getNameSpace())) { if (!assertionsOms.getTBoxModel().getProfile().NAMESPACE().equals(OWL.NAMESPACE.getNameSpace())) {
log.error("Not connecting Pellet reasoner - the TBox assertions model is not an OWL model"); log.error("Not connecting Pellet reasoner - the TBox assertions model is not an OWL model");
@ -75,28 +75,24 @@ public class SimpleReasonerSetup implements ServletContextListener {
sce.getServletContext().setAttribute("pelletListener",pelletListener); sce.getServletContext().setAttribute("pelletListener",pelletListener);
sce.getServletContext().setAttribute("pelletOntModel", pelletListener.getPelletModel()); sce.getServletContext().setAttribute("pelletOntModel", pelletListener.getPelletModel());
if (wadf != null) { if (wadf instanceof WebappDaoFactoryJena) {
wadf.setPelletListener(pelletListener); ((WebappDaoFactoryJena) wadf).setPelletListener(pelletListener);
} }
log.info("Pellet reasoner connected for the TBox"); log.info("Pellet reasoner connected for the TBox");
// set up simple reasoning for the ABox // set up simple reasoning for the ABox
DataSource bds = JenaDataSourceSetupBase
.getApplicationDataSource(ctx);
String dbType = ConfigurationProperties.getBean(ctx).getProperty( // database type
"VitroConnection.DataSource.dbtype","MySQL");
RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService(); RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService();
Dataset dataset = new RDFServiceDataset(rdfService); Dataset dataset = new RDFServiceDataset(rdfService);
Model rebuildModel = dataset.getNamedModel(JENA_INF_MODEL_REBUILD); Model rebuildModel = dataset.getNamedModel(JENA_INF_MODEL_REBUILD);
Model scratchModel = dataset.getNamedModel(JENA_INF_MODEL_SCRATCHPAD); Model scratchModel = dataset.getNamedModel(JENA_INF_MODEL_SCRATCHPAD);
Model inferenceModel = dataset.getNamedModel(JenaDataSourceSetupBase.JENA_INF_MODEL);
// the simple reasoner will register itself as a listener to the ABox assertions // the simple reasoner will register itself as a listener to the ABox assertions
SimpleReasoner simpleReasoner = new SimpleReasoner( SimpleReasoner simpleReasoner = new SimpleReasoner(
unionOms.getTBoxModel(), rdfService, inferencesOms.getABoxModel(), rebuildModel, scratchModel); unionOms.getTBoxModel(), rdfService, inferenceModel, rebuildModel, scratchModel);
sce.getServletContext().setAttribute(SimpleReasoner.class.getName(),simpleReasoner); sce.getServletContext().setAttribute(SimpleReasoner.class.getName(),simpleReasoner);
StartupStatus ss = StartupStatus.getBean(ctx); StartupStatus ss = StartupStatus.getBean(ctx);
@ -114,19 +110,6 @@ public class SimpleReasonerSetup implements ServletContextListener {
} }
simpleReasoner.setPluginList(pluginList); simpleReasoner.setPluginList(pluginList);
if (isRecomputeRequired(sce.getServletContext())) {
log.info("ABox inference recompute required.");
waitForTBoxReasoning(pelletListener);
if (JenaDataSourceSetupBase.isFirstStartup()) {
simpleReasoner.recompute();
} else {
log.info("starting ABox inference recompute in a separate thread.");
new Thread(new ABoxRecomputer(simpleReasoner),"ABoxRecomputer").start();
}
}
SimpleReasonerTBoxListener simpleReasonerTBoxListener = new SimpleReasonerTBoxListener(simpleReasoner); SimpleReasonerTBoxListener simpleReasonerTBoxListener = new SimpleReasonerTBoxListener(simpleReasoner);
sce.getServletContext().setAttribute(SimpleReasonerTBoxListener.class.getName(),simpleReasonerTBoxListener); sce.getServletContext().setAttribute(SimpleReasonerTBoxListener.class.getName(),simpleReasonerTBoxListener);
assertionsOms.getTBoxModel().register(simpleReasonerTBoxListener); assertionsOms.getTBoxModel().register(simpleReasonerTBoxListener);
@ -139,16 +122,21 @@ public class SimpleReasonerSetup implements ServletContextListener {
} }
} }
private void waitForTBoxReasoning(PelletListener pelletListener) public static void waitForTBoxReasoning(ServletContextEvent sce)
throws InterruptedException { throws InterruptedException {
int sleeps = 0; PelletListener pelletListener = (PelletListener) sce.getServletContext().getAttribute("pelletListener");
while (sleeps < 1000 && pelletListener.isReasoning()) { if (pelletListener == null) {
if ((sleeps % 10) == 0) { // print message at 10 second intervals return ;
log.info("Waiting for initial TBox reasoning to complete"); }
} int sleeps = 0;
Thread.sleep(1000); // sleep at least once to make sure the TBox reasoning gets started
sleeps++; while ((0 == sleeps) || ((sleeps < 1000) && pelletListener.isReasoning())) {
} if ((sleeps % 10) == 0) { // print message at 10 second intervals
log.info("Waiting for initial TBox reasoning to complete");
}
Thread.sleep(1000);
sleeps++;
}
} }
@Override @Override
@ -196,7 +184,7 @@ public class SimpleReasonerSetup implements ServletContextListener {
ctx.setAttribute(RECOMPUTE_REQUIRED_ATTR, true); ctx.setAttribute(RECOMPUTE_REQUIRED_ATTR, true);
} }
private static boolean isRecomputeRequired(ServletContext ctx) { public static boolean isRecomputeRequired(ServletContext ctx) {
return (ctx.getAttribute(RECOMPUTE_REQUIRED_ATTR) != null); return (ctx.getAttribute(RECOMPUTE_REQUIRED_ATTR) != null);
} }
@ -210,19 +198,6 @@ public class SimpleReasonerSetup implements ServletContextListener {
private static boolean isMSTComputeRequired(ServletContext ctx) { private static boolean isMSTComputeRequired(ServletContext ctx) {
return (ctx.getAttribute(MSTCOMPUTE_REQUIRED_ATTR) != null); return (ctx.getAttribute(MSTCOMPUTE_REQUIRED_ATTR) != null);
} }
private class ABoxRecomputer implements Runnable {
private SimpleReasoner simpleReasoner;
public ABoxRecomputer(SimpleReasoner simpleReasoner) {
this.simpleReasoner = simpleReasoner;
}
public void run() {
simpleReasoner.recompute();
}
}
/** /**
* Read the names of the plugin classes classes. * Read the names of the plugin classes classes.

View file

@ -41,6 +41,9 @@ import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater; import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater;
import edu.cornell.mannlib.vitro.webapp.ontology.update.UpdateSettings; import edu.cornell.mannlib.vitro.webapp.ontology.update.UpdateSettings;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
import edu.cornell.mannlib.vitro.webapp.reasoner.ABoxRecomputer;
import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/** /**
@ -54,10 +57,11 @@ public class UpdateKnowledgeBase implements ServletContextListener {
private final static Log log = LogFactory.getLog(UpdateKnowledgeBase.class); private final static Log log = LogFactory.getLog(UpdateKnowledgeBase.class);
private static final String DATA_DIR = "/WEB-INF/ontologies/update/"; private static final String DATA_DIR = "/WEB-INF/ontologies/update/";
private static final String DIFF_FILE = DATA_DIR + "diff.tab.txt";
private static final String ASK_QUERY_FILE = DATA_DIR + "askUpdated.sparql";
private static final String SUCCESS_ASSERTIONS_FILE = DATA_DIR + "success.n3";
private static final String OLD_TBOX_MODEL_DIR = DATA_DIR + "oldVersion/"; private static final String OLD_TBOX_MODEL_DIR = DATA_DIR + "oldVersion/";
private static final String NEW_TBOX_MODEL_DIR = "/WEB-INF/filegraph/tbox/";
private static final String OLD_TBOX_ANNOTATIONS_DIR = DATA_DIR + "oldAnnotations/"; private static final String OLD_TBOX_ANNOTATIONS_DIR = DATA_DIR + "oldAnnotations/";
private static final String NEW_TBOX_ANNOTATIONS_DIR = "/WEB-INF/ontologies/user/tbox/";
//For display model migration //For display model migration
private static final String OLD_DISPLAYMODEL_TBOX_PATH = DATA_DIR + "oldDisplayModel/displayTBOX.n3"; private static final String OLD_DISPLAYMODEL_TBOX_PATH = DATA_DIR + "oldDisplayModel/displayTBOX.n3";
private static final String NEW_DISPLAYMODEL_TBOX_PATH = "/WEB-INF/ontologies/app/menuload/displayTBOX.n3"; private static final String NEW_DISPLAYMODEL_TBOX_PATH = "/WEB-INF/ontologies/app/menuload/displayTBOX.n3";
@ -72,78 +76,136 @@ public class UpdateKnowledgeBase implements ServletContextListener {
ServletContext ctx = sce.getServletContext(); ServletContext ctx = sce.getServletContext();
StartupStatus ss = StartupStatus.getBean(ctx); StartupStatus ss = StartupStatus.getBean(ctx);
boolean migrationChangesMade = false;
try { try {
UpdateSettings settings = new UpdateSettings(); UpdateSettings settings = new UpdateSettings();
putReportingPathsIntoSettings(ctx, settings); putReportingPathsIntoSettings(ctx, settings);
putNonReportingPathsIntoSettings(ctx, settings);
SimpleReasonerSetup.waitForTBoxReasoning(sce);
WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory(); WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory();
settings.setDefaultNamespace(wadf.getDefaultNamespace()); settings.setDefaultNamespace(wadf.getDefaultNamespace());
settings.setAssertionOntModelSelector(ModelAccess.on(ctx).getBaseOntModelSelector()); settings.setAssertionOntModelSelector(ModelAccess.on(ctx).getBaseOntModelSelector());
settings.setInferenceOntModelSelector(ModelAccess.on(ctx).getInferenceOntModelSelector()); settings.setInferenceOntModelSelector(ModelAccess.on(ctx).getInferenceOntModelSelector());
settings.setUnionOntModelSelector(ModelAccess.on(ctx).getUnionOntModelSelector()); settings.setUnionOntModelSelector(ModelAccess.on(ctx).getUnionOntModelSelector());
ConfigurationProperties props = ConfigurationProperties.getBean(ctx);
Path homeDir = Paths.get(props.getProperty("vitro.home"));
settings.setDisplayModel(ModelAccess.on(ctx).getDisplayModel());
OntModel oldTBoxModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_MODEL_DIR));
settings.setOldTBoxModel(oldTBoxModel);
OntModel newTBoxModel = loadModelFromDirectory(createDirectory(homeDir, "rdf", "tbox", "filegraph").toString());
settings.setNewTBoxModel(newTBoxModel);
OntModel oldTBoxAnnotationsModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_ANNOTATIONS_DIR));
settings.setOldTBoxAnnotationsModel(oldTBoxAnnotationsModel);
OntModel newTBoxAnnotationsModel = loadModelFromDirectory(createDirectory(homeDir, "rdf", "tbox", "firsttime").toString());
settings.setNewTBoxAnnotationsModel(newTBoxAnnotationsModel);
settings.setRDFService(RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService());
boolean tryMigrateDisplay = true; boolean tryMigrateDisplay = true;
try { try {
settings.setDisplayModel(ModelAccess.on(ctx).getDisplayModel()); //Display model tbox and display metadata
OntModel oldTBoxModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_MODEL_DIR)); //old display model tbox model
settings.setOldTBoxModel(oldTBoxModel); OntModel oldDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_TBOX_PATH));
OntModel newTBoxModel = loadModelFromDirectory(ctx.getRealPath(NEW_TBOX_MODEL_DIR)); settings.setOldDisplayModelTboxModel(oldDisplayModelTboxModel);
settings.setNewTBoxModel(newTBoxModel); //new display model tbox model
OntModel oldTBoxAnnotationsModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_ANNOTATIONS_DIR)); OntModel newDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_TBOX_PATH));
settings.setOldTBoxAnnotationsModel(oldTBoxAnnotationsModel); settings.setNewDisplayModelTboxModel(newDisplayModelTboxModel);
OntModel newTBoxAnnotationsModel = loadModelFromDirectory(ctx.getRealPath(NEW_TBOX_ANNOTATIONS_DIR)); //old display model display model metadata
settings.setNewTBoxAnnotationsModel(newTBoxAnnotationsModel); OntModel oldDisplayModelDisplayMetadataModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_DISPLAYMETADATA_PATH));
//Display model tbox and display metadata settings.setOldDisplayModelDisplayMetadataModel(oldDisplayModelDisplayMetadataModel);
//old display model tbox model //new display model display model metadata
OntModel oldDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_TBOX_PATH)); OntModel newDisplayModelDisplayMetadataModel = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_DISPLAYMETADATA_PATH));
settings.setOldDisplayModelTboxModel(oldDisplayModelTboxModel); settings.setNewDisplayModelDisplayMetadataModel(newDisplayModelDisplayMetadataModel);
//new display model tbox model //Get new display model
OntModel newDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_TBOX_PATH)); OntModel newDisplayModelFromFile = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_PATH));
settings.setNewDisplayModelTboxModel(newDisplayModelTboxModel); settings.setNewDisplayModelFromFile(newDisplayModelFromFile);
//old display model display model metadata OntModel loadedAtStartupFiles = loadModelFromDirectory(ctx.getRealPath(LOADED_STARTUPT_DISPLAYMODEL_DIR));
OntModel oldDisplayModelDisplayMetadataModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_DISPLAYMETADATA_PATH)); settings.setLoadedAtStartupDisplayModel(loadedAtStartupFiles);
settings.setOldDisplayModelDisplayMetadataModel(oldDisplayModelDisplayMetadataModel); OntModel oldDisplayModelVivoListView = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_VIVOLISTVIEW_PATH));
//new display model display model metadata settings.setVivoListViewConfigDisplayModel(oldDisplayModelVivoListView);
OntModel newDisplayModelDisplayMetadataModel = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_DISPLAYMETADATA_PATH)); } catch (ModelFileNotFoundException e) {
settings.setNewDisplayModelDisplayMetadataModel(newDisplayModelDisplayMetadataModel); // expected if no display migration was intended
//Get new display model tryMigrateDisplay = false;
OntModel newDisplayModelFromFile = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_PATH));
settings.setNewDisplayModelFromFile(newDisplayModelFromFile);
OntModel loadedAtStartupFiles = loadModelFromDirectory(ctx.getRealPath(LOADED_STARTUPT_DISPLAYMODEL_DIR));
settings.setLoadedAtStartupDisplayModel(loadedAtStartupFiles);
OntModel oldDisplayModelVivoListView = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_VIVOLISTVIEW_PATH));
settings.setVivoListViewConfigDisplayModel(oldDisplayModelVivoListView);
} catch (Exception e) { } catch (Exception e) {
log.info("unable to read display model migration files, display model not migrated. " + e.getMessage()); log.info("Unable to read display model migration files. ", e);
tryMigrateDisplay = false; tryMigrateDisplay = false;
} }
try {
KnowledgeBaseUpdater ontologyUpdater = new KnowledgeBaseUpdater(settings); KnowledgeBaseUpdater ontologyUpdater = new KnowledgeBaseUpdater(settings);
boolean requiredUpdate = ontologyUpdater.updateRequired(ctx);
try {
if (ontologyUpdater.updateRequired(ctx)) { try {
ctx.setAttribute(KBM_REQURIED_AT_STARTUP, Boolean.TRUE); ctx.setAttribute(KBM_REQURIED_AT_STARTUP, Boolean.TRUE);
ontologyUpdater.update(ctx); log.info("Data migration required");
if (tryMigrateDisplay) { migrationChangesMade = ontologyUpdater.update(ctx);
try { if (tryMigrateDisplay) {
migrateDisplayModel(settings); try {
log.info("Migrated display model"); migrateDisplayModel(settings);
} catch (Exception e) { log.info("Migrated display model");
log.warn("unable to successfully update display model: " + e.getMessage()); } catch (Exception e) {
} log.warn("unable to successfully update display model: " + e.getMessage());
} }
} }
} catch (Exception ioe) { // reload the display model since the TBoxUpdater may have
ss.fatal(this, "Exception updating knowledge base for ontology changes: ", ioe); // modified it
} new ApplicationModelSetup().contextInitialized(sce);
} catch (Throwable t){ } catch (Exception ioe) {
ss.fatal(this, "Exception updating knowledge base for ontology changes: ", t); ss.fatal(this, "Exception updating knowledge base for ontology changes: ", ioe);
} }
} catch (Throwable t) {
ss.fatal(this, "Exception updating knowledge base for ontology changes: ", t); SimpleReasoner simpleReasoner = (SimpleReasoner) sce.getServletContext()
.getAttribute(SimpleReasoner.class.getName());
if (simpleReasoner != null) {
if ( (requiredUpdate && migrationChangesMade)
|| JenaDataSourceSetupBase.isFirstStartup()) {
log.info("ABox inference recompute required.");
simpleReasoner.recompute();
} else if (SimpleReasonerSetup.isRecomputeRequired(sce.getServletContext()) || migrationChangesMade) {
log.info("starting ABox inference recompute in a separate thread.");
new Thread(
new ABoxRecomputer(
simpleReasoner),"ABoxRecomputer").start();
}
}
} catch (Throwable t){
ss.fatal(this, "Exception updating knowledge base for ontology changes: ", t);
} }
} }
private class ABoxRecomputer implements Runnable {
private SimpleReasoner simpleReasoner;
public ABoxRecomputer(SimpleReasoner simpleReasoner) {
this.simpleReasoner = simpleReasoner;
}
public void run() {
simpleReasoner.recompute();
}
}
/**
* Set the paths for the files that specify how to perform the update
*/
private void putNonReportingPathsIntoSettings(ServletContext ctx, UpdateSettings settings) {
settings.setAskUpdatedQueryFile(ctx.getRealPath(ASK_QUERY_FILE));
settings.setDiffFile(ctx.getRealPath(DIFF_FILE));
settings.setSparqlConstructAdditionsDir(ctx.getRealPath(DATA_DIR + "sparqlConstructs/additions"));
settings.setSparqlConstructDeletionsDir(ctx.getRealPath(DATA_DIR + "sparqlConstructs/deletions"));
settings.setSuccessAssertionsFile(ctx.getRealPath(SUCCESS_ASSERTIONS_FILE));
settings.setSuccessRDFFormat("N3");
}
/** /**
* Create the directories where we will report on the update. * Create the directories where we will report on the update.
* Put the paths for the directories and files into the settings object. * Put the paths for the directories and files into the settings object.
@ -156,14 +218,6 @@ public class UpdateKnowledgeBase implements ServletContextListener {
settings.setDataDir(dataDir.toString()); settings.setDataDir(dataDir.toString());
StartupStatus.getBean(ctx).info(this, "Updating knowledge base: reports are in '" + dataDir + "'"); StartupStatus.getBean(ctx).info(this, "Updating knowledge base: reports are in '" + dataDir + "'");
settings.setAskUpdatedQueryFile(dataDir.resolve("askUpdated.sparql").toString());
settings.setDiffFile(dataDir.resolve("diff.tab.txt").toString());
settings.setSuccessAssertionsFile(dataDir.resolve("success.n3").toString());
settings.setSuccessRDFFormat("N3");
settings.setSparqlConstructAdditionsDir(createDirectory(dataDir, "sparqlConstructs", "additions").toString());
settings.setSparqlConstructDeletionsDir(createDirectory(dataDir, "sparqlConstructs", "deletions").toString());
Path changedDir = createDirectory(dataDir, "changedData"); Path changedDir = createDirectory(dataDir, "changedData");
settings.setAddedDataFile(changedDir.resolve("addedData.n3").toString()); settings.setAddedDataFile(changedDir.resolve("addedData.n3").toString());
settings.setRemovedDataFile(changedDir.resolve("removedData.n3").toString()); settings.setRemovedDataFile(changedDir.resolve("removedData.n3").toString());
@ -171,8 +225,19 @@ public class UpdateKnowledgeBase implements ServletContextListener {
Path logDir = createDirectory(dataDir, "logs"); Path logDir = createDirectory(dataDir, "logs");
settings.setLogFile(logDir.resolve(timestampedFileName("knowledgeBaseUpdate", "log")).toString()); settings.setLogFile(logDir.resolve(timestampedFileName("knowledgeBaseUpdate", "log")).toString());
settings.setErrorLogFile(logDir.resolve(timestampedFileName("knowledgeBaseUpdate.error", "log")).toString()); settings.setErrorLogFile(logDir.resolve(timestampedFileName("knowledgeBaseUpdate.error", "log")).toString());
Path qualifiedPropertyConfigFile = getFilePath(homeDir, "rdf", "display", "everytime", "PropertyConfig.n3");
settings.setQualifiedPropertyConfigFile(qualifiedPropertyConfigFile.toString());
} }
private Path getFilePath(Path parent, String... children) throws IOException {
Path path = parent;
for (String child : children) {
path = path.resolve(child);
}
return path;
}
private Path createDirectory(Path parent, String... children) throws IOException { private Path createDirectory(Path parent, String... children) throws IOException {
Path dir = parent; Path dir = parent;
for (String child : children) { for (String child : children) {

View file

@ -10,100 +10,119 @@ import javax.servlet.ServletContext;
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.ontology.OntModelSpec;
import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet; 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.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess; import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID; import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess.ModelID;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
public class ApplicationConfigurationOntologyUtils { public class ApplicationConfigurationOntologyUtils {
private static final Log log = LogFactory.getLog(ApplicationConfigurationOntologyUtils.class); private static final Log log = LogFactory.getLog(ApplicationConfigurationOntologyUtils.class);
public static List<ObjectProperty> getAdditionalFauxSubpropertiesForList(List<ObjectProperty> propList, VitroRequest vreq) { public static List<ObjectProperty> getAdditionalFauxSubpropertiesForList(List<ObjectProperty> propList, Individual subject, VitroRequest vreq) {
ServletContext ctx = vreq.getSession().getServletContext(); ServletContext ctx = vreq.getSession().getServletContext();
Model displayModel = ModelAccess.on(ctx).getDisplayModel(); Model displayModel = ModelAccess.on(ctx).getDisplayModel();
Model tboxModel = ModelAccess.on(ctx).getOntModel(ModelID.UNION_TBOX); Model tboxModel = ModelAccess.on(ctx).getOntModel(ModelID.UNION_TBOX);
return getAdditionalFauxSubpropertiesForList(propList, displayModel, tboxModel); return getAdditionalFauxSubpropertiesForList(propList, subject, displayModel, tboxModel);
} }
public static List<ObjectProperty> getAdditionalFauxSubproperties(ObjectProperty prop,
Individual subject,
Model tboxModel,
Model union) {
List<ObjectProperty> additionalProps = new ArrayList<ObjectProperty>();
String queryStr = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
"SELECT DISTINCT ?range ?domain ?property WHERE { \n" +
" ?context config:configContextFor ?property . \n" +
" ?context config:qualifiedBy ?range . \n" +
" ?context config:hasConfiguration ?configuration . \n" +
" ?configuration a config:ObjectPropertyDisplayConfig . \n" +
" OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" +
"}";
if(prop != null) {
log.debug("Checking " + prop.getURI() + " for additional properties");
queryStr = queryStr.replaceAll("For \\?property", "For <" + prop.getURI() + ">");
}
log.debug(queryStr);
Query q = QueryFactory.create(queryStr);
QueryExecution qe = QueryExecutionFactory.create(q, union);
WebappDaoFactory wadf = new WebappDaoFactoryJena(
ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, union));
ObjectPropertyDao opDao = wadf.getObjectPropertyDao();
try {
ResultSet rs = qe.execSelect();
while (rs.hasNext()) {
QuerySolution qsoln = rs.nextSolution();
log.debug(qsoln);
String opURI = (prop != null) ? prop.getURI() : qsoln.getResource(
"property").getURI();
Resource domainRes = qsoln.getResource("domain");
String domainURI = (domainRes != null) ? domainRes.getURI() : null;
String rangeURI = qsoln.getResource("range").getURI();
if (appropriateDomain(domainRes, subject, tboxModel)) {
additionalProps.add(opDao.getObjectPropertyByURIs(
opURI, domainURI, rangeURI));
}
}
} finally {
qe.close();
}
return additionalProps;
}
public static List<ObjectProperty> getAdditionalFauxSubpropertiesForList(List<ObjectProperty> propList, public static List<ObjectProperty> getAdditionalFauxSubpropertiesForList(List<ObjectProperty> propList,
Individual subject,
Model displayModel, Model displayModel,
Model tboxModel) { Model tboxModel) {
List<ObjectProperty> additionalProps = new ArrayList<ObjectProperty>(); List<ObjectProperty> additionalProps = new ArrayList<ObjectProperty>();
Model union = ModelFactory.createUnion(displayModel, tboxModel); Model union = ModelFactory.createUnion(displayModel, tboxModel);
String propQuery = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
"SELECT ?range ?label ?group ?customForm WHERE { \n" +
" ?p rdfs:subPropertyOf ?property . \n" +
" ?context config:configContextFor ?p . \n" +
" ?context config:qualifiedBy ?range . \n" +
" ?context config:hasConfiguration ?configuration . \n" +
" OPTIONAL { ?configuration config:propertyGroup ?group } \n" +
" OPTIONAL { ?configuration config:displayName ?label } \n" +
" OPTIONAL { ?configuration vitro:customEntryFormAnnot ?customForm } \n" +
"}";
for (ObjectProperty op : propList) {
log.debug("Checking " + op.getURI() + " for additional properties");
String queryStr = propQuery.replaceAll("\\?property", "<" + op.getURI() + ">");
log.debug(queryStr);
Query q = QueryFactory.create(queryStr);
QueryExecution qe = QueryExecutionFactory.create(q, union);
try {
ResultSet rs = qe.execSelect();
while (rs.hasNext()) {
ObjectProperty newProp = new ObjectProperty();
newProp.setURI(op.getURI());
QuerySolution qsoln = rs.nextSolution();
log.debug(qsoln);
Resource rangeRes = qsoln.getResource("range");
if (rangeRes != null) {
newProp.setRangeVClassURI(rangeRes.getURI());
} else {
newProp.setRangeVClassURI(op.getRangeVClassURI());
}
Resource groupRes = qsoln.getResource("group");
if (groupRes != null) {
newProp.setGroupURI(groupRes.getURI());
} else {
newProp.setGroupURI(op.getURI());
}
Literal labelLit = qsoln.getLiteral("label");
if (labelLit != null) {
newProp.setDomainPublic(labelLit.getLexicalForm());
} else {
newProp.setDomainPublic(op.getDomainPublic());
}
Literal customFormLit = qsoln.getLiteral("customForm");
if (customFormLit != null) {
newProp.setCustomEntryForm(customFormLit.getLexicalForm());
} else {
newProp.setCustomEntryForm(op.getCustomEntryForm());
}
additionalProps.add(newProp);
}
} finally {
qe.close();
}
}
for (ObjectProperty op : propList) {
additionalProps.addAll(getAdditionalFauxSubproperties(op, subject, tboxModel, union));
}
return additionalProps; return additionalProps;
} }
private static boolean appropriateDomain(Resource domainRes, Individual subject, Model tboxModel) {
if (subject == null || domainRes == null) {
return true;
}
for (VClass vclass : subject.getVClasses()) {
if ((vclass.getURI() != null) &&
((vclass.getURI().equals(domainRes.getURI()) ||
(tboxModel.contains(
ResourceFactory.createResource(
vclass.getURI()), RDFS.subClassOf, domainRes))))) {
return true;
}
}
return false;
}
} }

View file

@ -453,10 +453,13 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
String objectKey = vreq.getParameter("objectKey"); String objectKey = vreq.getParameter("objectKey");
statementDisplay.put(objectKey, objectUri); statementDisplay.put(objectKey, objectUri);
ObjectProperty predicate = new ObjectProperty();
predicate.setURI(predicateUri);
//Using object property statement template model here //Using object property statement template model here
ObjectPropertyStatementTemplateModel osm = new ObjectPropertyStatementTemplateModel( ObjectPropertyStatementTemplateModel osm = new ObjectPropertyStatementTemplateModel(
subjectUri, subjectUri,
predicateUri, predicate,
objectKey, objectKey,
statementDisplay, statementDisplay,
null, vreq); null, vreq);
@ -524,15 +527,23 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
if( subjectVClasses == null ) { if( subjectVClasses == null ) {
vclasses = wdf.getVClassDao().getAllVclasses(); vclasses = wdf.getVClassDao().getAllVclasses();
} else if (rangeClass != null) { } else if (rangeClass != null) {
List<VClass> rangeVClasses = new ArrayList<VClass>();
vclasses = new ArrayList<VClass>(); vclasses = new ArrayList<VClass>();
vclasses.add(rangeClass); if (!rangeClass.isUnion()) {
List<String> subURIs = wdf.getVClassDao().getSubClassURIs(rangeClass.getURI()); rangeVClasses.add(rangeClass);
for (String subClassURI : subURIs) { } else {
VClass subClass = wdf.getVClassDao().getVClassByURI(subClassURI); rangeVClasses.addAll(rangeClass.getUnionComponents());
if (subClass != null) { }
vclasses.add(subClass); for(VClass rangeVClass : rangeVClasses) {
} vclasses.add(rangeVClass);
} List<String> subURIs = wdf.getVClassDao().getSubClassURIs(rangeVClass.getURI());
for (String subClassURI : subURIs) {
VClass subClass = wdf.getVClassDao().getVClassByURI(subClassURI);
if (subClass != null) {
vclasses.add(subClass);
}
}
}
} else { } else {
//this hash is used to make sure there are no duplicates in the vclasses //this hash is used to make sure there are no duplicates in the vclasses
//a more elegant method may look at overriding equals/hashcode to enable a single hashset of VClass objects //a more elegant method may look at overriding equals/hashcode to enable a single hashset of VClass objects

View file

@ -117,7 +117,7 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel {
RequestActionConstants.SOME_URI); RequestActionConstants.SOME_URI);
AddObjectPropertyStatement aops = new AddObjectPropertyStatement( AddObjectPropertyStatement aops = new AddObjectPropertyStatement(
vreq.getJenaOntModel(), individual.getURI(), vreq.getJenaOntModel(), individual.getURI(),
RequestActionConstants.SOME_URI, RequestActionConstants.SOME_PREDICATE,
RequestActionConstants.SOME_URI); RequestActionConstants.SOME_URI);
return PolicyHelper.isAuthorizedForActions(vreq, new Actions(adps).or(aops)); return PolicyHelper.isAuthorizedForActions(vreq, new Actions(adps).or(aops));
} }

View file

@ -18,6 +18,7 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao; import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
@ -58,7 +59,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
postprocess(statementData); postprocess(statementData);
/* Collate the data */ /* Collate the data */
subclasses = collate(subjectUri, propertyUri, statementData, editing); subclasses = collate(subjectUri, op, statementData, editing);
for (SubclassTemplateModel subclass : subclasses) { for (SubclassTemplateModel subclass : subclasses) {
List<ObjectPropertyStatementTemplateModel> list = subclass.getStatements(); List<ObjectPropertyStatementTemplateModel> list = subclass.getStatements();
@ -188,7 +189,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
} }
// Collate the statements by subclass. // Collate the statements by subclass.
private List<SubclassTemplateModel> collate(String subjectUri, String propertyUri, private List<SubclassTemplateModel> collate(String subjectUri, ObjectProperty property,
List<Map<String, String>> statementData, boolean editing) { List<Map<String, String>> statementData, boolean editing) {
String objectKey = getObjectKey(); String objectKey = getObjectKey();
@ -218,7 +219,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
} }
listForThisSubclass.add(new ObjectPropertyStatementTemplateModel(subjectUri, listForThisSubclass.add(new ObjectPropertyStatementTemplateModel(subjectUri,
propertyUri, objectKey, map, getTemplateName(), vreq)); property, objectKey, map, getTemplateName(), vreq));
} }

View file

@ -13,12 +13,14 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPr
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
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; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.RdfLiteralHash; import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.RdfLiteralHash;
public class DataPropertyStatementTemplateModel extends PropertyStatementTemplateModel { public class DataPropertyStatementTemplateModel extends PropertyStatementTemplateModel {
private static final Log log = LogFactory.getLog(DataPropertyStatementTemplateModel.class); private static final Log log = LogFactory.getLog(DataPropertyStatementTemplateModel.class);
@ -28,9 +30,10 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
private final String templateName; private final String templateName;
//Extended to include vitro request to check for special parameters //Extended to include vitro request to check for special parameters
public DataPropertyStatementTemplateModel(String subjectUri, String propertyUri, Literal literal, public DataPropertyStatementTemplateModel(String subjectUri, Property property, Literal literal,
String templateName, VitroRequest vreq) { String templateName, VitroRequest vreq) {
super(subjectUri, propertyUri, vreq);
super(subjectUri, property, vreq);
this.literalValue = literal; this.literalValue = literal;
this.templateName = templateName; this.templateName = templateName;
@ -50,7 +53,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
ParamMap params = new ParamMap( ParamMap params = new ParamMap(
"subjectUri", subjectUri, "subjectUri", subjectUri,
"predicateUri", propertyUri, "predicateUri", property.getURI(),
"datapropKey", makeHash(dps), "datapropKey", makeHash(dps),
"cmd", "delete"); "cmd", "delete");
@ -63,7 +66,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
private String makeEditUrl() { private String makeEditUrl() {
// vitro:moniker is deprecated. We display existing data values so editors can // vitro:moniker is deprecated. We display existing data values so editors can
// move them to other properties and delete, but don't allow editing. // move them to other properties and delete, but don't allow editing.
if ( propertyUri.equals(VitroVocabulary.MONIKER) ) { if ( VitroVocabulary.MONIKER.equals(property.getURI()) ) {
return ""; return "";
} }
@ -76,7 +79,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
ParamMap params = new ParamMap( ParamMap params = new ParamMap(
"subjectUri", subjectUri, "subjectUri", subjectUri,
"predicateUri", propertyUri, "predicateUri", property.getURI(),
"datapropKey", makeHash(dps)); "datapropKey", makeHash(dps));
if ( deleteUrl.isEmpty() ) { if ( deleteUrl.isEmpty() ) {
@ -89,7 +92,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
} }
private DataPropertyStatement makeStatement() { private DataPropertyStatement makeStatement() {
DataPropertyStatement dps = new DataPropertyStatementImpl(subjectUri, propertyUri, literalValue.getLexicalForm()); DataPropertyStatement dps = new DataPropertyStatementImpl(subjectUri, property.getURI(), literalValue.getLexicalForm());
// Language and datatype are needed to get the correct hash value // Language and datatype are needed to get the correct hash value
dps.setLanguage(literalValue.getLanguage()); dps.setLanguage(literalValue.getLanguage());
dps.setDatatypeURI(literalValue.getDatatypeURI()); dps.setDatatypeURI(literalValue.getDatatypeURI());

View file

@ -88,7 +88,7 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
DataPropertyStatementDao dpDao = vreq.getWebappDaoFactory().getDataPropertyStatementDao(); DataPropertyStatementDao dpDao = vreq.getWebappDaoFactory().getDataPropertyStatementDao();
List<Literal> values = dpDao.getDataPropertyValuesForIndividualByProperty(subject, dp, queryString, constructQueries); List<Literal> values = dpDao.getDataPropertyValuesForIndividualByProperty(subject, dp, queryString, constructQueries);
for (Literal value : values) { for (Literal value : values) {
statements.add(new DataPropertyStatementTemplateModel(subjectUri, propertyUri, value, getTemplateName(), vreq)); statements.add(new DataPropertyStatementTemplateModel(subjectUri, dp, value, getTemplateName(), vreq));
} }
} else { } else {
log.debug("Data property " + getUri() + " is unpopulated."); log.debug("Data property " + getUri() + " is unpopulated.");

View file

@ -1,94 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
/**
* Sometimes we don't want to show an Add, Edit, or Delete link for a particular
* property, no matter who the user is.
*
* TODO These are hard-coded while we wait for the Application Ontology to be
* implemented.
*/
public class EditLinkSuppressor {
private static final Log log = LogFactory.getLog(EditLinkSuppressor.class);
private static final String CORE = "http://vivoweb.org/ontology/core#";
private static final String PUB_TO_AUTHORSHIP = core("informationResourceInAuthorship");
private static final String PERSON_TO_AUTHORSHIP = core("authorInAuthorship");
private static final String AUTHORSHIP_TO_PERSON = core("linkedAuthor");
private static final String AUTHORSHIP_TO_PUB = core("linkedInformationResource");
private static final String INDIVIDUAL_TO_WEBPAGE = core("webpage");
private static final String WEBPAGE_TO_INDIVIDUAL = core("webpageOf");
private static final String HAS_RESEARCH_AREA = core("hasResearchArea");
private static final String HAS_SUBJECT_AREA = core("hasSubjectArea");
private static final String RESEARCH_AREA_OF = core("researchAreaOf");
private static final String SUBJECT_AREA_FOR = core("subjectAreaFor");
private static String core(String localName) {
return CORE + localName;
}
private static final List<String> suppressAddLinksForThese = Arrays
.asList(new String[] { AUTHORSHIP_TO_PERSON, AUTHORSHIP_TO_PUB,
WEBPAGE_TO_INDIVIDUAL });
private static final List<String> suppressEditLinksForThese = Arrays
.asList(new String[] { WEBPAGE_TO_INDIVIDUAL });
private static final List<String> suppressDeleteLinksForThese = Arrays
.asList(new String[] { PUB_TO_AUTHORSHIP, PERSON_TO_AUTHORSHIP,
AUTHORSHIP_TO_PERSON, AUTHORSHIP_TO_PUB,
INDIVIDUAL_TO_WEBPAGE, WEBPAGE_TO_INDIVIDUAL,
HAS_RESEARCH_AREA, RESEARCH_AREA_OF, HAS_SUBJECT_AREA,
SUBJECT_AREA_FOR });
// TODO When we remove the hard-coding, vreq will allow us to find the
// application ontology model.
@SuppressWarnings("unused")
private final VitroRequest vreq;
public EditLinkSuppressor(VitroRequest vreq) {
this.vreq = vreq;
}
/**
* Should we suppress the Add link on this property?
*/
public boolean isAddLinkSuppressed(String propertyUri) {
if (propertyUri == null) {
log.error("Suppressing the add link on a null property.");
return true;
}
return suppressAddLinksForThese.contains(propertyUri);
}
/**
* Should we suppress the Edit link on this property?
*/
public boolean isEditLinkSuppressed(String propertyUri) {
if (propertyUri == null) {
log.error("Suppressing the edit link on a null property.");
return true;
}
return suppressEditLinksForThese.contains(propertyUri);
}
/**
* Should we suppress the Delete link on this property?
*/
public boolean isDeleteLinkSuppressed(String propertyUri) {
if (propertyUri == null) {
log.error("Suppressing the delete link on a null property.");
return true;
}
return suppressDeleteLinksForThese.contains(propertyUri);
}
}

View file

@ -20,6 +20,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance; import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao;
@ -74,12 +75,12 @@ public class GroupedPropertyList extends BaseTemplateModel {
List<ObjectProperty> populatedObjectPropertyList = subject List<ObjectProperty> populatedObjectPropertyList = subject
.getPopulatedObjectPropertyList(); .getPopulatedObjectPropertyList();
List<ObjectProperty> additions = ApplicationConfigurationOntologyUtils Collection<ObjectProperty> additions = ApplicationConfigurationOntologyUtils
.getAdditionalFauxSubpropertiesForList( .getAdditionalFauxSubpropertiesForList(
populatedObjectPropertyList, vreq); populatedObjectPropertyList, subject, vreq);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
for (ObjectProperty t : additions) { for (ObjectProperty t : additions) {
log.debug(t.getDomainPublic() + " " + t.getGroupURI()); log.debug(t.getDomainPublic() + " " + t.getGroupURI() + " domain " + t.getDomainVClassURI());
} }
log.debug("Added " + additions.size() + log.debug("Added " + additions.size() +
" properties due to application configuration ontology"); " properties due to application configuration ontology");
@ -88,7 +89,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
populatedObjectPropertyList.addAll(additions); populatedObjectPropertyList.addAll(additions);
propertyList.addAll(populatedObjectPropertyList); propertyList.addAll(populatedObjectPropertyList);
// If editing this page, merge in object properties applicable to the individual that are currently // If editing this page, merge in object properties applicable to the individual that are currently
// unpopulated, so the properties are displayed to allow statements to be added to these properties. // unpopulated, so the properties are displayed to allow statements to be added to these properties.
// RY In future, we should limit this to properties that the user has permission to add properties to. // RY In future, we should limit this to properties that the user has permission to add properties to.
@ -175,7 +176,13 @@ public class GroupedPropertyList extends BaseTemplateModel {
// There is no ObjectPropertyDao.getAllPossibleObjectPropertiesForIndividual() parallel to // There is no ObjectPropertyDao.getAllPossibleObjectPropertiesForIndividual() parallel to
// DataPropertyDao.getAllPossibleDatapropsForIndividual(). The comparable method for object properties // DataPropertyDao.getAllPossibleDatapropsForIndividual(). The comparable method for object properties
// is defined using PropertyInstance rather than ObjectProperty. // is defined using PropertyInstance rather than ObjectProperty.
PropertyInstanceDao piDao = wdf.getPropertyInstanceDao();
// Getting WebappDaoFactory from the session because we can't have the filtering
// that gets applied to the request. This breaks blank node structures in the
// restrictions that determine applicable properties.
WebappDaoFactory wadf = ModelAccess.on(vreq.getSession().getServletContext()).getWebappDaoFactory();
PropertyInstanceDao piDao = wadf.getPropertyInstanceDao();
Collection<PropertyInstance> allPropInstColl = piDao Collection<PropertyInstance> allPropInstColl = piDao
.getAllPossiblePropInstForIndividual(subject.getURI()); .getAllPossiblePropInstForIndividual(subject.getURI());
if (allPropInstColl != null) { if (allPropInstColl != null) {
@ -183,7 +190,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
if (pi != null) { if (pi != null) {
if (!alreadyOnObjectPropertyList( if (!alreadyOnObjectPropertyList(
populatedObjectPropertyList, pi)) { populatedObjectPropertyList, pi)) {
addObjectPropertyToPropertyList(pi.getPropertyURI(), pi.getRangeClassURI(), addObjectPropertyToPropertyList(pi.getPropertyURI(), pi.getDomainClassURI(), pi.getRangeClassURI(),
propertyList); propertyList);
} }
} else { } else {
@ -199,7 +206,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
// constitute a special case (i.e., included in piDao.getAllPossiblePropInstForIndividual()). // constitute a special case (i.e., included in piDao.getAllPossiblePropInstForIndividual()).
for (String propertyUri : VITRO_PROPS_TO_ADD_TO_LIST) { for (String propertyUri : VITRO_PROPS_TO_ADD_TO_LIST) {
if (!alreadyOnPropertyList(propertyList, propertyUri)) { if (!alreadyOnPropertyList(propertyList, propertyUri)) {
addObjectPropertyToPropertyList(propertyUri, null, propertyList); addObjectPropertyToPropertyList(propertyUri, null, null, propertyList);
} }
} }
} }
@ -211,16 +218,29 @@ public class GroupedPropertyList extends BaseTemplateModel {
} }
for (ObjectProperty op : opList) { for (ObjectProperty op : opList) {
if (op.getURI() != null && op.getURI().equals(pi.getPropertyURI())) { if (op.getURI() != null && op.getURI().equals(pi.getPropertyURI())) {
return true; if(op.getDomainVClassURI() == null) {
if(pi.getDomainClassURI() == null) {
return true;
}
} else if (op.getDomainVClassURI().equals(pi.getDomainClassURI())) {
return true;
}
if(op.getRangeVClassURI() == null) {
if (pi.getDomainClassURI() == null) {
return true;
}
} else if (op.getRangeVClassURI().equals(pi.getRangeClassURI())) {
return true;
}
} }
} }
return false; return false;
} }
private void addObjectPropertyToPropertyList(String propertyUri, String rangeUri, private void addObjectPropertyToPropertyList(String propertyUri, String domainUri, String rangeUri,
List<Property> propertyList) { List<Property> propertyList) {
ObjectPropertyDao opDao = wdf.getObjectPropertyDao(); ObjectPropertyDao opDao = wdf.getObjectPropertyDao();
ObjectProperty op = opDao.getObjectPropertyByURIAndRangeURI(propertyUri, rangeUri); ObjectProperty op = opDao.getObjectPropertyByURIs(propertyUri, domainUri, rangeUri);
if (op == null) { if (op == null) {
log.error("ObjectProperty op returned null from opDao.getObjectPropertyByURI(" + propertyUri + ")"); log.error("ObjectProperty op returned null from opDao.getObjectPropertyByURI(" + propertyUri + ")");
} else if (op.getURI() == null) { } else if (op.getURI() == null) {
@ -457,11 +477,16 @@ public class GroupedPropertyList extends BaseTemplateModel {
} }
public PropertyTemplateModel pullProperty(String propertyUri) { public PropertyTemplateModel pullProperty(String propertyUri) {
return pullProperty(propertyUri, null);
}
public PropertyTemplateModel pullProperty(String propertyUri, String rangeUri) {
for (PropertyGroupTemplateModel pgtm : groups) { for (PropertyGroupTemplateModel pgtm : groups) {
List<PropertyTemplateModel> properties = pgtm.getProperties(); List<PropertyTemplateModel> properties = pgtm.getProperties();
for (PropertyTemplateModel ptm : properties) { for (PropertyTemplateModel ptm : properties) {
if (propertyUri.equals(ptm.getUri())) { if (propertyUri.equals(ptm.getUri()) &&
(rangeUri == null || rangeUri.equals(ptm.getRangeUri()))) {
// Remove the property from the group. // Remove the property from the group.
// NB Works with a for-each loop instead of an iterator, // NB Works with a for-each loop instead of an iterator,
// since iteration doesn't continue after the remove. // since iteration doesn't continue after the remove.

View file

@ -14,6 +14,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl; import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatementImpl;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
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; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
@ -37,7 +38,7 @@ public class NameStatementTemplateModel extends PropertyStatementTemplateModel {
private final String editUrl; private final String editUrl;
NameStatementTemplateModel(String subjectUri, VitroRequest vreq) { NameStatementTemplateModel(String subjectUri, VitroRequest vreq) {
super(subjectUri, VitroVocabulary.LABEL, vreq); super(subjectUri, new Property(VitroVocabulary.LABEL), vreq);
// NIHVIVO-2466 Use the same methods to get the label that are used elsewhere in the // NIHVIVO-2466 Use the same methods to get the label that are used elsewhere in the
// application, to guarantee consistent results for individuals with multiple labels // application, to guarantee consistent results for individuals with multiple labels
@ -69,7 +70,7 @@ public class NameStatementTemplateModel extends PropertyStatementTemplateModel {
ParamMap params = new ParamMap( ParamMap params = new ParamMap(
"subjectUri", subjectUri, "subjectUri", subjectUri,
"predicateUri", propertyUri, "predicateUri", property.getURI(),
"datapropKey", makeHash(dps), "datapropKey", makeHash(dps),
"deleteProhibited", "prohibited"); "deleteProhibited", "prohibited");
@ -80,7 +81,7 @@ public class NameStatementTemplateModel extends PropertyStatementTemplateModel {
private DataPropertyStatement makeStatement(Literal literalValue) { private DataPropertyStatement makeStatement(Literal literalValue) {
DataPropertyStatement dps = new DataPropertyStatementImpl(subjectUri, DataPropertyStatement dps = new DataPropertyStatementImpl(subjectUri,
propertyUri, literalValue.getLexicalForm()); property.getURI(), literalValue.getLexicalForm());
// Language and datatype are needed to get the correct hash value // Language and datatype are needed to get the correct hash value
dps.setLanguage(literalValue.getLanguage()); dps.setLanguage(literalValue.getLanguage());
dps.setDatatypeURI(literalValue.getDatatypeURI()); dps.setDatatypeURI(literalValue.getDatatypeURI());

View file

@ -13,8 +13,10 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl; import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatementImpl;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
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; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
@ -31,9 +33,9 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl
private final String editUrl; private final String editUrl;
private final String deleteUrl; private final String deleteUrl;
public ObjectPropertyStatementTemplateModel(String subjectUri, String propertyUri, String objectKey, public ObjectPropertyStatementTemplateModel(String subjectUri, ObjectProperty predicate, String objectKey,
Map<String, String> data, String templateName, VitroRequest vreq) { Map<String, String> data, String templateName, VitroRequest vreq) {
super(subjectUri, propertyUri, vreq); super(subjectUri, predicate, vreq);
this.data = Collections.unmodifiableMap(new HashMap<String, String>(data)); this.data = Collections.unmodifiableMap(new HashMap<String, String>(data));
this.objectUri = data.get(objectKey); this.objectUri = data.get(objectKey);
@ -41,7 +43,8 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl
//to keep track of later //to keep track of later
this.objectKey = objectKey; this.objectKey = objectKey;
ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(subjectUri, propertyUri, objectUri); ObjectPropertyStatement ops = new ObjectPropertyStatementImpl(subjectUri, property.getURI(), objectUri);
ops.setProperty(predicate);
// Do delete url first, since it is used in building edit url // Do delete url first, since it is used in building edit url
this.deleteUrl = makeDeleteUrl(); this.deleteUrl = makeDeleteUrl();
@ -50,24 +53,24 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl
private String makeDeleteUrl() { private String makeDeleteUrl() {
// Is the delete link suppressed for this property? // Is the delete link suppressed for this property?
if (new EditLinkSuppressor(vreq).isDeleteLinkSuppressed(propertyUri)) { if (property.isDeleteLinkSuppressed()) {
return ""; return "";
} }
// Determine whether the statement can be deleted // Determine whether the statement can be deleted
RequestedAction action = new DropObjectPropertyStatement( RequestedAction action = new DropObjectPropertyStatement(
vreq.getJenaOntModel(), subjectUri, propertyUri, objectUri); vreq.getJenaOntModel(), subjectUri, property, objectUri);
if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) { if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) {
return ""; return "";
} }
if (propertyUri.equals(VitroVocabulary.IND_MAIN_IMAGE)) { if (VitroVocabulary.IND_MAIN_IMAGE.equals(property.getURI())) {
return ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "delete"); return ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "delete");
} }
ParamMap params = new ParamMap( ParamMap params = new ParamMap(
"subjectUri", subjectUri, "subjectUri", subjectUri,
"predicateUri", propertyUri, "predicateUri", property.getURI(),
"objectUri", objectUri, "objectUri", objectUri,
"cmd", "delete", "cmd", "delete",
"objectKey", objectKey); "objectKey", objectKey);
@ -92,7 +95,7 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl
private String makeEditUrl(ObjectPropertyStatement ops) { private String makeEditUrl(ObjectPropertyStatement ops) {
// Is the edit link suppressed for this property? // Is the edit link suppressed for this property?
if (new EditLinkSuppressor(vreq).isEditLinkSuppressed(propertyUri)) { if (property.isEditLinkSuppressed()) {
return ""; return "";
} }
@ -102,19 +105,26 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl
return ""; return "";
} }
if (propertyUri.equals(VitroVocabulary.IND_MAIN_IMAGE)) { if (VitroVocabulary.IND_MAIN_IMAGE.equals(property.getURI())) {
return ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "edit"); return ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "edit");
} }
ParamMap params = new ParamMap( ParamMap params = new ParamMap(
"subjectUri", subjectUri, "subjectUri", subjectUri,
"predicateUri", propertyUri, "predicateUri", property.getURI(),
"objectUri", objectUri); "objectUri", objectUri);
if ( deleteUrl.isEmpty() ) { if ( deleteUrl.isEmpty() ) {
params.put("deleteProhibited", "prohibited"); params.put("deleteProhibited", "prohibited");
} }
if (ops.getProperty()!= null && ops.getProperty().getDomainVClassURI() != null) {
params.put("domainUri", ops.getProperty().getDomainVClassURI());
}
if (ops.getProperty()!= null && ops.getProperty().getRangeVClassURI() != null) {
params.put("rangeUri", ops.getProperty().getRangeVClassURI());
}
params.putAll(UrlBuilder.getModelParams(vreq)); params.putAll(UrlBuilder.getModelParams(vreq));
return UrlBuilder.getUrl(EDIT_PATH, params); return UrlBuilder.getUrl(EDIT_PATH, params);

View file

@ -80,7 +80,6 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
private PropertyListConfig config; private PropertyListConfig config;
private String objectKey; private String objectKey;
private String sortDirection; private String sortDirection;
private String rangeURI;
ObjectPropertyTemplateModel(ObjectProperty op, Individual subject, VitroRequest vreq, ObjectPropertyTemplateModel(ObjectProperty op, Individual subject, VitroRequest vreq,
boolean editing) boolean editing)
@ -90,7 +89,8 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
setName(op.getDomainPublic()); setName(op.getDomainPublic());
sortDirection = op.getDomainEntitySortDirection(); sortDirection = op.getDomainEntitySortDirection();
rangeURI = op.getRangeVClassURI(); domainUri = op.getDomainVClassURI();
rangeUri = op.getRangeVClassURI();
// Get the config for this object property // Get the config for this object property
try { try {
@ -110,13 +110,13 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
protected void setAddUrl(Property property) { protected void setAddUrl(Property property) {
// Is the add link suppressed for this property? // Is the add link suppressed for this property?
if (new EditLinkSuppressor(vreq).isAddLinkSuppressed(propertyUri)) { if (property.isAddLinkSuppressed()) {
return; return;
} }
// Determine whether a new statement can be added // Determine whether a new statement can be added
RequestedAction action = new AddObjectPropertyStatement( RequestedAction action = new AddObjectPropertyStatement(
vreq.getJenaOntModel(), subjectUri, propertyUri, vreq.getJenaOntModel(), subjectUri, property,
RequestActionConstants.SOME_URI); RequestActionConstants.SOME_URI);
if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) { if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) {
return; return;
@ -133,6 +133,9 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
"subjectUri", subjectUri, "subjectUri", subjectUri,
"predicateUri", propertyUri); "predicateUri", propertyUri);
if (domainUri != null) {
params.put("domainUri", domainUri);
}
if (rangeUri != null) { if (rangeUri != null) {
params.put("rangeUri", rangeUri); params.put("rangeUri", rangeUri);
} }
@ -157,7 +160,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
protected List<Map<String, String>> getStatementData() { protected List<Map<String, String>> getStatementData() {
ObjectPropertyStatementDao opDao = vreq.getWebappDaoFactory().getObjectPropertyStatementDao(); ObjectPropertyStatementDao opDao = vreq.getWebappDaoFactory().getObjectPropertyStatementDao();
return opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, objectKey, rangeURI, getSelectQuery(), getConstructQueries(), sortDirection); return opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, objectKey, domainUri, rangeUri, getSelectQuery(), getConstructQueries(), sortDirection);
} }
protected abstract boolean isEmpty(); protected abstract boolean isEmpty();

View file

@ -36,8 +36,13 @@ public class PropertyGroupTemplateModel extends BaseTemplateModel {
properties = new ArrayList<PropertyTemplateModel>(propertyList.size()); properties = new ArrayList<PropertyTemplateModel>(propertyList.size());
for (Property p : propertyList) { for (Property p : propertyList) {
if (p instanceof ObjectProperty) { if (p instanceof ObjectProperty) {
ObjectProperty op = (ObjectProperty)p; ObjectProperty op = (ObjectProperty) p;
properties.add(ObjectPropertyTemplateModel.getObjectPropertyTemplateModel(op, subject, vreq, editing, populatedObjectPropertyList)); ObjectPropertyTemplateModel tm = ObjectPropertyTemplateModel.getObjectPropertyTemplateModel(
op, subject, vreq, editing, populatedObjectPropertyList);
if (!tm.isEmpty() || (editing && !tm.getAddUrl().isEmpty())) {
properties.add(tm);
}
} else { } else {
properties.add(new DataPropertyTemplateModel((DataProperty)p, subject, vreq, editing, populatedDataPropertyList)); properties.add(new DataPropertyTemplateModel((DataProperty)p, subject, vreq, editing, populatedDataPropertyList));
} }

View file

@ -2,6 +2,7 @@
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual; package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
@ -10,12 +11,12 @@ public abstract class PropertyStatementTemplateModel extends BaseTemplateModel {
protected final VitroRequest vreq; protected final VitroRequest vreq;
protected final String subjectUri; protected final String subjectUri;
protected final String propertyUri; protected final Property property;
PropertyStatementTemplateModel(String subjectUri, String propertyUri, VitroRequest vreq) { PropertyStatementTemplateModel(String subjectUri, Property property, VitroRequest vreq) {
this.vreq = vreq; this.vreq = vreq;
this.subjectUri = subjectUri; this.subjectUri = subjectUri;
this.propertyUri = propertyUri; this.property = property;
} }
/* Template properties */ /* Template properties */

View file

@ -28,7 +28,10 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
protected final VitroRequest vreq; protected final VitroRequest vreq;
protected final String subjectUri; protected final String subjectUri;
protected final Property property;
protected final String propertyUri; protected final String propertyUri;
protected String domainUri;
protected String rangeUri;
private final String localName; private final String localName;
protected Map<String, Object> verboseDisplay; protected Map<String, Object> verboseDisplay;
@ -41,6 +44,7 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
PropertyTemplateModel(Property property, Individual subject, VitroRequest vreq) { PropertyTemplateModel(Property property, Individual subject, VitroRequest vreq) {
this.vreq = vreq; this.vreq = vreq;
subjectUri = subject.getURI(); subjectUri = subject.getURI();
this.property = property;
propertyUri = property.getURI(); propertyUri = property.getURI();
localName = property.getLocalName(); localName = property.getLocalName();
setVerboseDisplayValues(property); setVerboseDisplayValues(property);
@ -121,6 +125,10 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
return propertyUri; return propertyUri;
} }
public String getRangeUri() {
return rangeUri;
}
public String getAddUrl() { public String getAddUrl() {
//log.info("addUrl=" + addUrl); //log.info("addUrl=" + addUrl);
return (addUrl != null) ? addUrl : ""; return (addUrl != null) ? addUrl : "";

View file

@ -41,7 +41,7 @@ public class UncollatedObjectPropertyTemplateModel extends ObjectPropertyTemplat
String objectKey = getObjectKey(); String objectKey = getObjectKey();
for (Map<String, String> map : statementData) { for (Map<String, String> map : statementData) {
statements.add(new ObjectPropertyStatementTemplateModel(subjectUri, statements.add(new ObjectPropertyStatementTemplateModel(subjectUri,
propertyUri, objectKey, map, getTemplateName(), vreq)); op, objectKey, map, getTemplateName(), vreq));
} }
postprocessStatementList(statements); postprocessStatementList(statements);

View file

@ -42,6 +42,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObject
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class SelfEditingPolicyTest extends AbstractTestClass { public class SelfEditingPolicyTest extends AbstractTestClass {
@ -55,8 +56,8 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
private static final String UNSAFE_RESOURCE = UNSAFE_NS private static final String UNSAFE_RESOURCE = UNSAFE_NS
+ "otherIndividual99999"; + "otherIndividual99999";
private static final String SAFE_PREDICATE = SAFE_NS + "hasHairStyle"; private static final Property SAFE_PREDICATE = new Property(SAFE_NS + "hasHairStyle");
private static final String UNSAFE_PREDICATE = UNSAFE_NS + "hasSuperPowers"; private static final Property UNSAFE_PREDICATE = new Property(UNSAFE_NS + "hasSuperPowers");
private ServletContextStub ctx; private ServletContextStub ctx;
@ -95,19 +96,19 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
PropertyRestrictionPolicyHelper.setBean(ctx, prph); PropertyRestrictionPolicyHelper.setBean(ctx, prph);
whatToAuth = new AddObjectPropertyStatement(ontModel, SELFEDITOR_URI, whatToAuth = new AddObjectPropertyStatement(ontModel, SELFEDITOR_URI,
"http://mannlib.cornell.edu/bad#prp234", SAFE_RESOURCE); new Property("http://mannlib.cornell.edu/bad#prp234"), SAFE_RESOURCE);
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new AddObjectPropertyStatement(ontModel, SAFE_RESOURCE, whatToAuth = new AddObjectPropertyStatement(ontModel, SAFE_RESOURCE,
"http://mannlib.cornell.edu/bad#prp234", SELFEDITOR_URI); new Property("http://mannlib.cornell.edu/bad#prp234"), SELFEDITOR_URI);
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new AddObjectPropertyStatement(ontModel, SELFEDITOR_URI, whatToAuth = new AddObjectPropertyStatement(ontModel, SELFEDITOR_URI,
"http://mannlib.cornell.edu/bad#prp999", SAFE_RESOURCE); new Property("http://mannlib.cornell.edu/bad#prp999"), SAFE_RESOURCE);
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new AddObjectPropertyStatement(ontModel, SAFE_RESOURCE, whatToAuth = new AddObjectPropertyStatement(ontModel, SAFE_RESOURCE,
"http://mannlib.cornell.edu/bad#prp999", SELFEDITOR_URI); new Property("http://mannlib.cornell.edu/bad#prp999"), SELFEDITOR_URI);
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new AddObjectPropertyStatement(ontModel, SAFE_RESOURCE, whatToAuth = new AddObjectPropertyStatement(ontModel, SAFE_RESOURCE,
@ -132,11 +133,11 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new AddDataPropertyStatement(ontModel, SELFEDITOR_URI, whatToAuth = new AddDataPropertyStatement(ontModel, SELFEDITOR_URI,
SAFE_PREDICATE); SAFE_PREDICATE.getURI());
assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth)); assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new AddDataPropertyStatement(ontModel, SELFEDITOR_URI, whatToAuth = new AddDataPropertyStatement(ontModel, SELFEDITOR_URI,
UNSAFE_PREDICATE); UNSAFE_PREDICATE.getURI());
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
} }
@ -218,16 +219,16 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
// //
@Test @Test
public void testVisitIdentifierBundleEditDataPropStmt() { public void testVisitIdentifierBundleEditDataPropStmt() {
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI,SAFE_PREDICATE); whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI,SAFE_PREDICATE.getURI());
assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth)); assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, UNSAFE_PREDICATE); whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, UNSAFE_PREDICATE.getURI());
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new EditDataPropertyStatement(ontModel, UNSAFE_RESOURCE, SAFE_PREDICATE); whatToAuth = new EditDataPropertyStatement(ontModel, UNSAFE_RESOURCE, SAFE_PREDICATE.getURI());
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE); whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE.getURI());
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
} }
@ -287,7 +288,7 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
public void twoSEIsFindDataPropertySubject() { public void twoSEIsFindDataPropertySubject() {
setUpTwoSEIs(); setUpTwoSEIs();
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, SAFE_PREDICATE); whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, SAFE_PREDICATE.getURI());
assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth)); assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth));
} }
@ -295,7 +296,7 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
public void twoSEIsDontFindInDataProperty() { public void twoSEIsDontFindInDataProperty() {
setUpTwoSEIs(); setUpTwoSEIs();
whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE); whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE.getURI());
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth)); assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
} }

View file

@ -32,6 +32,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditDataPr
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl; import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class SelfEditingPolicy_2_Test extends AbstractTestClass { public class SelfEditingPolicy_2_Test extends AbstractTestClass {
@ -123,7 +124,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass {
@Test @Test
public void nullIdentifierBundle() { public void nullIdentifierBundle() {
AddObjectPropertyStatement whatToAuth = new AddObjectPropertyStatement( AddObjectPropertyStatement whatToAuth = new AddObjectPropertyStatement(
ontModel, SELFEDITOR_URI, SAFE_PREDICATE, SAFE_RESOURCE); ontModel, SELFEDITOR_URI, new Property(SAFE_PREDICATE), SAFE_RESOURCE);
PolicyDecision dec = policy.isAuthorized(null, whatToAuth); PolicyDecision dec = policy.isAuthorized(null, whatToAuth);
Assert.assertNotNull(dec); Assert.assertNotNull(dec);
Assert.assertEquals(Authorization.INCONCLUSIVE, dec.getAuthorized()); Assert.assertEquals(Authorization.INCONCLUSIVE, dec.getAuthorized());
@ -277,7 +278,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass {
private void assertAddObjectPropStmt(String uriOfSub, String uriOfPred, private void assertAddObjectPropStmt(String uriOfSub, String uriOfPred,
String uriOfObj, Authorization expectedAuthorization) { String uriOfObj, Authorization expectedAuthorization) {
AddObjectPropertyStatement whatToAuth = new AddObjectPropertyStatement( AddObjectPropertyStatement whatToAuth = new AddObjectPropertyStatement(
ontModel, uriOfSub, uriOfPred, uriOfObj); ontModel, uriOfSub, new Property(uriOfPred), uriOfObj);
PolicyDecision dec = policy.isAuthorized(ids, whatToAuth); PolicyDecision dec = policy.isAuthorized(ids, whatToAuth);
log.debug(dec); log.debug(dec);
Assert.assertNotNull(dec); Assert.assertNotNull(dec);
@ -291,7 +292,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass {
private void assertEditObjPropStmt(String uriOfSub, String uriOfPred, private void assertEditObjPropStmt(String uriOfSub, String uriOfPred,
String uriOfObj, Authorization expectedAuthorization) { String uriOfObj, Authorization expectedAuthorization) {
EditObjectPropertyStatement whatToAuth = new EditObjectPropertyStatement( EditObjectPropertyStatement whatToAuth = new EditObjectPropertyStatement(
ontModel, uriOfSub, uriOfPred, uriOfObj); ontModel, uriOfSub, new Property(uriOfPred), uriOfObj);
PolicyDecision dec = policy.isAuthorized(ids, whatToAuth); PolicyDecision dec = policy.isAuthorized(ids, whatToAuth);
log.debug(dec); log.debug(dec);
Assert.assertNotNull(dec); Assert.assertNotNull(dec);

View file

@ -18,7 +18,6 @@ import java.util.Map;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Level;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -27,6 +26,8 @@ import com.hp.hpl.jena.ontology.OntModelSpec;
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.Property;
import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.sdb.util.Pair;
import com.hp.hpl.jena.vocabulary.OWL;
import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean;
@ -58,17 +59,25 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
// setLoggerLevel(PropertyRestrictionPolicyHelper.class, Level.DEBUG); // setLoggerLevel(PropertyRestrictionPolicyHelper.class, Level.DEBUG);
} }
private void mapPut(String predicateURI, RoleLevel roleLevel,
Map<Pair<String, Pair<String,String>>, RoleLevel> map) {
map.put(new Pair<String, Pair<String,String>>(
OWL.Thing.getURI(), new Pair<String, String>(
predicateURI, OWL.Thing.getURI())), roleLevel);
}
@Before @Before
public void createTheBean() { public void createTheBean() {
Map<String, RoleLevel> displayLevels = new HashMap<String, BaseResourceBean.RoleLevel>(); Map<Pair<String, Pair<String,String>>, RoleLevel> displayLevels =
displayLevels.put("http://predicates#display_self", SELF); new HashMap<Pair<String, Pair<String,String>>, RoleLevel>();
displayLevels.put("http://predicates#display_curator", CURATOR); mapPut("http://predicates#display_curator", CURATOR, displayLevels);
displayLevels.put("http://predicates#display_hidden", NOBODY); mapPut("http://predicates#display_hidden", NOBODY, displayLevels);
Map<String, RoleLevel> modifyLevels = new HashMap<String, BaseResourceBean.RoleLevel>(); Map<Pair<String, Pair<String,String>>, RoleLevel> modifyLevels =
modifyLevels.put("http://predicates#modify_self", SELF); new HashMap<Pair<String, Pair<String,String>>, RoleLevel>();
modifyLevels.put("http://predicates#modify_curator", CURATOR); mapPut("http://predicates#modify_self", SELF, modifyLevels);
modifyLevels.put("http://predicates#modify_hidden", NOBODY); mapPut("http://predicates#modify_curator", CURATOR, modifyLevels);
mapPut("http://predicates#modify_hidden", NOBODY, modifyLevels);
bean = new PropertyRestrictionPolicyHelper( bean = new PropertyRestrictionPolicyHelper(
Arrays.asList(PROHIBITED_NAMESPACES), Arrays.asList(PROHIBITED_NAMESPACES),
@ -125,68 +134,75 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
@Test @Test
public void displayPredicateNoRestriction() { public void displayPredicateNoRestriction() {
assertEquals("displayPredicate: open", true, assertEquals("displayPredicate: open", true,
bean.canDisplayPredicate("http://predicates#open", PUBLIC)); bean.canDisplayPredicate(createVitroProperty(
"http://predicates#open"), PUBLIC));
} }
@Test @Test
public void displayPredicateRestrictionLower() { public void displayPredicateRestrictionLower() {
assertEquals("displayPredicate: lower restriction", true, assertEquals("displayPredicate: lower restriction", true,
bean.canDisplayPredicate("http://predicates#display_self", bean.canDisplayPredicate(createVitroProperty(
CURATOR)); "http://predicates#display_self"), CURATOR));
} }
@Test @Test
public void displayPredicateRestrictionEqual() { public void displayPredicateRestrictionEqual() {
assertEquals("displayPredicate: equal restriction", true, assertEquals("displayPredicate: equal restriction", true,
bean.canDisplayPredicate("http://predicates#display_curator", bean.canDisplayPredicate(createVitroProperty(
CURATOR)); "http://predicates#display_curator"), CURATOR));
} }
@Test @Test
public void displayPredicateRestrictionHigher() { public void displayPredicateRestrictionHigher() {
assertEquals("displayPredicate: higher restriction", false, assertEquals("displayPredicate: higher restriction", false,
bean.canDisplayPredicate("http://predicates#display_hidden", bean.canDisplayPredicate(createVitroProperty(
CURATOR)); "http://predicates#display_hidden"), CURATOR));
} }
@Test @Test
public void modifyPredicateNoRestriction() { public void modifyPredicateNoRestriction() {
assertEquals("modifyPredicate: open", true, assertEquals("modifyPredicate: open", true,
bean.canModifyPredicate("http://predicates#open", PUBLIC)); bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property(
"http://predicates#open"), PUBLIC));
} }
@Test @Test
public void modifyPredicateRestrictionLower() { public void modifyPredicateRestrictionLower() {
assertEquals("modifyPredicate: lower restriction", true, assertEquals("modifyPredicate: lower restriction", true,
bean.canModifyPredicate("http://predicates#modify_self", bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property(
"http://predicates#modify_self"),
CURATOR)); CURATOR));
} }
@Test @Test
public void modifyPredicateRestrictionEqual() { public void modifyPredicateRestrictionEqual() {
assertEquals("modifyPredicate: equal restriction", true, assertEquals("modifyPredicate: equal restriction", true,
bean.canModifyPredicate("http://predicates#modify_curator", bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property(
"http://predicates#modify_curator"),
CURATOR)); CURATOR));
} }
@Test @Test
public void modifyPredicateRestrictionHigher() { public void modifyPredicateRestrictionHigher() {
assertEquals("modifyPredicate: higher restriction", false, assertEquals("modifyPredicate: higher restriction", false,
bean.canModifyPredicate("http://predicates#modify_hidden", bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property(
"http://predicates#modify_hidden"),
CURATOR)); CURATOR));
} }
@Test @Test
public void modifyPredicateProhibitedNamespace() { public void modifyPredicateProhibitedNamespace() {
assertEquals("modifyPredicate: prohibited namespace", false, assertEquals("modifyPredicate: prohibited namespace", false,
bean.canModifyPredicate(PROHIBITED_NAMESPACES[0] + "randoom", bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property(
PROHIBITED_NAMESPACES[0] + "randoom"),
DB_ADMIN)); DB_ADMIN));
} }
@Test @Test
public void modifyPredicatePermittedException() { public void modifyPredicatePermittedException() {
assertEquals("modifyPredicate: permitted exception", true, assertEquals("modifyPredicate: permitted exception", true,
bean.canModifyPredicate(PERMITTED_EXCEPTIONS[0], DB_ADMIN)); bean.canModifyPredicate(new edu.cornell.mannlib.vitro.webapp.beans.Property(
PERMITTED_EXCEPTIONS[0]), DB_ADMIN));
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -195,9 +211,10 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
@Test @Test
public void buildDisplayThresholds() { public void buildDisplayThresholds() {
Map<String, RoleLevel> expectedMap = new HashMap<String, BaseResourceBean.RoleLevel>(); Map<Pair<String, Pair<String,String>>, BaseResourceBean.RoleLevel> expectedMap =
expectedMap.put("http://thresholds#display_public", PUBLIC); new HashMap<Pair<String, Pair<String,String>>, BaseResourceBean.RoleLevel>();
expectedMap.put("http://thresholds#display_hidden", NOBODY); mapPut("http://thresholds#display_public", PUBLIC, expectedMap);
mapPut("http://thresholds#display_hidden", NOBODY, expectedMap);
Map<String, RoleLevel> actualMap = populateThresholdMap(PROPERTY_DISPLAY_THRESHOLD); Map<String, RoleLevel> actualMap = populateThresholdMap(PROPERTY_DISPLAY_THRESHOLD);
assertEquals("display thresholds", expectedMap, actualMap); assertEquals("display thresholds", expectedMap, actualMap);
@ -205,9 +222,10 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
@Test @Test
public void buildModifyThresholds() { public void buildModifyThresholds() {
Map<String, RoleLevel> expectedMap = new HashMap<String, BaseResourceBean.RoleLevel>(); Map<Pair<String, Pair<String,String>>, BaseResourceBean.RoleLevel> expectedMap =
expectedMap.put("http://thresholds#modify_editor", EDITOR); new HashMap<Pair<String, Pair<String,String>>, BaseResourceBean.RoleLevel>();
expectedMap.put("http://thresholds#modify_curator", CURATOR); mapPut("http://thresholds#modify_editor", EDITOR, expectedMap);
mapPut("http://thresholds#modify_curator", CURATOR, expectedMap);
Map<String, RoleLevel> actualMap = populateThresholdMap(PROPERTY_MODIFY_THRESHOLD); Map<String, RoleLevel> actualMap = populateThresholdMap(PROPERTY_MODIFY_THRESHOLD);
assertEquals("modify thresholds", expectedMap, actualMap); assertEquals("modify thresholds", expectedMap, actualMap);
@ -244,4 +262,9 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
model.add(subject, property, object); model.add(subject, property, object);
} }
} }
private edu.cornell.mannlib.vitro.webapp.beans.Property createVitroProperty(
String propertyURI) {
return new edu.cornell.mannlib.vitro.webapp.beans.Property(propertyURI);
}
} }

View file

@ -81,7 +81,14 @@ public class SimpleReasonerInversePropertyTest extends AbstractTestClass {
aBox.add(a,P,b); aBox.add(a,P,b);
Assert.assertTrue(inf.contains(b,Q,a)); Assert.assertTrue(inf.contains(b,Q,a));
aBox.add(c,Q,d); aBox.add(c,Q,d);
Assert.assertTrue(inf.contains(d,P,c)); Assert.assertTrue(inf.contains(d,P,c));
// delete assertions and verify that inferences go away
aBox.remove(c,Q,d);
Assert.assertFalse(inf.contains(d,P,c));
aBox.remove(a,P,b);
Assert.assertFalse(inf.contains(b,Q,a));
} }
@Test @Test

View file

@ -10,6 +10,8 @@ import java.util.Set;
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.util.Pair;
import com.hp.hpl.jena.vocabulary.OWL;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper; import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
@ -43,10 +45,15 @@ public class PropertyRestrictionPolicyHelperStub extends
namespaceSet.addAll(Arrays.asList(restrictedNamespaces)); namespaceSet.addAll(Arrays.asList(restrictedNamespaces));
} }
Map<String, RoleLevel> thresholdMap = new HashMap<String, RoleLevel>(); Map<Pair<String, Pair<String,String>>, RoleLevel> thresholdMap = new HashMap<
Pair<String, Pair<String,String>>, RoleLevel>();
if (restrictedProperties != null) { if (restrictedProperties != null) {
for (String prop : restrictedProperties) { for (String prop : restrictedProperties) {
thresholdMap.put(prop, RoleLevel.NOBODY); thresholdMap.put(
new Pair<String, Pair<String, String>>(
OWL.Thing.getURI(), new Pair<String, String>(
prop, OWL.Thing.getURI())),
RoleLevel.NOBODY);
} }
} }
@ -57,8 +64,8 @@ public class PropertyRestrictionPolicyHelperStub extends
private PropertyRestrictionPolicyHelperStub( private PropertyRestrictionPolicyHelperStub(
Set<String> modifyRestrictedNamespaces, Set<String> modifyRestrictedNamespaces,
Set<String> modifyPermittedExceptions, Set<String> modifyPermittedExceptions,
Map<String, RoleLevel> displayThresholds, Map<Pair<String, Pair<String,String>>, RoleLevel> displayThresholds,
Map<String, RoleLevel> modifyThresholds) { Map<Pair<String, Pair<String,String>>, RoleLevel> modifyThresholds) {
super(modifyRestrictedNamespaces, modifyPermittedExceptions, super(modifyRestrictedNamespaces, modifyPermittedExceptions,
displayThresholds, modifyThresholds, ModelFactory.createDefaultModel()); displayThresholds, modifyThresholds, ModelFactory.createDefaultModel());
} }

View file

@ -67,7 +67,7 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
} }
@Override @Override
public ObjectProperty getObjectPropertyByURIAndRangeURI(String objectPropertyURI, String rangeURI) { public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI) {
return getObjectPropertyByURI(objectPropertyURI); return getObjectPropertyByURI(objectPropertyURI);
} }

View file

@ -216,7 +216,7 @@ public class ObjectPropertyStatementDaoStub implements
@Override @Override
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty( public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri, String propertyUri, String objectKey, String rangeUri, String subjectUri, String propertyUri, String objectKey, String domainUri, String rangeUri,
String query, Set<String> constructQueries, String sortDir) { String query, Set<String> constructQueries, String sortDir) {
throw new RuntimeException( throw new RuntimeException(
"ObjectPropertyStatementDaoStub.getObjectPropertyStatementsForIndividualByProperty() not implemented."); "ObjectPropertyStatementDaoStub.getObjectPropertyStatementsForIndividualByProperty() not implemented.");

View file

@ -25,8 +25,6 @@ edu.cornell.mannlib.vitro.webapp.servlet.setup.UserModelSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.ContentModelSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.ContentModelSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.ModelMakerSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.ModelMakerSetup
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 edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil$Setup
@ -38,6 +36,8 @@ edu.cornell.mannlib.vitro.webapp.servlet.setup.FileGraphSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.SimpleReasonerSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.SimpleReasonerSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase
# Must run after JenaDataSourceSetup # Must run after JenaDataSourceSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.ThemeInfoSetup edu.cornell.mannlib.vitro.webapp.servlet.setup.ThemeInfoSetup

View file

@ -42,13 +42,13 @@ crop_page_title_with_name = Crop image for {0}
current_photo = Current Photo current_photo = Current Photo
upload_photo = Upload a photo upload_photo = Upload a photo
replace_photo = Replace Photo replace_photo = Replace Photo
photo_types = (JPEG, GIF or PNG) photo_types = (JPEG, GIF or PNG)
maximum_file_size = Maximum file size: {0} megabytes maximum_file_size = Maximum file size: {0} megabytes
minimum_image_dimensions = Minimum image dimensions: {0} x {1} pixels minimum_image_dimensions = Minimum image dimensions: {0} x {1} pixels
cropping_caption = Your profile photo will look like the image below. cropping_caption = Your profile photo will look like the image below.
cropping_note = To make adjustments, you can drag around and resize the photo to the right. \ cropping_note = To make adjustments, you can drag around and resize the photo to the right. \
When you are happy with your photo click the "Save Photo" button. When you are happy with your photo click the "Save Photo" button.
alt_thumbnail_photo = Individual photo alt_thumbnail_photo = Individual photo
alt_image_to_crop = Image to be cropped alt_image_to_crop = Image to be cropped
@ -69,7 +69,7 @@ imageUpload.errorFileTooBig = Please upload an image smaller than {0} megabytes.
imageUpload.errorUnrecognizedFileType = ''{0}'' is not a recognized image file type. Please upload JPEG, GIF, or PNG files only. imageUpload.errorUnrecognizedFileType = ''{0}'' is not a recognized image file type. Please upload JPEG, GIF, or PNG files only.
imageUpload.errorNoPhotoSelected = Please browse and select a photo. imageUpload.errorNoPhotoSelected = Please browse and select a photo.
imageUpload.errorBadMultipartRequest = Failed to parse the multi-part request for uploading an image. imageUpload.errorBadMultipartRequest = Failed to parse the multi-part request for uploading an image.
imageUpload.errorFormFieldMissing = The form did not contain a ''{0}'' field." imageUpload.errorFormFieldMissing = The form did not contain a ''{0}'' field."
# #
# User Accounts pages # User Accounts pages
@ -84,27 +84,27 @@ last_login = Last Login
add_new_account = Add new account add_new_account = Add new account
edit_account = Edit account edit_account = Edit account
external_auth_only = Externally Authenticated Only external_auth_only = Externally Authenticated Only
reset_password = Reset password reset_password = Reset password
reset_password_note = Note: Instructions for resetting the password will \ reset_password_note = Note: Instructions for resetting the password will \
be emailed to the address entered above. The password will not \ be emailed to the address entered above. The password will not \
be reset until the user follows the link provided in this email. be reset until the user follows the link provided in this email.
new_password = New password new_password = New password
confirm_password = Confirm new password confirm_password = Confirm new password
minimum_password_length = Minimum of {0} characters in length. minimum_password_length = Minimum of {0} characters in length.
leave_password_unchanged = Leaving this blank means that the password will not be changed. leave_password_unchanged = Leaving this blank means that the password will not be changed.
confirm_initial_password = Confirm initial password confirm_initial_password = Confirm initial password
new_account_1 = A new account for new_account_1 = A new account for
new_account_2 = was successfully created. new_account_2 = was successfully created.
new_account_title = new account new_account_title = new account
new_account_notification = A notification email has been sent to {0} \ new_account_notification = A notification email has been sent to {0} \
with instructions for activating the account and creating a password. with instructions for activating the account and creating a password.
updated_account_1 = The account for updated_account_1 = The account for
updated_account_2 = has been updated. updated_account_2 = has been updated.
updated_account_title = updated account updated_account_title = updated account
updated_account_notification = A confirmation email has been sent to {0} \ updated_account_notification = A confirmation email has been sent to {0} \
with instructions for resetting a password. \ with instructions for resetting a password. \
The password will not be reset until the user follows the link provided in this email. The password will not be reset until the user follows the link provided in this email.
deleted_accounts = Deleted {0} {0, choice, 0#accounts|1#account|1<accounts}. deleted_accounts = Deleted {0} {0, choice, 0#accounts|1#account|1<accounts}.
enter_new_password = Please enter your new password for {0} enter_new_password = Please enter your new password for {0}
@ -126,8 +126,8 @@ view_all_accounts = View all accounts
view_all_accounts_title = view all accounts view_all_accounts_title = view all accounts
new_account_note = Note: An email will be sent to the address entered above \ new_account_note = Note: An email will be sent to the address entered above \
notifying that an account has been created. \ notifying that an account has been created. \
It will include instructions for activating the account and creating a password. It will include instructions for activating the account and creating a password.
initial_password = Initial password initial_password = Initial password
submit_add_new_account = Add new account submit_add_new_account = Add new account
@ -177,22 +177,22 @@ first_time_login = First time log in
create_account = Create account create_account = Create account
cant_activate_while_logged_in = You may not activate the account for {0} while you are logged in as {1}. \ cant_activate_while_logged_in = You may not activate the account for {0} while you are logged in as {1}. \
Please log out and try again. Please log out and try again.
account_already_activated = The account for {0} has already been activated. account_already_activated = The account for {0} has already been activated.
cant_change_password_while_logged_in = You may not reset the password for {0} while you are logged in as {1}. \ cant_change_password_while_logged_in = You may not reset the password for {0} while you are logged in as {1}. \
Please log out and try again. Please log out and try again.
password_change_not_pending = The password for {0} has already been reset. password_change_not_pending = The password for {0} has already been reset.
password_changed_subject = Password changed. password_changed_subject = Password changed.
account_no_longer_exists = The account you are trying to set a password on is no longer available. \ account_no_longer_exists = The account you are trying to set a password on is no longer available. \
Please contact your system administrator if you think this is an error. Please contact your system administrator if you think this is an error.
password_saved = Your password has been saved. password_saved = Your password has been saved.
password_saved_please_login = Your password has been saved. Please log in. password_saved_please_login = Your password has been saved. Please log in.
please_provide_contact_information = Please provide your contact information to finish creating your account. please_provide_contact_information = Please provide your contact information to finish creating your account.
first_time_login_note = Note: An email will be sent to the address entered above notifying \ first_time_login_note = Note: An email will be sent to the address entered above notifying \
that an account has been created. that an account has been created.
first_time_external_email_html = @@file files/accountFirstTimeExternal.html first_time_external_email_html = @@file files/accountFirstTimeExternal.html
first_time_external_email_text = @@file files/accountFirstTimeExternal.txt first_time_external_email_text = @@file files/accountFirstTimeExternal.txt
@ -201,7 +201,7 @@ myAccount_confirm_changes = Your changes have been saved.
myAccount_confirm_changes_plus_note = Your changes have been saved. A confirmation email has been sent to {0}. myAccount_confirm_changes_plus_note = Your changes have been saved. A confirmation email has been sent to {0}.
email_change_will_be_confirmed = Note: if email changes, a confirmation email will be sent to the new email address entered above. email_change_will_be_confirmed = Note: if email changes, a confirmation email will be sent to the new email address entered above.
#email_changed_subject = "Your VIVO email account has been changed."); #email_changed_subject = "Your VIVO email account has been changed.");
who_can_edit_profile = Who can edit my profile who_can_edit_profile = Who can edit my profile
add_profile_editor = Add profile editor add_profile_editor = Add profile editor
select_existing_last_name = Select an existing last name select_existing_last_name = Select an existing last name
@ -211,7 +211,6 @@ remove_selection_title = remove selection
external_id_not_provided = Login failed - External ID is not found. external_id_not_provided = Login failed - External ID is not found.
external_id_already_in_use = User account already exists for ''{0}'' external_id_already_in_use = User account already exists for ''{0}''
logins_disabled_for_maintenance = User logins are temporarily disabled while the system is being maintained.
error_no_email = You must supply an email address. error_no_email = You must supply an email address.
error_email_already_exists = An account with that email address already exists. error_email_already_exists = An account with that email address already exists.
@ -220,20 +219,18 @@ error_external_auth_already_exists = An account with that external authorization
error_no_first_name = You must supply a first name. error_no_first_name = You must supply a first name.
error_no_last_name = You must supply a last name. error_no_last_name = You must supply a last name.
error_no_role = You must select a role. error_no_role = You must select a role.
error_no_password = No password supplied.
error_password_length = Password must be between {0} and {1} characters.
error_password_mismatch = Passwords do not match. error_password_mismatch = Passwords do not match.
logged_in_but_no_profile = You have logged in, but the system contains no profile for you. logged_in_but_no_profile = You have logged in, but the system contains no profile for you.
unknown_user_name = friend unknown_user_name = friend
login_welcome_message = Welcome{1, choice, 1# |1< back}, {0} login_welcome_message = Welcome{1, choice, 1# |1< back}, {0}
external_login_failed = External login failed external_login_failed = External login failed
logged_out = You have logged out. logged_out = You have logged out.
insufficient_authorization = We're sorry, but you are not authorized to view the page you requested. If you think this is an error, please contact us and we'll be happy to help. insufficient_authorization = We're sorry, but you are not authorized to view the page you requested. If you think this is an error, please contact us and we'll be happy to help.
# #
# "partial" individual templates ( /templates/freemarker/body/partials/individual ) # "partial" individual templates ( /templates/freemarker/body/partials/individual )
# #
manage_publications = manage publications manage_publications = manage publications
manage_grants_and_projects = manage grants & projects manage_grants_and_projects = manage grants & projects
@ -307,7 +304,7 @@ search_index_not_connected = The search index is not connected.
failed = failed failed = failed
check_startup_status = Check startup status page and/or Tomcat logs for more information. check_startup_status = Check startup status page and/or Tomcat logs for more information.
search_indexer_idle = The search indexer is idle. search_indexer_idle = The search indexer is idle.
most_recent_update = The most recent update was at most_recent_update = The most recent update was at
rebuild_button = Rebuild rebuild_button = Rebuild
reset_search_index = Reset the search index and re-populate it. reset_search_index = Reset the search index and re-populate it.
preparing_to_rebuild_index = Preparing to rebuild the search index. preparing_to_rebuild_index = Preparing to rebuild the search index.
@ -322,7 +319,7 @@ warning = Warning
warnings_issued = {0} issued warnings during startup. warnings_issued = {0} issued warnings during startup.
startup_trace = Startup trace startup_trace = Startup trace
full_list_startup = The full list of startup events and messages. full_list_startup = The full list of startup events and messages.
startup_status = Startup Status startup_status = Startup status
continue = Continue continue = Continue
# #
@ -479,7 +476,7 @@ hide_show_properties = hide/show properties
hide_properties = hide properties hide_properties = hide properties
property_hierarchy = Property Hierarchy property_hierarchy = Property Hierarchy
all_x_properties = All {0} Properties all_x_properties = All {0} Properties
property_groups = Property Groups property_groups = Property groups
add_new = Add new add_new = Add new
object = object object = object
data = data data = data
@ -496,7 +493,7 @@ object_property_hierarchy = Object property hierarchy
data_property_hierarchy = Data property hierarchy data_property_hierarchy = Data property hierarchy
site_config = Site Configuration site_config = Site Configuration
internal_class = Institutional internal class internal_class_i_capped = Institutional internal class
manage_profile_editing = Manage profile editing manage_profile_editing = Manage profile editing
page_management = Page management page_management = Page management
menu_ordering_mixed_caps = Menu ordering menu_ordering_mixed_caps = Menu ordering
@ -504,6 +501,18 @@ restrict_logins_mixed_caps = Restrict logins
site_information = Site information site_information = Site information
user_accounts = User accounts user_accounts = User accounts
#
# search controller ( PagedSearchController.java )
#
error_in_search_request = The search request contained errors.
enter_search_term = Please enter a search term.
invalid_search_term = Search term was invalid
paging_link_more = more...
no_matching_results = No matching results.
search_failed = Search failed.
search_term_error_near = The search term had an error near
search_for = Search for ''{0}''
# #
# search templates ( /templates/freemarker/body/search ) # search templates ( /templates/freemarker/body/search )
# #
@ -521,24 +530,12 @@ page_link = page link
next_capitalized = Next next_capitalized = Next
# #
# search controller ( PagedSearchController.java ) # shortview templates ( /templates/freemarker/body/partials/shortview )
#
error_in_search_request = The search request contained errors.
enter_search_term = Please enter a search term.
invalid_search_term = Search term was invalid
paging_link_more = more...
no_matching_results = No matching results.
search_failed = Search failed.
search_term_error_near = The search term had an error near
search_for = Search for ''{0}''
#
# shortview templates ( /templates/freemarker/body/partials/shortview )
# #
view_profile_page_for = View the profile page for view_profile_page_for = View the profile page for
# #
# menupage templates ( /templates/freemarker/body/partials/menupage ) # menupage templates ( /templates/freemarker/body/partials/menupage )
# #
browse_page_javascript_one = This browse page requires javascript, but your browser is set to disable javascript. Either enable javascript or use the browse_page_javascript_one = This browse page requires javascript, but your browser is set to disable javascript. Either enable javascript or use the
browse_page_javascript_two = to browse for information. browse_page_javascript_two = to browse for information.
@ -552,14 +549,14 @@ browse_all_public_content = You can browse all of the public content currently i
browse_all_content = browse all content browse_all_content = browse all content
# #
# partial templates ( /templates/freemarker/body/partials ) # partial templates ( /templates/freemarker/body/partials )
# #
no_content_create_groups_classes = There is currently no content in the system, or you need to create class groups and assign your classes to them. no_content_create_groups_classes = There is currently no content in the system, or you need to create class groups and assign your classes to them.
browse_capitalized = Browse browse_capitalized = Browse
browse_by = Browse by browse_by = Browse by
# #
# partial account templates ( /templates/freemarker/body/partials/accounts ) # partial account templates ( /templates/freemarker/body/partials/accounts )
# #
delete_button = Delete delete_button = Delete
accounts = accounts accounts = accounts
@ -567,7 +564,7 @@ accounts_per_page = accounts per page
update_button = Update update_button = Update
# #
# pagemanagement templates ( /templates/freemarker/body/pagemanagement ) # pagemanagement templates ( /templates/freemarker/body/pagemanagement )
# #
title_capitalized = Title title_capitalized = Title
type_capitalized = Type type_capitalized = Type
@ -588,7 +585,7 @@ use_capitalized = Use
to_order_menu_items = to set the order of menu items. to_order_menu_items = to set the order of menu items.
# #
# menupage templates ( /templates/freemarker/body/menupage ) # menupage templates ( /templates/freemarker/body/menupage )
# #
page_not_configured = This page is not yet configured. page_not_configured = This page is not yet configured.
implement_capitalized = Implement implement_capitalized = Implement
@ -599,10 +596,10 @@ no_html_specified = No HTML specified.
page_text = page text page_text = page text
sparql_query_results = Sparql Query Results sparql_query_results = Sparql Query Results
no_results_returned = No results were returned. no_results_returned = No results were returned.
# #
# manage proxies templates ( /templates/freemarker/body/manageproxies ) # manage proxies templates ( /templates/freemarker/body/manageproxies )
# #
operation_successful = The operation was successful. operation_successful = The operation was successful.
operation_unsuccessful = The operation was unsuccessful. Full details can be found in the system log. operation_unsuccessful = The operation was unsuccessful. Full details can be found in the system log.
@ -623,7 +620,7 @@ selected_profiles = Selected profiles
save_profile_changes = Save changes to profiles save_profile_changes = Save changes to profiles
# #
# page partials templates ( /templates/freemarker/page/partials ) # page partials templates ( /templates/freemarker/page/partials )
# #
copyright = copyright copyright = copyright
all_rights_reserved = All Rights Reserved. all_rights_reserved = All Rights Reserved.
@ -650,7 +647,7 @@ menu_item = menu item
version = Version version = Version
# #
# widget templates ( /templates/freemarker/widgets ) # widget templates ( /templates/freemarker/widgets )
# #
individual_name = individual name individual_name = individual name
vclassAlpha_not_implemented = vclassAlpha is not yet implemented. vclassAlpha_not_implemented = vclassAlpha is not yet implemented.
@ -668,11 +665,10 @@ account = account
change_password_to_login = Change Password to Log in change_password_to_login = Change Password to Log in
new_password_capitalized = New Password new_password_capitalized = New Password
confirm_password_capitalized = Confirm Password confirm_password_capitalized = Confirm Password
minimum_password_length = Minimum of {0} characters in length.
already_logged_in = You are already logged in. already_logged_in = You are already logged in.
# #
# lib templates ( /templates/freemarker/lib ) # lib templates ( /templates/freemarker/lib )
# #
statistics = Statistics statistics = Statistics
@ -695,7 +691,7 @@ add_label_for_language = Language
unsupported_ie_version = This form is not supported in versions of Internet Explorer below version 8. Please upgrade your browser, or switch to another browser, such as FireFox. unsupported_ie_version = This form is not supported in versions of Internet Explorer below version 8. Please upgrade your browser, or switch to another browser, such as FireFox.
# #
# edit templates ( /templates/freemarker/edit and edit/forms ) # edit templates ( /templates/freemarker/edit and edit/forms )
# #
edit_capitalized = Edit edit_capitalized = Edit
add_capitalized = Add add_capitalized = Add
@ -764,7 +760,7 @@ label = label
no_classes_to_select = There are no Classes in the system from which to select. no_classes_to_select = There are no Classes in the system from which to select.
# #
# vitro theme templates ( /themes/vitro/templates ) # vitro theme templates ( /themes/vitro/templates )
# #
powered_by = Powered by powered_by = Powered by
javascript_ie_alert_text = This site uses HTML elements that are not recognized by Internet Explorer 8 and below in the absence of JavaScript. As a result, the site will not be rendered appropriately. To correct this, please either enable JavaScript, upgrade to Internet Explorer 9, or use another browser. javascript_ie_alert_text = This site uses HTML elements that are not recognized by Internet Explorer 8 and below in the absence of JavaScript. As a result, the site will not be rendered appropriately. To correct this, please either enable JavaScript, upgrade to Internet Explorer 9, or use another browser.
@ -780,7 +776,7 @@ search_vitro = Search VITRO
filter_search = filter search filter_search = filter search
# #
# custom form javascript variables ( /templates/freemarker/edit/js) # custom form javascript variables ( /templates/freemarker/edit/js)
# #
select_an_existing = Select an existing select_an_existing = Select an existing
or_create_new_one = or create a new one. or_create_new_one = or create a new one.
@ -805,7 +801,7 @@ october = October
november = November november = November
# #
# miscellaneous javascript variables ( webapp/web/js) # miscellaneous javascript variables ( webapp/web/js)
# #
select_editor_and_profile = You must select a minimum of 1 editor and profile. select_editor_and_profile = You must select a minimum of 1 editor and profile.

View file

@ -18,7 +18,7 @@
<#-- List the menu items --> <#-- List the menu items -->
<ul class="menuItems"> <ul class="menuItems">
<#list hasElement.statements as statement> <#list hasElement.statements as statement>
<li class="menuItem"><#include "${hasElement.template}"> <span class="controls"><!--p.editingLinks "hasElement" statement editable /--></span></li> <li class="menuItem"><#include "${hasElement.template}"> <span class="controls"><!--p.editingLinks "hasElement" "" statement editable /--></span></li>
</#list> </#list>
</ul> </ul>

View file

@ -8,7 +8,7 @@
<ul role="navigation"> <ul role="navigation">
<#if siteConfig.internalClass?has_content> <#if siteConfig.internalClass?has_content>
<li role="listitem"><a href="${siteConfig.internalClass}" title="${i18n().internal_class}">${i18n().internal_class}</a></li> <li role="listitem"><a href="${siteConfig.internalClass}" title="${i18n().internal_class}">${i18n().internal_class_i_capped}</a></li>
</#if> </#if>
<#if siteConfig.manageProxies?has_content> <#if siteConfig.manageProxies?has_content>

View file

@ -144,7 +144,7 @@ var customForm = {
// Put this case first, because in edit mode with // Put this case first, because in edit mode with
// validation errors we just want initFormFullView. // validation errors we just want initFormFullView.
// if ((!this.supportEdit) && (this.editMode == 'edit' || this.editMode == 'repair')) { // if ((!this.supportEdit) && (this.editMode == 'edit' || this.editMode == 'repair')) {
if (this.editMode == 'edit' || this.editMode == 'repair') { if (this.editMode == 'edit' || this.editMode == 'repair' || this.editMode == 'error') {
this.initFormWithValidationErrors(); this.initFormWithValidationErrors();
} }
else if (this.findValidationErrors()) { else if (this.findValidationErrors()) {
@ -321,8 +321,12 @@ var customForm = {
}, },
complete: function(xhr, status) { complete: function(xhr, status) {
// Not sure why, but we need an explicit json parse here. // Not sure why, but we need an explicit json parse here.
var results = $.parseJSON(xhr.responseText), var results = $.parseJSON(xhr.responseText);
filteredResults = customForm.filterAcResults(results); var filteredResults = customForm.filterAcResults(results);
if ( customForm.acTypes[$(selectedObj).attr('acGroupName')] == "http://www.w3.org/2004/02/skos/core#Concept" ) {
filteredResults = customForm.removeConceptSubclasses(filteredResults);
}
customForm.acCache[request.term] = filteredResults; customForm.acCache[request.term] = filteredResults;
response(filteredResults); response(filteredResults);
@ -423,6 +427,16 @@ var customForm = {
}, },
removeConceptSubclasses: function(array) {
$(array).each(function(i) {
if(this["msType"] != "http://www.w3.org/2004/02/skos/core#Concept") {
//Remove from array
array.splice(i, 1);
}
});
return array;
},
showAutocompleteSelection: function(label, uri, selectedObj) { showAutocompleteSelection: function(label, uri, selectedObj) {
// hide the acSelector field and set it's value to the selected ac item // hide the acSelector field and set it's value to the selected ac item
this.hideFields($(selectedObj).parent()); this.hideFields($(selectedObj).parent());

View file

@ -108,13 +108,13 @@ name will be used as the label. -->
<#if editable> <#if editable>
<#local url = property.addUrl> <#local url = property.addUrl>
<#if url?has_content> <#if url?has_content>
<@showAddLink property.localName label url /> <@showAddLink property.localName property.name label url />
</#if> </#if>
</#if> </#if>
</#macro> </#macro>
<#macro showAddLink propertyLocalName label url> <#macro showAddLink propertyLocalName propertyName label url>
<#if propertyLocalName == "informationResourceInAuthorship" || propertyLocalName == "webpage" || propertyLocalName == "hasResearchArea"> <#if propertyName == "informationResourceInAuthorship" || propertyName == "webpage" || propertyLocalName == "hasResearchArea">
<a class="add-${propertyLocalName}" href="${url}" title="${i18n().manage_list_of} ${label?lower_case}"> <a class="add-${propertyLocalName}" href="${url}" title="${i18n().manage_list_of} ${label?lower_case}">
<img class="add-individual" src="${urls.images}/individual/manage-icon.png" alt="${i18n().manage}" /></a> <img class="add-individual" src="${urls.images}/individual/manage-icon.png" alt="${i18n().manage}" /></a>
<#else> <#else>
@ -131,30 +131,42 @@ name will be used as the label. -->
<#macro propertyListItem property statement editable > <#macro propertyListItem property statement editable >
<li role="listitem"> <li role="listitem">
<#nested> <#nested>
<@editingLinks "${property.localName}" statement editable/> <@editingLinks "${property.localName}" "${property.name}" statement editable/>
</li> </li>
</#macro> </#macro>
<#macro editingLinks propertyLocalName statement editable> <#macro editingLinks propertyLocalName propertyName statement editable>
<#if editable && (propertyLocalName != "informationResourceInAuthorship" && propertyLocalName != "webpage" && propertyLocalName != "hasResearchArea")> <#if editable && (propertyName != "authors" && propertyName != "webpage" && propertyLocalName != "hasResearchArea")>
<@editLink propertyLocalName statement /> <@editLink propertyLocalName propertyName statement />
<@deleteLink propertyLocalName statement /> <@deleteLink propertyLocalName propertyName statement />
</#if> </#if>
</#macro> </#macro>
<#macro editLink propertyLocalName propertyName statement>
<#macro editLink propertyLocalName statement> <#if propertyLocalName?contains("ARG_2000028")>
<#if propertyName?contains("mailing address")>
<#local url = statement.editUrl + "&addressUri=" + "${statement.address!}">
<#elseif propertyName?contains("phone")>
<#local url = statement.editUrl + "&phoneUri=" + "${statement.phone!}">
<#elseif propertyName?contains("primary email") || propertyName?contains("additional emails")>
<#local url = statement.editUrl + "&emailUri=" + "${statement.email!}">
<#elseif propertyName?contains("full name")>
<#local url = statement.editUrl + "&fullNameUri=" + "${statement.fullName!}">
</#if>
<#else>
<#local url = statement.editUrl> <#local url = statement.editUrl>
</#if>
<#if url?has_content> <#if url?has_content>
<@showEditLink propertyLocalName url /> <@showEditLink propertyLocalName url />
</#if> </#if>
</#macro> </#macro>
<#macro showEditLink propertyLocalName url> <#macro showEditLink propertyLocalName url>
<a class="edit-${propertyLocalName}" href="${url}" title="${i18n().edit_entry}"><img class="edit-individual" src="${urls.images}/individual/editIcon.gif" alt="${i18n().edit_entry}" /></a> <a class="edit-${propertyLocalName}" href="${url}" title="${i18n().edit_entry}"><img class="edit-individual" src="${urls.images}/individual/editIcon.gif" alt="${i18n().edit_entry}" /></a>
</#macro> </#macro>
<#macro deleteLink propertyLocalName statement> <#macro deleteLink propertyLocalName propertyName statement>
<#local url = statement.deleteUrl> <#local url = statement.deleteUrl>
<#if url?has_content> <#if url?has_content>
<@showDeleteLink propertyLocalName url /> <@showDeleteLink propertyLocalName url />
@ -197,7 +209,7 @@ name will be used as the label. -->
<a href="${individual.imageUrl}" title="${i18n().alt_thumbnail_photo}"> <a href="${individual.imageUrl}" title="${i18n().alt_thumbnail_photo}">
<img class="individual-photo" src="${thumbUrl}" title="${i18n().click_to_view_larger}" alt="${individual.name}" width="${imageWidth!}" /> <img class="individual-photo" src="${thumbUrl}" title="${i18n().click_to_view_larger}" alt="${individual.name}" width="${imageWidth!}" />
</a> </a>
<@editingLinks "${mainImage.localName}" mainImage.first() editable /> <@editingLinks "${mainImage.localName}" "" mainImage.first() editable />
<#else> <#else>
<#local imageLabel><@addLinkWithLabel mainImage editable "${i18n().photo}" /></#local> <#local imageLabel><@addLinkWithLabel mainImage editable "${i18n().photo}" /></#local>
${imageLabel} ${imageLabel}
@ -218,7 +230,7 @@ name will be used as the label. -->
<#local label = individual.nameStatement> <#local label = individual.nameStatement>
${label.value} ${label.value}
<#if useEditLink> <#if useEditLink>
<@editingLinks "label" label editable /> <@editingLinks "label" "" label editable />
<#elseif editable || (labelCount > 1)> <#elseif editable || (labelCount > 1)>
<#--We display the link even when the user is not logged in case of multiple labels--> <#--We display the link even when the user is not logged in case of multiple labels-->
<#if editable> <#if editable>