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

View file

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

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.DataPropertyStatement;
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
@ -82,7 +83,7 @@ public class DisplayByRolePermission extends Permission {
*/
private boolean isAuthorized(DisplayDataProperty action) {
String predicateUri = action.getDataProperty().getURI();
return canDisplayPredicate(predicateUri);
return canDisplayPredicate(new Property(predicateUri));
}
/**
@ -90,8 +91,7 @@ public class DisplayByRolePermission extends Permission {
* predicate.
*/
private boolean isAuthorized(DisplayObjectProperty action) {
String predicateUri = action.getObjectProperty().getURI();
return canDisplayPredicate(predicateUri);
return canDisplayPredicate(action.getObjectProperty());
}
/**
@ -103,7 +103,7 @@ public class DisplayByRolePermission extends Permission {
String subjectUri = stmt.getIndividualURI();
String predicateUri = stmt.getDatapropURI();
return canDisplayResource(subjectUri)
&& canDisplayPredicate(predicateUri);
&& canDisplayPredicate(new Property(predicateUri));
}
/**
@ -113,12 +113,10 @@ public class DisplayByRolePermission extends Permission {
private boolean isAuthorized(DisplayObjectPropertyStatement action) {
ObjectPropertyStatement stmt = action.getObjectPropertyStatement();
String subjectUri = stmt.getSubjectURI();
String predicateUri = stmt.getPropertyURI();
String rangeUri = (stmt.getProperty() == null) ? null
: stmt.getProperty().getRangeVClassURI();
Property predicate = stmt.getProperty();
String objectUri = stmt.getObjectURI();
return canDisplayResource(subjectUri)
&& canDisplayPredicate(predicateUri, rangeUri)
&& canDisplayPredicate(predicate)
&& canDisplayResource(objectUri);
}
@ -126,14 +124,10 @@ public class DisplayByRolePermission extends Permission {
return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource(
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)
.canDisplayPredicate(predicateUri, rangeUri, this.roleLevel);
.canDisplayPredicate(predicate, this.roleLevel);
}
@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.AbstractObjectPropertyStatementAction;
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
@ -78,9 +79,9 @@ public class EditByRolePermission extends Permission {
*/
private boolean isAuthorized(AbstractDataPropertyStatementAction action) {
String subjectUri = action.getSubjectUri();
String predicateUri = action.getPredicateUri();
Property predicate = action.getPredicate();
return canModifyResource(subjectUri)
&& canModifyPredicate(predicateUri);
&& canModifyPredicate(predicate);
}
/**
@ -89,10 +90,10 @@ public class EditByRolePermission extends Permission {
*/
private boolean isAuthorized(AbstractObjectPropertyStatementAction action) {
String subjectUri = action.getSubjectUri();
String predicateUri = action.getPredicateUri();
Property predicate = action.getPredicate();
String objectUri = action.getObjectUri();
return canModifyResource(subjectUri)
&& canModifyPredicate(predicateUri)
&& canModifyPredicate(predicate)
&& canModifyResource(objectUri);
}
@ -101,9 +102,9 @@ public class EditByRolePermission extends Permission {
resourceUri, roleLevel);
}
private boolean canModifyPredicate(String predicateUri) {
private boolean canModifyPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
predicateUri, roleLevel);
predicate, roleLevel);
}
@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.PolicyDecision;
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.
@ -26,9 +27,9 @@ public abstract class BaseSelfEditingPolicy {
uri, roleLevel);
}
protected boolean canModifyPredicate(String uri) {
protected boolean canModifyPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
uri, roleLevel);
predicate, roleLevel);
}
protected PolicyDecision cantModifyResource(String uri) {
@ -36,9 +37,9 @@ public abstract class BaseSelfEditingPolicy {
+ uri);
}
protected PolicyDecision cantModifyPredicate(String uri) {
protected PolicyDecision cantModifyPredicate(Property predicate) {
return inconclusiveDecision("No access to admin predicates; cannot modify "
+ uri);
+ predicate.getURI());
}
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.DataPropertyStatement;
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
@ -92,14 +93,14 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface {
Collection<String> individuals) {
DataPropertyStatement stmt = action.getDataPropertyStatement();
String subjectUri = stmt.getIndividualURI();
String predicateUri = stmt.getDatapropURI();
if (canDisplayResource(subjectUri) && canDisplayPredicate(predicateUri)
Property predicate = new Property(stmt.getDatapropURI());
if (canDisplayResource(subjectUri) && canDisplayPredicate(predicate)
&& isAboutAssociatedIndividual(individuals, stmt)) {
return authorized("user may view DataPropertyStatement "
+ subjectUri + " ==> " + predicateUri);
+ subjectUri + " ==> " + predicate.getURI());
} else {
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 predicateUri = stmt.getPropertyURI();
String objectUri = stmt.getObjectURI();
if (canDisplayResource(subjectUri) && canDisplayPredicate(predicateUri)
if (canDisplayResource(subjectUri) && canDisplayPredicate(new Property
(predicateUri))
&& canDisplayResource(objectUri)
&& isAboutAssociatedIndividual(individuals, stmt)) {
return authorized("user may view ObjectPropertyStatement "
@ -143,9 +145,9 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface {
uri, RoleLevel.SELF);
}
private boolean canDisplayPredicate(String uri) {
private boolean canDisplayPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx)
.canDisplayPredicate(uri, RoleLevel.SELF);
.canDisplayPredicate(predicate, RoleLevel.SELF);
}
private boolean isAboutAssociatedIndividual(Collection<String> selves,

View file

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

View file

@ -122,7 +122,8 @@ public class PolicyHelper {
}
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();
if ((subject == null) || (predicate == null) || (objectNode == null)) {
return false;
@ -131,7 +132,7 @@ public class PolicyHelper {
RequestedAction action;
if (objectNode.isResource()) {
action = new AddObjectPropertyStatement(modelToBeModified,
subject.getURI(), predicate.getURI(), objectNode
subject.getURI(), predicate, objectNode
.asResource().getURI());
} else {
action = new AddDataPropertyStatement(modelToBeModified,
@ -153,7 +154,9 @@ public class PolicyHelper {
}
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();
if ((subject == null) || (predicate == null) || (objectNode == null)) {
return false;
@ -162,7 +165,7 @@ public class PolicyHelper {
RequestedAction action;
if (objectNode.isResource()) {
action = new DropObjectPropertyStatement(modelToBeModified,
subject.getURI(), predicate.getURI(), objectNode
subject.getURI(), predicate, objectNode
.asResource().getURI());
} else {
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.resource.AbstractResourceAction;
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
@ -69,7 +70,7 @@ public class SelfEditingPolicy extends BaseSelfEditingPolicy implements
private PolicyDecision isAuthorizedForObjectPropertyAction(
List<String> userUris, AbstractObjectPropertyStatementAction action) {
String subject = action.getSubjectUri();
String predicate = action.getPredicateUri();
Property predicate = action.getPredicate();
String object = action.getObjectUri();
if (!canModifyResource(subject)) {
@ -96,7 +97,7 @@ public class SelfEditingPolicy extends BaseSelfEditingPolicy implements
private PolicyDecision isAuthorizedForDataPropertyAction(
List<String> userUris, AbstractDataPropertyStatementAction action) {
String subject = action.getSubjectUri();
String predicate = action.getPredicateUri();
Property predicate = action.getPredicate();
if (!canModifyResource(subject)) {
return cantModifyResource(subject);

View file

@ -7,6 +7,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
@ -17,6 +18,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
@ -24,18 +26,23 @@ import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.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.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
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.vocabulary.OWL;
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.VitroVocabulary;
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
@ -108,17 +115,22 @@ public class PropertyRestrictionPolicyHelper {
Model displayModel) {
Map<String, RoleLevel> displayThresholdMap = new HashMap<String, RoleLevel>();
Map<String, RoleLevel> modifyThresholdMap = new HashMap<String, RoleLevel>();
Map<Pair<String, Pair<String,String>>, RoleLevel> displayThresholdMap =
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(
PROHIBITED_NAMESPACES, PERMITTED_EXCEPTIONS,
@ -127,29 +139,85 @@ public class PropertyRestrictionPolicyHelper {
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
* URI to the required RoleLevel.
*/
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);
try {
Property property = model.getProperty(propertyUri);
com.hp.hpl.jena.rdf.model.Property property = model.getProperty(propertyUri);
StmtIterator stmts = model.listStatements((Resource) null,
property, (Resource) null);
while (stmts.hasNext()) {
Statement stmt = stmts.next();
Resource subject = stmt.getSubject();
RDFNode objectNode = stmt.getObject();
if ((subject == null) || (!(objectNode instanceof Resource))) {
continue;
}
Resource object = (Resource) objectNode;
RoleLevel role = RoleLevel.getRoleByUri(object.getURI());
map.put(subject.getURI(), role);
try {
while (stmts.hasNext()) {
Statement stmt = stmts.next();
Resource subject = stmt.getSubject();
RDFNode objectNode = stmt.getObject();
if ((subject == null) || (!(objectNode instanceof Resource))) {
continue;
}
Resource object = (Resource) objectNode;
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 {
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
* 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
* 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.
@ -194,14 +261,15 @@ public class PropertyRestrictionPolicyHelper {
protected PropertyRestrictionPolicyHelper(
Collection<String> modifyProhibitedNamespaces,
Collection<String> modifyExceptionsAllowedUris,
Map<String, RoleLevel> displayThresholdMap,
Map<String, RoleLevel> modifyThresholdMap,
Map<Pair<String, Pair<String,String>>, RoleLevel> displayThresholdMap,
Map<Pair<String, Pair<String,String>>, RoleLevel> modifyThresholdMap,
Model displayModel) {
this.modifyProhibitedNamespaces = unmodifiable(modifyProhibitedNamespaces);
this.modifyExceptionsAllowedUris = unmodifiable(modifyExceptionsAllowedUris);
this.displayThresholdMap = unmodifiable(displayThresholdMap);
this.modifyThresholdMap = unmodifiable(modifyThresholdMap);
this.displayModel = displayModel;
this.displayThresholdMap = displayThresholdMap;
this.modifyThresholdMap = modifyThresholdMap;
// this.displayThresholdMap = unmodifiable(displayThresholdMap);
// this.modifyThresholdMap = unmodifiable(modifyThresholdMap);
if (log.isDebugEnabled()) {
log.debug("prohibited: " + this.modifyProhibitedNamespaces);
@ -219,6 +287,7 @@ public class PropertyRestrictionPolicyHelper {
}
}
@SuppressWarnings("unused")
private Map<String, RoleLevel> unmodifiable(Map<String, RoleLevel> raw) {
if (raw == null) {
return Collections.emptyMap();
@ -271,83 +340,34 @@ public class PropertyRestrictionPolicyHelper {
log.debug("can modify resource '" + resourceUri + "'");
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
* as high as the restriction level.
*/
public boolean canDisplayPredicate(String predicateUri, String rangeUri, RoleLevel userRole) {
if (predicateUri == null) {
log.debug("can't display predicate: predicateUri was null");
public boolean canDisplayPredicate(Property predicate, RoleLevel userRole) {
if (predicate == null) {
log.debug("can't display predicate: predicate was null");
return false;
}
RoleLevel displayThreshold = RoleLevel.NOBODY;
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);
}
RoleLevel displayThreshold = getThreshold(predicate, displayThresholdMap);
if (isAuthorized(userRole, displayThreshold)) {
log.debug("can display predicate: '" + predicateUri
+ "', userRole=" + userRole + ", thresholdRole="
+ displayThreshold);
log.debug("can display predicate: '" + predicate.getURI() + "', domain="
+ predicate.getDomainVClassURI() + ", range="
+ predicate.getRangeVClassURI() + ", userRole="
+ userRole + ", thresholdRole=" + displayThreshold);
return true;
}
log.debug("can't display predicate: '" + predicateUri + "', userRole="
+ userRole + ", thresholdRole=" + displayThreshold);
log.debug("can't display predicate: '" + predicate.getURI() + "', domain="
+ predicate.getDomainVClassURI() + ", range="
+ predicate.getRangeVClassURI() + ", userRole="
+ userRole + ", thresholdRole=" + displayThreshold);
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
* (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
* least as high as the restriction level.
*/
public boolean canModifyPredicate(String predicateUri, RoleLevel userRole) {
if (predicateUri == null) {
log.debug("can't modify predicate: predicateUri was null");
public boolean canModifyPredicate(Property predicate, RoleLevel userRole) {
if (predicate == null || predicate.getURI() == null) {
log.debug("can't modify predicate: predicate was null");
return false;
}
if (modifyProhibitedNamespaces.contains(namespace(predicateUri))) {
if (modifyExceptionsAllowedUris.contains(predicateUri)) {
log.debug("'" + predicateUri + "' is a permitted exception");
if (modifyProhibitedNamespaces.contains(namespace(predicate.getURI()))) {
if (modifyExceptionsAllowedUris.contains(predicate.getURI())) {
log.debug("'" + predicate.getURI() + "' is a permitted exception");
} else {
log.debug("can't modify resource '" + predicateUri
log.debug("can't modify resource '" + predicate.getURI()
+ "': prohibited namespace: '"
+ namespace(predicateUri) + "'");
+ namespace(predicate.getURI()) + "'");
return false;
}
}
RoleLevel modifyThreshold = modifyThresholdMap.get(predicateUri);
RoleLevel modifyThreshold = getModifyThreshold(predicate);
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);
return true;
}
log.debug("can't modify predicate: '" + predicateUri + "', userRole="
+ userRole + ", thresholdRole=" + modifyThreshold);
log.debug("can't modify predicate: '" + predicate.getURI() + "', domain="
+ predicate.getDomainVClassURI() + ", range="
+ predicate.getRangeVClassURI() + ", userRole="
+ userRole + ", thresholdRole=" + modifyThreshold);
return false;
}
@ -422,7 +446,7 @@ public class PropertyRestrictionPolicyHelper {
throw new NullPointerException(
"display model has not been initialized.");
}
PropertyRestrictionPolicyHelper bean = PropertyRestrictionPolicyHelper
.createBean(model, displayModel);
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.PolicyIface;
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
@ -34,9 +35,9 @@ public abstract class AbstractRelationshipPolicy implements PolicyIface {
uri, RoleLevel.SELF);
}
protected boolean canModifyPredicate(String uri) {
protected boolean canModifyPredicate(Property predicate) {
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
uri, RoleLevel.SELF);
predicate, RoleLevel.SELF);
}
protected PolicyDecision cantModifyResource(String uri) {

View file

@ -2,9 +2,12 @@
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
public class RequestActionConstants {
public static String actionNamespace = "java:";
public static String SOME_URI = "?SOME_URI";
public static Property SOME_PREDICATE = new Property(SOME_URI);
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 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
@ -14,12 +15,16 @@ public abstract class AbstractDataPropertyStatementAction extends
AbstractPropertyStatementAction {
private final String subjectUri;
private final String predicateUri;
private final Property predicate;
public AbstractDataPropertyStatementAction(OntModel ontModel,
String subjectUri, String predicateUri) {
super(ontModel);
this.subjectUri = subjectUri;
this.predicateUri = predicateUri;
Property dataProperty = new Property();
dataProperty.setURI(predicateUri);
this.predicate = dataProperty;
}
public AbstractDataPropertyStatementAction(OntModel ontModel,
@ -28,12 +33,19 @@ public abstract class AbstractDataPropertyStatementAction extends
this.subjectUri = (dps.getIndividual() == null) ? dps
.getIndividualURI() : dps.getIndividual().getURI();
this.predicateUri = dps.getDatapropURI();
Property dataProperty = new Property();
dataProperty.setURI(predicateUri);
this.predicate = dataProperty;
}
public String getSubjectUri() {
return subjectUri;
}
public Property getPredicate() {
return predicate;
}
@Override
public String getPredicateUri() {
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 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
@ -13,14 +14,14 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
public abstract class AbstractObjectPropertyStatementAction extends
AbstractPropertyStatementAction {
private final String subjectUri;
private final String predicateUri;
private final Property predicate;
private final String objectUri;
public AbstractObjectPropertyStatementAction(OntModel ontModel, String subjectUri,
String predicateUri, String objectUri) {
Property predicate, String objectUri) {
super(ontModel);
this.subjectUri = subjectUri;
this.predicateUri = predicateUri;
this.predicate = predicate;
this.objectUri = objectUri;
}
@ -28,8 +29,7 @@ public abstract class AbstractObjectPropertyStatementAction extends
super(ontModel);
this.subjectUri = (ops.getSubject() == null) ? ops.getSubjectURI()
: ops.getSubject().getURI();
this.predicateUri = (ops.getProperty() == null) ? ops.getPropertyURI()
: ops.getProperty().getURI();
this.predicate = (ops.getProperty());
this.objectUri = (ops.getObject() == null) ? ops.getObjectURI() : ops
.getObject().getURI();
}
@ -42,9 +42,13 @@ public abstract class AbstractObjectPropertyStatementAction extends
return objectUri;
}
public Property getPredicate() {
return predicate;
}
@Override
public String getPredicateUri() {
return predicateUri;
return predicate.getURI();
}
@Override
@ -55,6 +59,6 @@ public abstract class AbstractObjectPropertyStatementAction extends
@Override
public String toString() {
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 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
@ -27,5 +28,7 @@ public abstract class AbstractPropertyStatementAction extends RequestedAction {
*/
public abstract String[] getResourceUris();
public abstract Property getPredicate();
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 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?
@ -12,8 +13,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
public class AddObjectPropertyStatement extends
AbstractObjectPropertyStatementAction {
public AddObjectPropertyStatement(OntModel ontModel, String uriOfSub,
String uriOfPred, String uriOfObj) {
super(ontModel, uriOfSub, uriOfPred, uriOfObj);
Property predicate, String uriOfObj) {
super(ontModel, uriOfSub, predicate, uriOfObj);
}
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 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
@ -13,7 +14,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
public class DropObjectPropertyStatement extends
AbstractObjectPropertyStatementAction {
public DropObjectPropertyStatement(OntModel ontModel, String sub,
String pred, String obj) {
Property pred, String 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 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?
@ -12,8 +13,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
public class EditObjectPropertyStatement extends
AbstractObjectPropertyStatementAction {
public EditObjectPropertyStatement(OntModel ontModel, String subjectUri,
String keywordPredUri, String objectUri) {
super(ontModel, subjectUri, keywordPredUri, objectUri);
Property keywordPred, String objectUri) {
super(ontModel, subjectUri, keywordPred, objectUri);
}
public EditObjectPropertyStatement(OntModel ontModel,

View file

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

View file

@ -15,11 +15,20 @@ public class Property extends BaseResourceBean {
private String groupURI = null;
private String label = null; // keep so can set in a context-specific way
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() {
this.groupURI = null;
this.label = null;
}
public Property(String URI) {
this.setURI(URI);
}
public String getCustomEntryForm() {
return customEntryForm;
@ -43,10 +52,53 @@ public class Property extends BaseResourceBean {
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() {
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.
* @author bdc34

View file

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

View file

@ -9,9 +9,11 @@ import java.io.PrintWriter;
import java.io.Writer;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.RequestDispatcher;
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.vitro.webapp.auth.permissions.SimplePermission;
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.rdfservice.RDFService;
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.impl.RDFServiceUtils;
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.
*
*
* @author bdc34
*
*/
public class SparqlQueryServlet extends BaseEditController {
private static final Log log = LogFactory.getLog(SparqlQueryServlet.class.getName());
private final static boolean CONVERT = true;
/**
* format configurations for SELECT queries.
*/
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.
*/
protected static HashMap<String,ModelFormatConfig> modelFormats =
new HashMap<String,ModelFormatConfig>();
private static ModelFormatConfig[] fmts = {
new ModelFormatConfig("RDF/XML", !CONVERT, ModelSerializationFormat.RDFXML, null, "application/rdf+xml" ),
new ModelFormatConfig("RDF/XML-ABBREV", CONVERT, ModelSerializationFormat.N3, "RDF/XML-ABBREV", "application/rdf+xml" ),
new ModelFormatConfig("N3", !CONVERT, ModelSerializationFormat.N3, null, "text/n3" ),
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" ) };
/**
* Use this map to decide which MIME type is suited for the "accept" header.
*/
public static final Map<String, Float> ACCEPTED_CONTENT_TYPES;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
@ -113,100 +108,85 @@ public class SparqlQueryServlet extends BaseEditController {
String queryParam = vreq.getParameter("query");
log.debug("queryParam was : " + queryParam);
String resultFormatParam = vreq.getParameter("resultFormat");
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 ) ) {
if( queryParam == null || "".equals(queryParam) ){
doHelp(request,response);
return;
}
executeQuery(response, resultFormatParam, rdfResultFormatParam,
queryParam, vreq.getUnfilteredRDFService());
String contentType = checkForContentType(vreq.getHeader("Accept"));
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;
}
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
* send the RDFService the same format as the rdfResultFormatParam
* 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,
RDFService rdfService, String resultFormatParam,
HttpServletResponse response) throws IOException, RDFServiceException{
RSFormatConfig config = rsFormats.get( resultFormatParam );
private void doSelect(HttpServletResponse response,
String queryParam,
RSFormatConfig formatConf,
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( config.responseMimeType );
InputStream results = rdfService.sparqlSelectQuery(queryParam, config.wireFormat );
pipe( results, response.getOutputStream() );
}else{
//always use JSON when conversion is needed.
InputStream results = rdfService.sparqlSelectQuery(queryParam, ResultFormat.JSON );
response.setContentType( config.responseMimeType );
ResultSet rs = ResultSetFactory.fromJSON( results );
OutputStream out = response.getOutputStream();
ResultSetFormatter.output(out, rs, config.jenaResponseFormat);
// } else {
// Writer out = response.getWriter();
// toCsv(out, results);
//}
response.setContentType( formatConf.responseMimeType );
ResultSet rs = ResultSetFactory.fromJSON( results );
OutputStream out = response.getOutputStream();
ResultSetFormatter.output(out, rs, formatConf.jenaResponseFormat);
}
} catch (RDFServiceException e) {
throw new ServletException("Cannot get result from the RDFService",e);
} catch (IOException e) {
throw new ServletException("Cannot perform SPARQL SELECT",e);
}
}
/**
* Execute the query and send the result to out. Attempt to
@ -217,40 +197,44 @@ public class SparqlQueryServlet extends BaseEditController {
* @throws RDFServiceException
* @throws
*/
private void doModelResultQuery( Query query,
RDFService rdfService, String rdfResultFormatParam,
HttpServletResponse response) throws IOException, RDFServiceException{
//config drives what formats and conversions to use
ModelFormatConfig config = modelFormats.get( rdfResultFormatParam );
InputStream rawResult = null;
if( query.isConstructType() ){
rawResult= rdfService.sparqlConstructQuery( query.toString(), config.wireFormat );
}else if ( query.isDescribeType() ){
rawResult = rdfService.sparqlDescribeQuery( query.toString(), config.wireFormat );
}
response.setContentType( config.responseMimeType );
if( config.converstionFromWireFormat ){
Model resultModel = RDFServiceUtils.parseModel( rawResult, config.wireFormat );
if( "JSON-LD".equals( config.jenaResponseFormat )){
//since jena 2.6.4 doesn't support JSON-LD we do it
try {
JenaRDFParser parser = new JenaRDFParser();
Object json = JSONLD.fromRDF(resultModel, parser);
JSONUtils.write(response.getWriter(), json);
} catch (JSONLDProcessingError e) {
throw new RDFServiceException("Could not convert from Jena model to JSON-LD", e);
private void doConstruct( HttpServletResponse response,
Query query,
ModelFormatConfig formatConfig,
RDFService rdfService
) throws ServletException{
try{
InputStream rawResult = null;
if( query.isConstructType() ){
rawResult= rdfService.sparqlConstructQuery( query.toString(), formatConfig.wireFormat );
}else if ( query.isDescribeType() ){
rawResult = rdfService.sparqlDescribeQuery( query.toString(), formatConfig.wireFormat );
}
response.setContentType( formatConfig.responseMimeType );
if( formatConfig.converstionFromWireFormat ){
Model resultModel = RDFServiceUtils.parseModel( rawResult, formatConfig.wireFormat );
if( "JSON-LD".equals( formatConfig.jenaResponseFormat )){
//since jena 2.6.4 doesn't support JSON-LD we do it
try {
JenaRDFParser parser = new JenaRDFParser();
Object json = JSONLD.fromRDF(resultModel, parser);
JSONUtils.write(response.getWriter(), json);
} catch (JSONLDProcessingError 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{
OutputStream out = response.getOutputStream();
resultModel.write(out, config.jenaResponseFormat );
pipe( rawResult, out );
}
}else{
OutputStream out = response.getOutputStream();
pipe( rawResult, out );
}catch( IOException ex){
throw new ServletException("could not run SPARQL CONSTRUCT",ex);
} 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);
}
/** 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 boolean converstionFromWireFormat;
public RDFService.ModelSerializationFormat wireFormat;
public String jenaResponseFormat;
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,
boolean converstionFromWireFormat,
@ -383,12 +389,20 @@ public class SparqlQueryServlet extends BaseEditController {
}
}
public static class RSFormatConfig{
public String valueFromForm;
public boolean converstionFromWireFormat;
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") };
public static class RSFormatConfig extends FormatConfig{
public ResultFormat wireFormat;
public ResultSetFormat jenaResponseFormat;
public String responseMimeType;
public RSFormatConfig( String valueFromForm,
boolean converstionFromWireFormat,
@ -403,14 +417,48 @@ public class SparqlQueryServlet extends BaseEditController {
}
}
static{
/* move the lists of configs into maps for easy lookup */
static{
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 ){
rsFormats.put( rsfc.valueFromForm, rsfc );
rsFormats.put( rsfc.responseMimeType, rsfc);
map.put(rsfc.responseMimeType, 1.0f);
}
for( ModelFormatConfig mfc : fmts ){
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) {
RequestedAction action = new EditObjectPropertyStatement(
vreq.getJenaOntModel(), individualUri,
RequestActionConstants.SOME_URI,
RequestActionConstants.SOME_PREDICATE,
RequestActionConstants.SOME_URI);
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.controller.Controllers;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
public class Classes2ClassesRetryController extends BaseEditController {
@ -43,7 +44,7 @@ public class Classes2ClassesRetryController extends BaseEditController {
action = epo.getAction();
}
VClassDao vcDao = request.getUnfilteredWebappDaoFactory().getVClassDao();
VClassDao vcDao = ModelAccess.on(getServletContext()).getWebappDaoFactory().getVClassDao();
epo.setDataAccessObject(vcDao);
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.validator.Validator;
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.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
@ -47,7 +48,13 @@ public class OntologyRetryController extends BaseEditController {
epo.setBeanClass(Ontology.class);
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();
epo.setDataAccessObject(oDao);
@ -67,13 +74,12 @@ public class OntologyRetryController extends BaseEditController {
epo.setOriginalBean(ontologyForEditing);
} else {
ontologyForEditing = (Ontology) epo.getNewBean();
action = "update";
log.error("using newBean");
}
//validators
List<Validator> validatorList = new ArrayList<Validator>();
validatorList.add(new RequiredFieldValidator());
validatorList.add(new UrlValidator());
epo.getValidatorMap().put("URI", validatorList);
//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.VitroRequest;
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.OntologyDao;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
@ -69,7 +70,8 @@ public class PropertyRetryController extends BaseEditController {
action = epo.getAction();
}
ObjectPropertyDao propDao = request.getUnfilteredWebappDaoFactory().getObjectPropertyDao();
ObjectPropertyDao propDao = ModelAccess.on(getServletContext()).getWebappDaoFactory().getObjectPropertyDao();
//getUnfilteredWebappDaoFactory().getObjectPropertyDao();
epo.setDataAccessObject(propDao);
OntologyDao ontDao = request.getUnfilteredWebappDaoFactory().getOntologyDao();
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.controller.Controllers;
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.VClassGroupDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
@ -44,7 +45,7 @@ public class VclassEditController extends BaseEditController {
EditProcessObject epo = super.createEpo(request, FORCE_NEW);
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"));
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
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.
VClassDao vcDao = request.getUnfilteredAssertionsWebappDaoFactory().getVClassDao();
// if supported, we want to show only the asserted superclasses and subclasses.
VClassDao vcDao = ModelAccess.on(getServletContext()).getBaseWebappDaoFactory().getVClassDao();
List superURIs = vcDao.getSuperClassURIs(vcl.getURI(),false);
List superVClasses = new ArrayList();
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.EditObjectPropertyStatement;
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.controller.VitroRequest;
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);
Individual entity = validateEntityUri(vreq);
String imageUri = entity.getMainImageUri();
Property indMainImage = new Property();
indMainImage.setURI(VitroVocabulary.IND_MAIN_IMAGE);
RequestedAction ra;
if (ACTION_DELETE.equals(action)
|| ACTION_DELETE_EDIT.equals(action)) {
ra = new DropObjectPropertyStatement(vreq.getJenaOntModel(),
entity.getURI(), VitroVocabulary.IND_MAIN_IMAGE,
entity.getURI(), indMainImage,
imageUri);
} else if (imageUri != null) {
ra = new EditObjectPropertyStatement(vreq.getJenaOntModel(),
entity.getURI(), VitroVocabulary.IND_MAIN_IMAGE,
entity.getURI(), indMainImage,
imageUri);
} else {
ra = new AddObjectPropertyStatement(vreq.getJenaOntModel(),
entity.getURI(), VitroVocabulary.IND_MAIN_IMAGE,
entity.getURI(), indMainImage,
RequestActionConstants.SOME_URI);
}
return new Actions(ra);

View file

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

View file

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

View file

@ -15,7 +15,7 @@ public interface ObjectPropertyDao extends PropertyDao {
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);

View file

@ -41,8 +41,8 @@ public interface ObjectPropertyStatementDao {
public Map<String, String> getMostSpecificTypesInClassgroupsForIndividual(String subjectUri);
List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri, String propertyUri, String objectKey, String rangeUri,
String queryString, Set<String> constructQueryStrings,
String subjectUri, String propertyUri, String objectKey, String domainUri,
String rangeUri, String queryString, Set<String> constructQueryStrings,
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 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_PUBLIC = "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:
@ -95,6 +98,9 @@ public class VitroVocabulary {
public static final String PROPERTY_CUSTOM_LIST_VIEW_ANNOT = vitroURI + "customListViewAnnot";
public static final String PROPERTY_SELECTFROMEXISTINGANNOT = vitroURI+"selectFromExistingAnnot";
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 PROPERTYGROUP = vitroURI + "PropertyGroup";
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);
}
public ObjectProperty getObjectPropertyByURIAndRangeURI(String objectPropertyURI, String rangeURI) {
ObjectProperty newOprop=innerObjectPropertyDao.getObjectPropertyByURIAndRangeURI(objectPropertyURI, rangeURI);
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI, String domainURI, String rangeURI) {
ObjectProperty newOprop=innerObjectPropertyDao.getObjectPropertyByURIs(objectPropertyURI, domainURI, rangeURI);
return (newOprop == null) ? null : new ObjectPropertyFiltering(newOprop, filters);
}

View file

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

View file

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

View file

@ -75,6 +75,9 @@ public class JenaBaseDaoCon {
protected AnnotationProperty PROPERTY_INPROPERTYGROUPANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_INPROPERTYGROUPANNOT);
protected AnnotationProperty PROPERTY_COLLATEBYSUBCLASSANNOT = _constModel.createAnnotationProperty(VitroVocabulary.PROPERTY_COLLATEBYSUBCLASSANNOT);
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);

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.StmtIterator;
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.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF;
@ -224,6 +225,13 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
Boolean collateBySubclass = getPropertyBooleanValue(op,PROPERTY_COLLATEBYSUBCLASSANNOT);
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);
if (groupRes != null) {
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);
if (op == null) {
if (op == null || rangeURI == null) {
return op;
}
op.setDomainVClassURI(domainURI);
op.setRangeVClassURI(rangeURI);
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 ?displayLevel ?updateLevel WHERE { \n" +
" ?context config:configContextFor <" + propertyURI + "> . \n" +
" ?context config:qualifiedBy <" + rangeURI + "> . \n" +
" ?context config:hasConfiguration ?configuration . \n" +
"SELECT ?range ?label ?group ?customForm ?displayRank ?displayLevel " +
" ?updateLevel ?editLinkSuppressed ?addLinkSuppressed ?deleteLinkSuppressed \n" +
" WHERE { \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: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:hiddenFromDisplayBelowRoleLevelAnnot ?displayLevel } \n" +
" OPTIONAL { ?configuration vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateLevel } \n" +
@ -314,6 +340,11 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
if (groupRes != null) {
op.setGroupURI(groupRes.getURI());
}
Literal displayRankLit = qsoln.getLiteral("displayRank");
if(displayRankLit != null) {
op.setDomainDisplayTier(
Integer.parseInt(displayRankLit.getLexicalForm()));
}
Resource displayLevelRes = qsoln.getResource("displayLevel");
if (displayLevelRes != null) {
op.setHiddenFromDisplayBelowRoleLevel(
@ -334,6 +365,18 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
if (customFormLit != null) {
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 {
qe.close();
@ -902,14 +945,14 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
protected static final String LIST_VIEW_CONFIG_FILE_QUERY_STRING =
"PREFIX display: <http://vitro.mannlib.cornell.edu/ontologies/display/1.1#> \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" +
" } UNION { \n" +
" ?lv config:listViewConfigFile ?filename . \n " +
" ?configuration config:hasListView ?lv . " +
" ?configuration config:listViewConfigFile ?filename . \n " +
" ?context config:hasConfiguration ?configuration . \n" +
" ?context config:configContextFor ?property . \n" +
" ?context config:qualifiedBy ?range . \n" +
" OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" +
" } \n" +
"}";
@ -925,14 +968,15 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
//TODO private void addPropertyClassCombinationsToListViewMap(HashMap)
// Map key is pair of object property and range class URI
// If range is unspecified, OWL.Thing.getURI() is used in the key.
Map<Pair<ObjectProperty, String>, String> customListViewConfigFileMap = null;
// Map key is inner pair of object property and range class URI,
// with first member of outer pair being a domain class URI.
// If domain or range is unspecified, OWL.Thing.getURI() is used in the key.
Map<Pair<String,Pair<ObjectProperty, String>>, String> customListViewConfigFileMap = null;
@Override
public String getCustomListViewConfigFileName(ObjectProperty op) {
if (customListViewConfigFileMap == null) {
customListViewConfigFileMap = new HashMap<Pair<ObjectProperty, String>, String>();
customListViewConfigFileMap = new HashMap<Pair<String,Pair<ObjectProperty, String>>, String>();
OntModel displayModel = getOntModelSelector().getDisplayModel();
//Get all property to list view config file mappings in the system
QueryExecution qexec = QueryExecutionFactory.create(listViewConfigFileQuery, displayModel);
@ -945,6 +989,10 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
String rangeUri = (rangeNode != null)
? ((Resource) rangeNode).getURI()
: OWL.Thing.getURI();
RDFNode domainNode = soln.get("domain");
String domainUri = (domainNode != null)
? ((Resource) domainNode).getURI()
: OWL.Thing.getURI();
ObjectProperty prop = getObjectPropertyByURI(propertyUri);
if (prop == null) {
//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 {
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();
}
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) {
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;

View file

@ -273,8 +273,7 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri,
String propertyUri,
String objectKey,
String rangeUri,
String objectKey, String domainUri, String rangeUri,
String queryString,
Set<String> constructQueryStrings,
String sortDirection) {
@ -282,11 +281,13 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
Model constructedModel = constructModelForSelectQueries(
subjectUri, propertyUri, constructQueryStrings);
if(log.isDebugEnabled()) {
log.debug("Constructed model has " + constructedModel.size() + " statements.");
}
if("desc".equalsIgnoreCase( sortDirection ) ){
queryString = queryString.replaceAll(" ASC\\(", " DESC(");
}
log.debug("Query string for object property " + propertyUri + ": " + queryString);
Query query = null;
try {
@ -300,10 +301,15 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("subject", ResourceFactory.createResource(subjectUri));
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));
}
log.debug("Query string for object property " + propertyUri + ": " + queryString);
// Run the SPARQL query to get the properties
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
DatasetWrapper w = dwf.getDatasetWrapper();
@ -353,13 +359,13 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
Model constructedModel = ModelFactory.createDefaultModel();
for (String queryString : constructQueries) {
queryString = queryString.replace("?subject", "<" + subjectUri + ">");
queryString = queryString.replace("?property", "<" + propertyUri + ">");
log.debug("CONSTRUCT query string for object property " +
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
// query parse step to improve debugging, depending on the error returned
// 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.LogFactory;
import com.hp.hpl.jena.ontology.IntersectionClass;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
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.Statement;
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.sparql.resultset.ResultSetMem;
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 {
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>() {{
put("afn", VitroVocabulary.AFN);
put("owl", VitroVocabulary.OWL);
@ -328,7 +331,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
public List <VClass> getClassesWithRestrictionOnProperty(String propertyURI) {
if (propertyURI == null) {
log.info("getClassesWithRestrictionOnProperty: called with null propertyURI");
log.warn("getClassesWithRestrictionOnProperty: called with null propertyURI");
return null;
}
@ -348,7 +351,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
Statement statement = stmtIter.next();
if ( statement.getSubject().canAs(OntClass.class) ) {
classURISet.addAll(getRelatedClasses(statement.getSubject().as(OntClass.class)));
classURISet.addAll(getRestrictedClasses(statement.getSubject().as(OntClass.class)));
} else {
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
* the given class.
*
* Find named classes to which a restriction "applies"
* @param resourceURI identifier of a class
* @return set of class URIs
*
@ -391,13 +392,12 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
* the ontology model.
*/
public HashSet<String> getRelatedClasses(OntClass ontClass) {
public HashSet<String> getRestrictedClasses(OntClass ontClass) {
HashSet<String> classSet = new HashSet<String>();
List<OntClass> classList = ontClass.listEquivalentClasses().toList();
classList.addAll(ontClass.listSubClasses().toList());
classList.addAll(ontClass.listSuperClasses().toList());
Iterator<OntClass> it = classList.iterator();
@ -406,6 +406,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
if (!oc.isAnon()) {
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;
}
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) {
List<PropertyInstance> propInsts = new ArrayList<PropertyInstance>();
@ -651,55 +682,52 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
String VClassURI = vclass.getURI();
OntClass ontClass = getOntClass(ontModel,VClassURI);
if (ontClass != null) {
List<OntClass> relatedClasses = new ArrayList<OntClass>();
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);
}
}
if (ontClass == null) {
continue;
}
}
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) {
log.error("Unable to get applicable properties " +
"by examining property restrictions and domains", e);
@ -718,12 +746,36 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
: (op.getRange() == null && foundRanges[1] != null)
? foundRanges[1]
: op.getRange();
propInsts.add(getPropInstForPropertyAndRange(op, rangeRes, applicableProperties));
List<String> additionalFauxSubpropertyRangeURIs = getAdditionalFauxSubpropertyRangeURIsForPropertyURI(propertyURI);
for (String rangeURI : additionalFauxSubpropertyRangeURIs) {
if (getWebappDaoFactory().getVClassDao().isSubClassOf(rangeURI, rangeRes.getURI())) {
propInsts.add(getPropInstForPropertyAndRange(
op, ResourceFactory.createResource(rangeURI), applicableProperties));
Resource domainRes = op.getDomain();
propInsts.add(getPropInst(
op, domainRes, rangeRes, applicableProperties));
List<Pair<String,String>> additionalFauxSubpropertyDomainAndRangeURIs =
getAdditionalFauxSubpropertyDomainAndRangeURIsForPropertyURI(
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,
Map<String, Resource[]> applicableProperties) {
private PropertyInstance getPropInst(OntProperty op, Resource domainRes, Resource rangeRes,
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();
String domainURIStr = getURIStr(op.getDomain());
if (rangeRes != null) {
String domainURIStr = (domainRes != null && !domainRes.isAnon()) ?
domainURIStr = domainRes.getURI()
: null;
if (rangeRes == null) {
pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above
} else {
String rangeClassURI;
if (rangeRes.isAnon()) {
rangeClassURI = PSEUDO_BNODE_NS + rangeRes.getId()
@ -757,18 +817,18 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
range.setName(range.getLocalName());
}
pi.setRangeClassName(range.getName());
} else {
pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above
}
pi.setDomainClassURI(domainURIStr);
VClass domain = getWebappDaoFactory().getVClassDao()
.getVClassByURI(domainURIStr);
if (domain == null) {
domain = new VClass();
domain.setURI(domainURIStr);
domain.setName(domain.getLocalName());
if (domainURIStr != null) {
VClass domain = getWebappDaoFactory().getVClassDao()
.getVClassByURI(domainURIStr);
if (domain == null) {
domain = new VClass();
domain.setURI(domainURIStr);
domain.setName(domain.getLocalName());
}
pi.setDomainClassName(domain.getName());
}
pi.setDomainClassName(domain.getName());
pi.setSubjectSide(true);
pi.setPropertyURI(op.getURI());
pi.setPropertyName(getLabelOrId(op)); // TODO
@ -777,14 +837,15 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
return pi;
}
private List<String> getAdditionalFauxSubpropertyRangeURIsForPropertyURI(String propertyURI) {
List<String> rangeURIs = new ArrayList<String>();
private List<Pair<String,String>> getAdditionalFauxSubpropertyDomainAndRangeURIsForPropertyURI(String propertyURI) {
List<Pair<String,String>> domainAndRangeURIs = new ArrayList<Pair<String,String>>();
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 WHERE { \n" +
"SELECT ?domain ?range WHERE { \n" +
" ?context config:configContextFor <" + propertyURI + "> . \n" +
" ?context config:qualifiedBy ?range . \n" +
" OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" +
"}";
Query q = QueryFactory.create(propQuery);
@ -794,12 +855,18 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
while (rs.hasNext()) {
QuerySolution qsoln = rs.nextSolution();
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 {
qe.close();
}
return rangeURIs;
return domainAndRangeURIs;
}
private String getURIStr(Resource res) {

View file

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

View file

@ -2,10 +2,15 @@
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.LogFactory;
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.Resource;
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 (!isSynchronizing) {
if (foreground) {
log.debug("Running Pellet in foreground.");
(new PelletSynchronizer()).run();
} else {
log.debug("Running Pellet in background.");
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.
* 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 also ignores "owl:inverseOf."
* It ignores domain and range "axioms," on the assumption that they are not truly axioms but editing constraints.
*/
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.rest,null));
defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,OWL.disjointWith,null));
defaultInferenceDrivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,OWL.inverseOf,null));
DEFAULT.setInferenceDrivingPatternAllowSet(defaultInferenceDrivingPatternAllowSet);
Set<ObjectPropertyStatementPattern> defaultInferenceReceivingPatternAllowSet = new HashSet<ObjectPropertyStatementPattern>();
defaultInferenceReceivingPatternAllowSet.add(ObjectPropertyStatementPatternFactory.getPattern(null,RDF.type,null));

View file

@ -53,12 +53,22 @@ public class EditConfigurationUtils {
return vreq.getParameter("objectUri");
}
public static String getDomainUri(VitroRequest vreq) {
return vreq.getParameter("domainUri");
}
public static String getRangeUri(VitroRequest vreq) {
return vreq.getParameter("rangeUri");
}
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

View file

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

View file

@ -99,41 +99,60 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
return getDefaultObjectEditConfiguration(vreq, session);
}
protected List<String> getRangeTypes(VitroRequest vreq) {
WebappDaoFactory wDaoFact = vreq.getWebappDaoFactory();
List<String> types = new ArrayList<String>();
protected List<VClass> getRangeTypes(VitroRequest vreq) {
// This first part 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();
List<VClass> types = new ArrayList<VClass>();
Individual subject = EditConfigurationUtils.getSubjectIndividual(vreq);
String predicateUri = EditConfigurationUtils.getPredicateUri(vreq);
String rangeUri = EditConfigurationUtils.getRangeUri(vreq);
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;
}
WebappDaoFactory wDaoFact = vreq.getWebappDaoFactory();
//Get all vclasses applicable to subject
List<VClass> vClasses = subject.getVClasses();
HashSet<String> typesHash = new HashSet<String>();
HashMap<String, VClass> typesHash = new HashMap<String, VClass>();
for(VClass vclass: vClasses) {
List<VClass> rangeVclasses = wDaoFact.getVClassDao().getVClassesForProperty(vclass.getURI(),predicateUri);
if(rangeVclasses != null) {
for(VClass range: rangeVclasses) {
//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;
}
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());
List<String> types = new ArrayList<String>();
//empty list means the range is not set to anything, force Thing
if(types.size() == 0 ){
types = new ArrayList<String>();
types.add(VitroVocabulary.OWL_THING);
}
if(types.size() == 0 ){
types.add(VitroVocabulary.OWL_THING);
} else {
for (VClass vclass : rangeTypes) {
if (vclass.getURI() != null) {
types.add(vclass.getURI());
}
}
}
long count = 0;
for( String type:types){
@ -184,7 +203,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
this.setSparqlQueries(editConfiguration);
//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
//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);
}
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();
field.setName("objectVar");
@ -370,7 +389,7 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
field.setOptions( new IndividualsViaObjectPropetyOptions(
subjectUri,
predicateUri,
rangeUri,
rangeTypes,
objectUri));
}else{
field.setOptions(null);
@ -441,14 +460,22 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
formSpecificData.put("editMode", getEditMode(vreq).toString().toLowerCase());
//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
//In this case, set an empty array
if(types.size() == 1 && types.get(0).equals(VitroVocabulary.OWL_THING) ){
types = new ArrayList<String>();
if(types.size() == 1 && types.get(0).getURI().equals(VitroVocabulary.OWL_THING) ){
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
if(EditConfigurationUtils.getObjectIndividual(vreq) != null) {
@ -464,15 +491,15 @@ public class DefaultObjectPropertyFormGenerator implements EditConfigurationGene
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());
boolean rangeIndividualsFound = false;
for( String type:types){
for( VClass type:types){
//solr for type count.
SolrQuery query = new SolrQuery();
query.setQuery( VitroSearchTermNames.RDFTYPE + ":" + type);
query.setQuery( VitroSearchTermNames.RDFTYPE + ":" + type.getURI());
query.setRows(0);
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.AddObjectPropertyStatement;
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.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.edit.n3editing.VTwo.EditConfigurationUtils;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.EditConfigurationVTwo;
@ -272,7 +274,7 @@ public class ManageLabelsForIndividualGenerator extends BaseEditConfigurationGen
RequestActionConstants.SOME_URI);
AddObjectPropertyStatement aops = new AddObjectPropertyStatement(
vreq.getJenaOntModel(), individual.getURI(),
RequestActionConstants.SOME_URI,
RequestActionConstants.SOME_PREDICATE,
RequestActionConstants.SOME_URI);
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
//Create label information instance with the required information
//To generate link
DataPropertyStatementTemplateModel dpstm = new DataPropertyStatementTemplateModel(subjectUri, propertyUri, l,
template, vreq);
DataPropertyStatementTemplateModel dpstm = new DataPropertyStatementTemplateModel(
subjectUri, new Property(propertyUri), l, template, vreq);
labelsList.add(new LabelInformation(
l, dpstm.getEditUrl(), dpstm.getDeleteUrl(), languageTag, languageName));
}

View file

@ -171,6 +171,9 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
makeEditConfigurationVTwo( editConfGeneratorName, vreq, session);
}
if(editConfig == null) {
log.error("editConfig is null! How did this happen?");
}
String editKey = EditConfigurationUtils.getEditKey(vreq);
editConfig.setEditKey(editKey);
@ -199,6 +202,7 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
String editConfGeneratorName = null;
String predicateUri = getPredicateUri(vreq);
String domainUri = EditConfigurationUtils.getDomainUri(vreq);
String rangeUri = EditConfigurationUtils.getRangeUri(vreq);
// *** 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
}else if( predicateUri != null && !predicateUri.isEmpty() ){
Property prop = getProperty( predicateUri, vreq);
Property prop = getProperty( predicateUri, domainUri, rangeUri, vreq);
if (prop != null && rangeUri != null) {
editConfGeneratorName = getCustomEntryFormForPropertyAndRange(prop, rangeUri);
editConfGeneratorName = getCustomEntryForm(prop);
} else if( prop != null && prop.getCustomEntryForm() != null ){
//there is a custom form, great! let's use it.
editConfGeneratorName = prop.getCustomEntryForm();
@ -247,25 +251,19 @@ public class EditRequestDispatchController extends FreemarkerHttpServlet {
return editConfGeneratorName;
}
private String getCustomEntryFormForPropertyAndRange(Property prop, String rangeUri){
String entryFormName = null;
// = ApplicationConfigurationOntologyUtils.getEntryForm(prop.getURI(), rangeUri);
if (entryFormName == null) {
if (prop.getCustomEntryForm() != null) {
return prop.getCustomEntryForm();
} else {
return DEFAULT_OBJ_FORM;
}
private String getCustomEntryForm(Property prop){
if (prop.getCustomEntryForm() == null) {
return DEFAULT_OBJ_FORM;
} else {
prop.setCustomEntryForm(entryFormName);
return entryFormName;
return prop.getCustomEntryForm();
}
}
private Property getProperty(String predicateUri, VitroRequest vreq) {
private Property getProperty(String predicateUri, String domainUri, String rangeUri, VitroRequest vreq) {
Property p = null;
try{
p = vreq.getWebappDaoFactory().getObjectPropertyDao().getObjectPropertyByURI(predicateUri);
p = vreq.getWebappDaoFactory().getObjectPropertyDao().getObjectPropertyByURIs(
predicateUri, domainUri, rangeUri);
if(p == null) {
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.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
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.Model;
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.vocabulary.OWL;
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.rdfservice.RDFService;
/**
* 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 {
private final Log log = LogFactory.getLog(ABoxUpdater.class);
private OntModel oldTboxModel;
private OntModel newTboxModel;
private OntModel aboxModel;
private Dataset dataset;
private RDFService rdfService;
private OntModel newTBoxAnnotationsModel;
private TBoxUpdater tboxUpdater;
private ChangeLogger logger;
private ChangeRecord record;
private OntClass OWL_THING = (ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM)).createClass(OWL.Thing.getURI());
@ -55,19 +62,19 @@ public class ABoxUpdater {
* and the retractions model.
*
*/
public ABoxUpdater(OntModel oldTboxModel,
OntModel newTboxModel,
OntModel aboxModel,
OntModel newAnnotationsModel,
public ABoxUpdater(UpdateSettings settings,
ChangeLogger logger,
ChangeRecord record) {
this.oldTboxModel = oldTboxModel;
this.newTboxModel = newTboxModel;
this.aboxModel = aboxModel;
this.newTBoxAnnotationsModel = newAnnotationsModel;
this.oldTboxModel = settings.getOldTBoxModel();
this.newTboxModel = settings.getNewTBoxModel();
RDFService rdfService = settings.getRDFService();
this.dataset = new RDFServiceDataset(rdfService);
this.rdfService = rdfService;
this.newTBoxAnnotationsModel = settings.getNewTBoxAnnotationsModel();
this.logger = logger;
this.record = record;
this.tboxUpdater = new TBoxUpdater(settings, logger, record);
}
/**
@ -124,68 +131,75 @@ public class ABoxUpdater {
public void renameClass(AtomicOntologyChange change) throws IOException {
//logger.log("Processing a class rename from: " + change.getSourceURI() + " to " + change.getDestinationURI());
aboxModel.enterCriticalSection(Lock.WRITE);
try {
Model additions = ModelFactory.createDefaultModel();
Model retractions = ModelFactory.createDefaultModel();
//TODO - look for these in the models and log error if not found
Resource oldClass = ResourceFactory.createResource(change.getSourceURI());
Resource newClass = ResourceFactory.createResource(change.getDestinationURI());
// Change class references in the subjects of statements
// BJL 2010-04-09 : In future versions we need to keep track of
// the difference between true direct renamings and "use-insteads."
// For now, the best behavior is to remove any remaining statements
// where the old class is the subject, *unless* the statements
// is part of the new annotations file (see comment below) or the
// predicate is vitro:autolinkedToTab. In the latter case,
// the autolinking annotation should be rewritten using the
// new class name.
StmtIterator iter = aboxModel.listStatements(oldClass, (Property) null, (RDFNode) null);
int removeCount = 0;
while (iter.hasNext()) {
Statement oldStatement = iter.next();
removeCount++;
retractions.add(oldStatement);
}
//log summary of changes
if (removeCount > 0) {
logger.log("Removed " + removeCount + " subject reference" + ((removeCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class");
}
// Change class references in the objects of rdf:type statements
iter = aboxModel.listStatements((Resource) null, RDF.type, oldClass);
int renameCount = 0;
while (iter.hasNext()) {
renameCount++;
Statement oldStatement = iter.next();
Statement newStatement = ResourceFactory.createStatement(oldStatement.getSubject(), RDF.type, newClass);
retractions.add(oldStatement);
additions.add(newStatement);
}
//log summary of changes
if (renameCount > 0) {
logger.log("Retyped " + renameCount + " individual" + ((renameCount > 1) ? "s" : "") + " from type " + oldClass.getURI() + " to type " + newClass.getURI());
}
aboxModel.remove(retractions);
record.recordRetractions(retractions);
aboxModel.add(additions);
record.recordAdditions(additions);
} finally {
aboxModel.leaveCriticalSection();
}
Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
String graph = graphIt.next();
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
}
Model aboxModel = dataset.getNamedModel(graph);
aboxModel.enterCriticalSection(Lock.WRITE);
try {
Model additions = ModelFactory.createDefaultModel();
Model retractions = ModelFactory.createDefaultModel();
//TODO - look for these in the models and log error if not found
Resource oldClass = ResourceFactory.createResource(change.getSourceURI());
Resource newClass = ResourceFactory.createResource(change.getDestinationURI());
// Change class references in the subjects of statements
// BJL 2010-04-09 : In future versions we need to keep track of
// the difference between true direct renamings and "use-insteads."
// For now, the best behavior is to remove any remaining statements
// where the old class is the subject, *unless* the statements
// is part of the new annotations file (see comment below) or the
// predicate is vitro:autolinkedToTab. In the latter case,
// the autolinking annotation should be rewritten using the
// new class name.
StmtIterator iter = aboxModel.listStatements(oldClass, (Property) null, (RDFNode) null);
int removeCount = 0;
while (iter.hasNext()) {
Statement oldStatement = iter.next();
removeCount++;
retractions.add(oldStatement);
}
//log summary of changes
if (removeCount > 0) {
logger.log("Removed " + removeCount + " subject reference" + ((removeCount > 1) ? "s" : "") + " to the " + oldClass.getURI() + " class");
}
// Change class references in the objects of rdf:type statements
iter = aboxModel.listStatements((Resource) null, RDF.type, oldClass);
int renameCount = 0;
while (iter.hasNext()) {
renameCount++;
Statement oldStatement = iter.next();
Statement newStatement = ResourceFactory.createStatement(oldStatement.getSubject(), RDF.type, newClass);
retractions.add(oldStatement);
additions.add(newStatement);
}
//log summary of changes
if (renameCount > 0) {
logger.log("Retyped " + renameCount + " individual" + ((renameCount > 1) ? "s" : "") + " from type " + oldClass.getURI() + " to type " + newClass.getURI());
}
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)) {
StmtIterator stmtIter = aboxModel.listStatements(null, RDF.type, parentOfAddedClass);
int count = stmtIter.toList().size();
if (count > 0) {
String indList = "";
while (stmtIter.hasNext()) {
Statement stmt = stmtIter.next();
indList += "\n\t" + stmt.getSubject().getURI();
}
Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
String graph = graphIt.next();
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
}
Model aboxModel = dataset.getNamedModel(graph);
StmtIterator stmtIter = aboxModel.listStatements(null, RDF.type, parentOfAddedClass);
int count = stmtIter.toList().size();
if (count > 0) {
//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() + "," +
" 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() );
}
}
}
}
}
}
@ -330,25 +346,33 @@ public class ABoxUpdater {
}
// Remove instances of the deleted class
aboxModel.enterCriticalSection(Lock.WRITE);
try {
int count = 0;
int refCount = 0;
StmtIterator iter = aboxModel.listStatements((Resource) null, RDF.type, deletedClass);
while (iter.hasNext()) {
count++;
Statement typeStmt = iter.next();
refCount = deleteIndividual(typeStmt.getSubject());
}
if (count > 0) {
logger.log("Removed " + count + " individual" + (((count > 1) ? "s" : "") + " of type " + deletedClass.getURI()) + " (refs = " + refCount + ")");
}
} finally {
aboxModel.leaveCriticalSection();
}
Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
String graph = graphIt.next();
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
}
Model aboxModel = dataset.getNamedModel(graph);
aboxModel.enterCriticalSection(Lock.WRITE);
try {
int count = 0;
int refCount = 0;
StmtIterator iter = aboxModel.listStatements((Resource) null, RDF.type, deletedClass);
while (iter.hasNext()) {
count++;
Statement typeStmt = iter.next();
refCount = deleteIndividual(typeStmt.getSubject());
}
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 {
@ -356,29 +380,37 @@ public class ABoxUpdater {
Model retractions = ModelFactory.createDefaultModel();
int refCount = 0;
aboxModel.enterCriticalSection(Lock.WRITE);
try {
StmtIterator iter = aboxModel.listStatements(individual, (Property) null, (RDFNode) null);
while (iter.hasNext()) {
Statement subjstmt = iter.next();
retractions.add(subjstmt);
}
iter = aboxModel.listStatements((Resource) null, (Property) null, individual);
while (iter.hasNext()) {
Statement objstmt = iter.next();
retractions.add(objstmt);
refCount++;
}
aboxModel.remove(retractions);
record.recordRetractions(retractions);
} finally {
aboxModel.leaveCriticalSection();
}
Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
String graph = graphIt.next();
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
}
Model aboxModel = dataset.getNamedModel(graph);
aboxModel.enterCriticalSection(Lock.WRITE);
try {
StmtIterator iter = aboxModel.listStatements(individual, (Property) null, (RDFNode) null);
while (iter.hasNext()) {
Statement subjstmt = iter.next();
retractions.add(subjstmt);
}
iter = aboxModel.listStatements((Resource) null, (Property) null, individual);
while (iter.hasNext()) {
Statement objstmt = iter.next();
retractions.add(objstmt);
refCount++;
}
aboxModel.remove(retractions);
record.recordRetractions(retractions);
} finally {
aboxModel.leaveCriticalSection();
}
}
return refCount;
}
@ -388,20 +420,33 @@ public class ABoxUpdater {
Iterator<AtomicOntologyChange> propItr = changes.iterator();
while(propItr.hasNext()){
AtomicOntologyChange propChangeObj = propItr.next();
switch (propChangeObj.getAtomicChangeType()){
case ADD:
addProperty(propChangeObj);
break;
case DELETE:
deleteProperty(propChangeObj);
break;
case RENAME:
renameProperty(propChangeObj);
break;
default:
logger.logError("unexpected change type indicator: " + propChangeObj.getAtomicChangeType());
break;
}
log.debug("processing " + propChangeObj);
try {
if (propChangeObj.getAtomicChangeType() == null) {
log.error("Missing change type; skipping " + propChangeObj);
continue;
}
switch (propChangeObj.getAtomicChangeType()){
case ADD:
log.debug("add");
addProperty(propChangeObj);
break;
case DELETE:
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) {
Model additions = ModelFactory.createDefaultModel();
aboxModel.enterCriticalSection(Lock.WRITE);
try {
StmtIterator iter = aboxModel.listStatements((Resource) null, inverseOfAddedProperty, (RDFNode) null);
while (iter.hasNext()) {
Statement stmt = iter.next();
if (stmt.getObject().isResource()) {
Statement newStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), addedProperty, stmt.getSubject());
additions.add(newStmt);
} else {
logger.log("WARNING: expected the object of this statement to be a Resource but it is not. No inverse has been asserted: " + stmtString(stmt));
}
}
aboxModel.add(additions);
record.recordAdditions(additions);
if (additions.size() > 0) {
logger.log("Added " + additions.size() + " statement" +
((additions.size() > 1) ? "s" : "") +
" with predicate " + addedProperty.getURI() +
" (as an inverse to existing " + inverseOfAddedProperty.getURI() +
" statement" + ((additions.size() > 1) ? "s" : "") + ")");
}
} finally {
aboxModel.leaveCriticalSection();
}
Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
String graph = graphIt.next();
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
}
Model aboxModel = dataset.getNamedModel(graph);
aboxModel.enterCriticalSection(Lock.WRITE);
try {
StmtIterator iter = aboxModel.listStatements((Resource) null, inverseOfAddedProperty, (RDFNode) null);
while (iter.hasNext()) {
Statement stmt = iter.next();
if (stmt.getObject().isResource()) {
Statement newStmt = ResourceFactory.createStatement(stmt.getObject().asResource(), addedProperty, stmt.getSubject());
additions.add(newStmt);
} else {
logger.log("WARNING: expected the object of this statement to be a Resource but it is not. No inverse has been asserted: " + stmtString(stmt));
}
}
aboxModel.add(additions);
record.recordAdditions(additions);
if (additions.size() > 0) {
logger.log("Added " + additions.size() + " statement" +
((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();
if (replacementProperty == null) {
aboxModel.enterCriticalSection(Lock.WRITE);
try {
deletePropModel.add(aboxModel.listStatements((Resource) null, deletedProperty, (RDFNode) null));
aboxModel.remove(deletePropModel);
} finally {
aboxModel.leaveCriticalSection();
}
record.recordRetractions(deletePropModel);
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);
}
Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
String graph = graphIt.next();
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
}
Model aboxModel = dataset.getNamedModel(graph);
Model deletePropModel = ModelFactory.createDefaultModel();
if (replacementProperty == null) {
aboxModel.enterCriticalSection(Lock.WRITE);
try {
deletePropModel.add(aboxModel.listStatements((Resource) null, deletedProperty, (RDFNode) null));
aboxModel.remove(deletePropModel);
} finally {
aboxModel.leaveCriticalSection();
}
record.recordRetractions(deletePropModel);
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 {
//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 newProperty = newTboxModel.getOntProperty(propObj.getDestinationURI());
@ -533,35 +594,46 @@ public class ABoxUpdater {
return;
}
Model renamePropAddModel = ModelFactory.createDefaultModel();
Model renamePropRetractModel = ModelFactory.createDefaultModel();
Iterator<String> graphIt = dataset.listNames();
while(graphIt.hasNext()) {
String graph = graphIt.next();
if(!KnowledgeBaseUpdater.isUpdatableABoxGraph(graph)){
continue;
}
Model aboxModel = dataset.getNamedModel(graph);
aboxModel.enterCriticalSection(Lock.WRITE);
try {
renamePropRetractModel.add( aboxModel.listStatements(
(Resource) null, oldProperty, (RDFNode) null));
StmtIterator stmItr = renamePropRetractModel.listStatements();
while(stmItr.hasNext()) {
Statement tempStatement = stmItr.nextStatement();
renamePropAddModel.add( tempStatement.getSubject(),
newProperty,
tempStatement.getObject() );
}
aboxModel.remove(renamePropRetractModel);
aboxModel.add(renamePropAddModel);
} finally {
aboxModel.leaveCriticalSection();
}
record.recordAdditions(renamePropAddModel);
record.recordRetractions(renamePropRetractModel);
if (renamePropRetractModel.size() > 0) {
logger.log("Changed " + renamePropRetractModel.size() + " statement" +
((renamePropRetractModel.size() > 1) ? "s" : "") +
" with predicate " + propObj.getSourceURI() + " to use " +
propObj.getDestinationURI() + " instead");
}
Model renamePropAddModel = ModelFactory.createDefaultModel();
Model renamePropRetractModel = ModelFactory.createDefaultModel();
aboxModel.enterCriticalSection(Lock.WRITE);
try {
renamePropRetractModel.add( aboxModel.listStatements(
(Resource) null, oldProperty, (RDFNode) null));
StmtIterator stmItr = renamePropRetractModel.listStatements();
while(stmItr.hasNext()) {
Statement tempStatement = stmItr.nextStatement();
renamePropAddModel.add( tempStatement.getSubject(),
newProperty,
tempStatement.getObject() );
}
aboxModel.remove(renamePropRetractModel);
aboxModel.add(renamePropAddModel);
} finally {
aboxModel.leaveCriticalSection();
}
record.recordAdditions(renamePropAddModel);
record.recordRetractions(renamePropRetractModel);
if (renamePropRetractModel.size() > 0) {
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 {

View file

@ -30,6 +30,11 @@ public class AtomicOntologyChange {
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

View file

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

View file

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

View file

@ -9,6 +9,8 @@ import java.util.ArrayList;
import java.util.List;
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.SimpleReader;
@ -23,6 +25,8 @@ import edu.cornell.mannlib.vitro.webapp.ontology.update.AtomicOntologyChange.Ato
public class OntologyChangeParser {
private final Log log = LogFactory.getLog(OntologyChangeParser.class);
private ChangeLogger logger;
public OntologyChangeParser(ChangeLogger logger) {
@ -85,6 +89,8 @@ public class OntologyChangeParser {
}
log.debug(changeObj);
changeObjects.add(changeObj);
}

View file

@ -26,6 +26,9 @@ public class SimpleChangeRecord implements ChangeRecord {
private File additionsFile;
private File retractionsFile;
private int additionsCount = 0;
private int retractionsCount = 0;
public SimpleChangeRecord(
String additionsFile, String retractionsFile) {
this.additionsFile = new File(additionsFile);
@ -46,11 +49,12 @@ public class SimpleChangeRecord implements ChangeRecord {
public void recordAdditions(Model incrementalAdditions) {
additionsModel.add(incrementalAdditions);
additionsCount += incrementalAdditions.size();
}
public void recordRetractions(Model incrementalRetractions) {
retractionsModel.add(incrementalRetractions);
retractionsCount += incrementalRetractions.size();
}
private void write(Model model, File file) {
@ -71,5 +75,9 @@ public class SimpleChangeRecord implements ChangeRecord {
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;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
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.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.Model;
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.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock;
@ -21,398 +33,542 @@ import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
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 {
private OntModel oldTboxAnnotationsModel;
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 static final Log log = LogFactory.getLog(TBoxUpdater.class);
/**
*
* Constructor
*
* @param oldTboxAnnotationsModel - previous version of the annotations in the ontology
* @param newTboxAnnotationsModel - new version of the annotations in the ontology
* @param siteModel - the knowledge base to be updated
* @param logger - for writing to the change log
* and the error log.
* @param record - for writing to the additions model
* and the retractions model.
*
*/
public TBoxUpdater(OntModel oldTboxAnnotationsModel,
OntModel newTboxAnnotationsModel,
OntModel siteModel,
ChangeLogger logger,
ChangeRecord record) {
this.oldTboxAnnotationsModel = oldTboxAnnotationsModel;
this.newTboxAnnotationsModel = newTboxAnnotationsModel;
this.siteModel = siteModel;
this.logger = logger;
this.record = record;
}
/**
*
* 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
* knowledge base to be updated are provided in the class constructor and are
* referenced via class level variables.
*
* If the default value (i.e. the value that is provided in the vivo-core
* annotations files) of a vitro annotation property has been changed for a vivo
* 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
* 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.
* If a property setting for a class exists in the old ontology but
* 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
* knowledge base.
*
* 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 {
siteModel.enterCriticalSection(Lock.WRITE);
try {
Model additions = ModelFactory.createDefaultModel();
Model retractions = ModelFactory.createDefaultModel();
// 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
// the site hasn't overidden the previous default in their knowledge base.
StmtIterator iter = oldTboxAnnotationsModel.listStatements();
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) {
/*
private UpdateSettings settings;
private OntModel oldTboxAnnotationsModel;
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);
/**
*
* Constructor
*
* @param oldTboxAnnotationsModel - previous version of the annotations in the ontology
* @param newTboxAnnotationsModel - new version of the annotations in the ontology
* @param siteModel - the knowledge base to be updated
* @param logger - for writing to the change log
* and the error log.
* @param record - for writing to the additions model
* and the retractions model.
*
*/
public TBoxUpdater(UpdateSettings settings,
ChangeLogger logger,
ChangeRecord record) {
this.settings = settings;
this.oldTboxAnnotationsModel = settings.getOldTBoxAnnotationsModel();
this.newTboxAnnotationsModel = settings.getNewTBoxAnnotationsModel();
this.siteModel = settings.getAssertionOntModelSelector().getTBoxModel();
this.logger = logger;
this.record = record;
}
/**
* Update application ontology data for domain and range-qualified properties
* to use any applicable settings from obsolete subproperties
*/
public void modifyPropertyQualifications() throws IOException {
}
private Model mergeConfigurations(Model oldConfig, Model newConfig) {
return null;
}
public void updateDefaultAnnotationValues() throws IOException {
updateDefaultAnnotationValues(null);
}
/**
*
* 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
* knowledge base to be updated are provided in the class constructor and are
* referenced via class level variables.
*
* If the default value (i.e. the value that is provided in the vivo-core
* annotations files) of a vitro annotation property has been changed for a vivo
* 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
* 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.
* If a property setting for a class exists in the old ontology but
* 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
* knowledge base.
*
* 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(String subjectURI) throws IOException {
siteModel.enterCriticalSection(Lock.WRITE);
try {
Model additions = ModelFactory.createDefaultModel();
Model retractions = ModelFactory.createDefaultModel();
// 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
// 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() +
" statements with subject = " + subject.getURI() +
" and property = " + predicate.getURI() +
" in the site database (maximum of one is expected)");
*/
}
if (siteObjects.size() > 0) {
RDFNode siteNode = siteObjects.get(0);
if (siteNode.equals(oldObject)) {
retractions.add(siteModel.listStatements(subject, predicate, (RDFNode) null));
}
}
continue;
}
RDFNode newObject = newObjects.next();
int i = 1;
while (newObjects.hasNext()) {
i++;
newObjects.next();
}
if (i > 1) {
/*
*/
}
if (siteObjects.size() > 0) {
RDFNode siteNode = siteObjects.get(0);
if (siteNode.equals(oldObject)) {
retractions.add(siteModel.listStatements(subject, predicate, (RDFNode) null));
}
}
continue;
}
RDFNode newObject = newObjects.next();
int i = 1;
while (newObjects.hasNext()) {
i++;
newObjects.next();
}
if (i > 1) {
/*
logger.log("WARNING: found " + i +
" statements with subject = " + subject.getURI() +
" and property = " + predicate.getURI() +
" in the new version of the annotations ontology (maximum of one is expected)");
*/
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)) {
*/
continue;
}
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;
while (siteObjects.hasNext()) {
i++;
siteObjects.next();
}
NodeIterator siteObjects = siteModel.listObjectsOfProperty(subject,predicate);
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 +
" statements with subject = " + subject.getURI() +
" and property = " + predicate.getURI() +
" in the site annotations model (maximum of one is expected) ");
*/
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());
}
*/
continue;
}
try {
additions.add(subject, predicate, newObject);
if (detailLogs) {
logger.log("Changed the value of property " + predicate.getURI() +
" of subject = " + subject.getURI() +
" 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());
}
}
}
}
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.
//
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());
}
Model newAnnotationSettings = newTboxAnnotationsModel.difference(oldTboxAnnotationsModel);
Model newAnnotationSettingsToAdd = ModelFactory.createDefaultModel();
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();
}
try {
additions.add(subject, predicate, newObject);
// If we were going to handle add, this is the logic:
// for each ClassGroup in new old vitro annotations model: if it is not in
// the old vitro annotations and it is not in the site model, then
// add it.
}
if (detailLogs) {
logger.log("Changed the value of property " + predicate.getURI() +
" of subject = " + subject.getURI() +
" 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.enterCriticalSection(Lock.READ);
try {
return (model.contains((Resource) null, inClassGroupProp, theClassGroup) ? true : false);
} finally {
model.leaveCriticalSection();
}
}
Model actualAdditions = additions.difference(retractions);
siteModel.add(actualAdditions);
record.recordAdditions(actualAdditions);
Model actualRetractions = retractions.difference(additions);
siteModel.remove(actualRetractions);
record.recordRetractions(actualRetractions);
public void removeObsoleteAnnotations() throws IOException {
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");
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)");
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);
Model newAnnotationSettingsToAdd = ModelFactory.createDefaultModel();
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) ) {
retractions.add(subj2, inPropertyGroupProp, obj2);
logger.log("Removed statement " + ABoxUpdater.stmtString(subj2, inPropertyGroupProp, obj2) + " from the knowledge base (assumed to be obsolete)");
}
// If we were going to handle add, this is the logic:
// for each ClassGroup in new old vitro annotations model: if it is not in
// 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);
record.recordRetractions(retractions);
}
} finally {
siteModel.leaveCriticalSection();
}
}
}
public void removeObsoleteAnnotations() throws IOException {
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");
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 edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
public class UpdateSettings {
@ -20,6 +21,7 @@ public class UpdateSettings {
private String errorLogFile;
private String addedDataFile;
private String removedDataFile;
private String qualifiedPropertyConfigFile;
private String defaultNamespace;
private OntModelSelector assertionOntModelSelector;
private OntModelSelector inferenceOntModelSelector;
@ -37,6 +39,8 @@ public class UpdateSettings {
private OntModel newDisplayModelFromFile;
private OntModel loadedAtStartupDisplayModel;
private OntModel oldDisplayModelVivoListViewConfig;
private RDFService rdfService;
public String getDataDir() {
return dataDir;
}
@ -118,7 +122,13 @@ public class UpdateSettings {
public void setRemovedDataFile(String 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;
}
public void setDefaultNamespace(String defaultNamespace) {
@ -223,6 +233,13 @@ public class UpdateSettings {
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.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.query.DataSource;
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.QueryExecutionFactory;
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.ResultSet;
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.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
@ -129,6 +130,7 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic
Resource s2 = (Resource) n;
// now run yet another describe query
String smallerTree = makeDescribe(s2);
log.debug(smallerTree);
Query smallerTreeQuery = QueryFactory.create(smallerTree);
QueryExecution qe3 = QueryExecutionFactory.create(
smallerTreeQuery, tree);
@ -172,13 +174,17 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic
StringBuffer queryBuff = new StringBuffer();
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");
if (graphURI != null) {
queryBuff.append(" GRAPH <" + graphURI + "> { \n");
}
stmtIt = model.listStatements();
addStatementPatterns(stmtIt, queryBuff, WHERE_CLAUSE);
stmts = stmtIt.toList();
stmts = sort(stmts);
addStatementPatterns(stmts, queryBuff, WHERE_CLAUSE);
if (graphURI != null) {
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 void addStatementPatterns(StmtIterator stmtIt, StringBuffer patternBuff, boolean whereClause) {
while(stmtIt.hasNext()) {
Triple t = stmtIt.next().asTriple();
private void addStatementPatterns(List<Statement> stmts, StringBuffer patternBuff, boolean whereClause) {
for(Statement stmt : stmts) {
Triple t = stmt.asTriple();
patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getSubject(), null));
patternBuff.append(" ");
patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getPredicate(), null));

View file

@ -9,6 +9,7 @@ import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
@ -715,7 +716,9 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService {
if (graphURI != null) {
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) {
queryBuff.append(" } \n");
}
@ -724,7 +727,9 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService {
queryBuff.append(" GRAPH <" + graphURI + "> { \n");
}
stmtIt = model.listStatements();
addStatementPatterns(stmtIt, queryBuff, WHERE_CLAUSE);
stmts = stmtIt.toList();
sort(stmts);
addStatementPatterns(stmts, queryBuff, WHERE_CLAUSE);
if (graphURI != null) {
queryBuff.append(" } \n");
}
@ -736,11 +741,53 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService {
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 void addStatementPatterns(StmtIterator stmtIt, StringBuffer patternBuff, boolean whereClause) {
while(stmtIt.hasNext()) {
Triple t = stmtIt.next().asTriple();
private void addStatementPatterns(List<Statement> stmts, StringBuffer patternBuff, boolean whereClause) {
for(Statement stmt : stmts) {
Triple t = stmt.asTriple();
patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getSubject(), null));
patternBuff.append(" ");
patternBuff.append(SparqlGraph.sparqlNodeDelete(t.getPredicate(), null));

View file

@ -251,18 +251,24 @@ public class SimpleReasoner extends StatementListener {
return;
}
OntClass subject = tboxModel.getOntClass((stmt.getSubject()).getURI());
if (subject == null) {
log.debug("didn't find subject class in the tbox: "
+ (stmt.getSubject()).getURI());
return;
}
OntClass object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI());
if (object == null) {
log.debug("didn't find object class in the tbox: "
+ ((Resource)stmt.getObject()).getURI());
return;
OntClass subject, object;
tboxModel.enterCriticalSection(Lock.READ);
try {
subject = tboxModel.getOntClass((stmt.getSubject()).getURI());
if (subject == null) {
log.debug("didn't find subject class in the tbox: "
+ (stmt.getSubject()).getURI());
return;
}
object = tboxModel.getOntClass(((Resource)stmt.getObject()).getURI());
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)) {
@ -1672,6 +1678,10 @@ public class SimpleReasoner extends StatementListener {
typeURIs = getRemainingAssertedTypeURIs(stmt.getSubject());
}
removedABoxTypeAssertion(stmt, inferenceModel, typeURIs);
} else if (doSameAs && stmt.getPredicate().equals(OWL.sameAs)) {
removedABoxSameAsAssertion(stmt, inferenceModel);
} else {
removedABoxAssertion(stmt, inferenceModel);
}
doPlugins(ModelUpdate.Operation.RETRACT,stmt);
} 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 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())) {
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("pelletOntModel", pelletListener.getPelletModel());
if (wadf != null) {
wadf.setPelletListener(pelletListener);
if (wadf instanceof WebappDaoFactoryJena) {
((WebappDaoFactoryJena) wadf).setPelletListener(pelletListener);
}
log.info("Pellet reasoner connected for the TBox");
// set up simple reasoning for the ABox
DataSource bds = JenaDataSourceSetupBase
.getApplicationDataSource(ctx);
String dbType = ConfigurationProperties.getBean(ctx).getProperty( // database type
"VitroConnection.DataSource.dbtype","MySQL");
// set up simple reasoning for the ABox
RDFService rdfService = RDFServiceUtils.getRDFServiceFactory(ctx).getRDFService();
Dataset dataset = new RDFServiceDataset(rdfService);
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
SimpleReasoner simpleReasoner = new SimpleReasoner(
unionOms.getTBoxModel(), rdfService, inferencesOms.getABoxModel(), rebuildModel, scratchModel);
unionOms.getTBoxModel(), rdfService, inferenceModel, rebuildModel, scratchModel);
sce.getServletContext().setAttribute(SimpleReasoner.class.getName(),simpleReasoner);
StartupStatus ss = StartupStatus.getBean(ctx);
@ -114,19 +110,6 @@ public class SimpleReasonerSetup implements ServletContextListener {
}
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);
sce.getServletContext().setAttribute(SimpleReasonerTBoxListener.class.getName(),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 {
int sleeps = 0;
while (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++;
}
PelletListener pelletListener = (PelletListener) sce.getServletContext().getAttribute("pelletListener");
if (pelletListener == null) {
return ;
}
int sleeps = 0;
// sleep at least once to make sure the TBox reasoning gets started
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
@ -196,7 +184,7 @@ public class SimpleReasonerSetup implements ServletContextListener {
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);
}
@ -210,19 +198,6 @@ public class SimpleReasonerSetup implements ServletContextListener {
private static boolean isMSTComputeRequired(ServletContext ctx) {
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.

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.ontology.update.KnowledgeBaseUpdater;
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;
/**
@ -54,10 +57,11 @@ public class UpdateKnowledgeBase implements ServletContextListener {
private final static Log log = LogFactory.getLog(UpdateKnowledgeBase.class);
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 NEW_TBOX_MODEL_DIR = "/WEB-INF/filegraph/tbox/";
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
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";
@ -72,78 +76,136 @@ public class UpdateKnowledgeBase implements ServletContextListener {
ServletContext ctx = sce.getServletContext();
StartupStatus ss = StartupStatus.getBean(ctx);
boolean migrationChangesMade = false;
try {
UpdateSettings settings = new UpdateSettings();
putReportingPathsIntoSettings(ctx, settings);
putNonReportingPathsIntoSettings(ctx, settings);
SimpleReasonerSetup.waitForTBoxReasoning(sce);
WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory();
settings.setDefaultNamespace(wadf.getDefaultNamespace());
settings.setAssertionOntModelSelector(ModelAccess.on(ctx).getBaseOntModelSelector());
settings.setInferenceOntModelSelector(ModelAccess.on(ctx).getInferenceOntModelSelector());
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;
try {
settings.setDisplayModel(ModelAccess.on(ctx).getDisplayModel());
OntModel oldTBoxModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_MODEL_DIR));
settings.setOldTBoxModel(oldTBoxModel);
OntModel newTBoxModel = loadModelFromDirectory(ctx.getRealPath(NEW_TBOX_MODEL_DIR));
settings.setNewTBoxModel(newTBoxModel);
OntModel oldTBoxAnnotationsModel = loadModelFromDirectory(ctx.getRealPath(OLD_TBOX_ANNOTATIONS_DIR));
settings.setOldTBoxAnnotationsModel(oldTBoxAnnotationsModel);
OntModel newTBoxAnnotationsModel = loadModelFromDirectory(ctx.getRealPath(NEW_TBOX_ANNOTATIONS_DIR));
settings.setNewTBoxAnnotationsModel(newTBoxAnnotationsModel);
//Display model tbox and display metadata
//old display model tbox model
OntModel oldDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_TBOX_PATH));
settings.setOldDisplayModelTboxModel(oldDisplayModelTboxModel);
//new display model tbox model
OntModel newDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_TBOX_PATH));
settings.setNewDisplayModelTboxModel(newDisplayModelTboxModel);
//old display model display model metadata
OntModel oldDisplayModelDisplayMetadataModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_DISPLAYMETADATA_PATH));
settings.setOldDisplayModelDisplayMetadataModel(oldDisplayModelDisplayMetadataModel);
//new display model display model metadata
OntModel newDisplayModelDisplayMetadataModel = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_DISPLAYMETADATA_PATH));
settings.setNewDisplayModelDisplayMetadataModel(newDisplayModelDisplayMetadataModel);
//Get new display model
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);
//Display model tbox and display metadata
//old display model tbox model
OntModel oldDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_TBOX_PATH));
settings.setOldDisplayModelTboxModel(oldDisplayModelTboxModel);
//new display model tbox model
OntModel newDisplayModelTboxModel = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_TBOX_PATH));
settings.setNewDisplayModelTboxModel(newDisplayModelTboxModel);
//old display model display model metadata
OntModel oldDisplayModelDisplayMetadataModel = loadModelFromFile(ctx.getRealPath(OLD_DISPLAYMODEL_DISPLAYMETADATA_PATH));
settings.setOldDisplayModelDisplayMetadataModel(oldDisplayModelDisplayMetadataModel);
//new display model display model metadata
OntModel newDisplayModelDisplayMetadataModel = loadModelFromFile(ctx.getRealPath(NEW_DISPLAYMODEL_DISPLAYMETADATA_PATH));
settings.setNewDisplayModelDisplayMetadataModel(newDisplayModelDisplayMetadataModel);
//Get new display model
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 (ModelFileNotFoundException e) {
// expected if no display migration was intended
tryMigrateDisplay = false;
} catch (Exception e) {
log.info("unable to read display model migration files, display model not migrated. " + e.getMessage());
tryMigrateDisplay = false;
log.info("Unable to read display model migration files. ", e);
tryMigrateDisplay = false;
}
try {
KnowledgeBaseUpdater ontologyUpdater = new KnowledgeBaseUpdater(settings);
try {
if (ontologyUpdater.updateRequired(ctx)) {
ctx.setAttribute(KBM_REQURIED_AT_STARTUP, Boolean.TRUE);
ontologyUpdater.update(ctx);
if (tryMigrateDisplay) {
try {
migrateDisplayModel(settings);
log.info("Migrated display model");
} catch (Exception e) {
log.warn("unable to successfully update display model: " + e.getMessage());
}
}
}
} catch (Exception ioe) {
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);
}
} catch (Throwable t) {
ss.fatal(this, "Exception updating knowledge base for ontology changes: ", t);
KnowledgeBaseUpdater ontologyUpdater = new KnowledgeBaseUpdater(settings);
boolean requiredUpdate = ontologyUpdater.updateRequired(ctx);
try {
ctx.setAttribute(KBM_REQURIED_AT_STARTUP, Boolean.TRUE);
log.info("Data migration required");
migrationChangesMade = ontologyUpdater.update(ctx);
if (tryMigrateDisplay) {
try {
migrateDisplayModel(settings);
log.info("Migrated display model");
} catch (Exception e) {
log.warn("unable to successfully update display model: " + e.getMessage());
}
}
// reload the display model since the TBoxUpdater may have
// modified it
new ApplicationModelSetup().contextInitialized(sce);
} catch (Exception ioe) {
ss.fatal(this, "Exception updating knowledge base for ontology changes: ", ioe);
}
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.
* 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());
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");
settings.setAddedDataFile(changedDir.resolve("addedData.n3").toString());
settings.setRemovedDataFile(changedDir.resolve("removedData.n3").toString());
@ -171,8 +225,19 @@ public class UpdateKnowledgeBase implements ServletContextListener {
Path logDir = createDirectory(dataDir, "logs");
settings.setLogFile(logDir.resolve(timestampedFileName("knowledgeBaseUpdate", "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 {
Path dir = parent;
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.LogFactory;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
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.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.ModelAccess;
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 {
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();
Model displayModel = ModelAccess.on(ctx).getDisplayModel();
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,
Individual subject,
Model displayModel,
Model tboxModel) {
List<ObjectProperty> additionalProps = new ArrayList<ObjectProperty>();
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;
}
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");
statementDisplay.put(objectKey, objectUri);
ObjectProperty predicate = new ObjectProperty();
predicate.setURI(predicateUri);
//Using object property statement template model here
ObjectPropertyStatementTemplateModel osm = new ObjectPropertyStatementTemplateModel(
subjectUri,
predicateUri,
predicate,
objectKey,
statementDisplay,
null, vreq);
@ -524,15 +527,23 @@ public class EditConfigurationTemplateModel extends BaseTemplateModel {
if( subjectVClasses == null ) {
vclasses = wdf.getVClassDao().getAllVclasses();
} else if (rangeClass != null) {
List<VClass> rangeVClasses = new ArrayList<VClass>();
vclasses = new ArrayList<VClass>();
vclasses.add(rangeClass);
List<String> subURIs = wdf.getVClassDao().getSubClassURIs(rangeClass.getURI());
for (String subClassURI : subURIs) {
VClass subClass = wdf.getVClassDao().getVClassByURI(subClassURI);
if (subClass != null) {
vclasses.add(subClass);
}
}
if (!rangeClass.isUnion()) {
rangeVClasses.add(rangeClass);
} else {
rangeVClasses.addAll(rangeClass.getUnionComponents());
}
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 {
//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

View file

@ -117,7 +117,7 @@ public abstract class BaseIndividualTemplateModel extends BaseTemplateModel {
RequestActionConstants.SOME_URI);
AddObjectPropertyStatement aops = new AddObjectPropertyStatement(
vreq.getJenaOntModel(), individual.getURI(),
RequestActionConstants.SOME_URI,
RequestActionConstants.SOME_PREDICATE,
RequestActionConstants.SOME_URI);
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.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
@ -58,7 +59,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
postprocess(statementData);
/* Collate the data */
subclasses = collate(subjectUri, propertyUri, statementData, editing);
subclasses = collate(subjectUri, op, statementData, editing);
for (SubclassTemplateModel subclass : subclasses) {
List<ObjectPropertyStatementTemplateModel> list = subclass.getStatements();
@ -188,7 +189,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
}
// 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) {
String objectKey = getObjectKey();
@ -218,7 +219,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
}
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.beans.DataPropertyStatement;
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.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.edit.n3editing.VTwo.RdfLiteralHash;
public class DataPropertyStatementTemplateModel extends PropertyStatementTemplateModel {
private static final Log log = LogFactory.getLog(DataPropertyStatementTemplateModel.class);
@ -28,9 +30,10 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
private final String templateName;
//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) {
super(subjectUri, propertyUri, vreq);
super(subjectUri, property, vreq);
this.literalValue = literal;
this.templateName = templateName;
@ -50,7 +53,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
"predicateUri", propertyUri,
"predicateUri", property.getURI(),
"datapropKey", makeHash(dps),
"cmd", "delete");
@ -63,7 +66,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
private String makeEditUrl() {
// vitro:moniker is deprecated. We display existing data values so editors can
// move them to other properties and delete, but don't allow editing.
if ( propertyUri.equals(VitroVocabulary.MONIKER) ) {
if ( VitroVocabulary.MONIKER.equals(property.getURI()) ) {
return "";
}
@ -76,7 +79,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
"predicateUri", propertyUri,
"predicateUri", property.getURI(),
"datapropKey", makeHash(dps));
if ( deleteUrl.isEmpty() ) {
@ -89,7 +92,7 @@ public class DataPropertyStatementTemplateModel extends PropertyStatementTemplat
}
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
dps.setLanguage(literalValue.getLanguage());
dps.setDatatypeURI(literalValue.getDatatypeURI());

View file

@ -88,7 +88,7 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
DataPropertyStatementDao dpDao = vreq.getWebappDaoFactory().getDataPropertyStatementDao();
List<Literal> values = dpDao.getDataPropertyValuesForIndividualByProperty(subject, dp, queryString, constructQueries);
for (Literal value : values) {
statements.add(new DataPropertyStatementTemplateModel(subjectUri, propertyUri, value, getTemplateName(), vreq));
statements.add(new DataPropertyStatementTemplateModel(subjectUri, dp, value, getTemplateName(), vreq));
}
} else {
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.controller.VitroRequest;
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.PropertyGroupDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao;
@ -74,12 +75,12 @@ public class GroupedPropertyList extends BaseTemplateModel {
List<ObjectProperty> populatedObjectPropertyList = subject
.getPopulatedObjectPropertyList();
List<ObjectProperty> additions = ApplicationConfigurationOntologyUtils
Collection<ObjectProperty> additions = ApplicationConfigurationOntologyUtils
.getAdditionalFauxSubpropertiesForList(
populatedObjectPropertyList, vreq);
populatedObjectPropertyList, subject, vreq);
if (log.isDebugEnabled()) {
for (ObjectProperty t : additions) {
log.debug(t.getDomainPublic() + " " + t.getGroupURI());
log.debug(t.getDomainPublic() + " " + t.getGroupURI() + " domain " + t.getDomainVClassURI());
}
log.debug("Added " + additions.size() +
" properties due to application configuration ontology");
@ -88,7 +89,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
populatedObjectPropertyList.addAll(additions);
propertyList.addAll(populatedObjectPropertyList);
// 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.
// 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
// DataPropertyDao.getAllPossibleDatapropsForIndividual(). The comparable method for object properties
// 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
.getAllPossiblePropInstForIndividual(subject.getURI());
if (allPropInstColl != null) {
@ -183,7 +190,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
if (pi != null) {
if (!alreadyOnObjectPropertyList(
populatedObjectPropertyList, pi)) {
addObjectPropertyToPropertyList(pi.getPropertyURI(), pi.getRangeClassURI(),
addObjectPropertyToPropertyList(pi.getPropertyURI(), pi.getDomainClassURI(), pi.getRangeClassURI(),
propertyList);
}
} else {
@ -199,7 +206,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
// constitute a special case (i.e., included in piDao.getAllPossiblePropInstForIndividual()).
for (String propertyUri : VITRO_PROPS_TO_ADD_TO_LIST) {
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) {
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;
}
private void addObjectPropertyToPropertyList(String propertyUri, String rangeUri,
private void addObjectPropertyToPropertyList(String propertyUri, String domainUri, String rangeUri,
List<Property> propertyList) {
ObjectPropertyDao opDao = wdf.getObjectPropertyDao();
ObjectProperty op = opDao.getObjectPropertyByURIAndRangeURI(propertyUri, rangeUri);
ObjectProperty op = opDao.getObjectPropertyByURIs(propertyUri, domainUri, rangeUri);
if (op == null) {
log.error("ObjectProperty op returned null from opDao.getObjectPropertyByURI(" + propertyUri + ")");
} else if (op.getURI() == null) {
@ -457,11 +477,16 @@ public class GroupedPropertyList extends BaseTemplateModel {
}
public PropertyTemplateModel pullProperty(String propertyUri) {
return pullProperty(propertyUri, null);
}
public PropertyTemplateModel pullProperty(String propertyUri, String rangeUri) {
for (PropertyGroupTemplateModel pgtm : groups) {
List<PropertyTemplateModel> properties = pgtm.getProperties();
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.
// NB Works with a for-each loop instead of an iterator,
// 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.beans.DataPropertyStatement;
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.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMap;
@ -37,7 +38,7 @@ public class NameStatementTemplateModel extends PropertyStatementTemplateModel {
private final String editUrl;
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
// application, to guarantee consistent results for individuals with multiple labels
@ -69,7 +70,7 @@ public class NameStatementTemplateModel extends PropertyStatementTemplateModel {
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
"predicateUri", propertyUri,
"predicateUri", property.getURI(),
"datapropKey", makeHash(dps),
"deleteProhibited", "prohibited");
@ -80,7 +81,7 @@ public class NameStatementTemplateModel extends PropertyStatementTemplateModel {
private DataPropertyStatement makeStatement(Literal literalValue) {
DataPropertyStatement dps = new DataPropertyStatementImpl(subjectUri,
propertyUri, literalValue.getLexicalForm());
property.getURI(), literalValue.getLexicalForm());
// Language and datatype are needed to get the correct hash value
dps.setLanguage(literalValue.getLanguage());
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.propstmt.DropObjectPropertyStatement;
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.ObjectPropertyStatementImpl;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
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.ParamMap;
@ -31,9 +33,9 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl
private final String editUrl;
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) {
super(subjectUri, propertyUri, vreq);
super(subjectUri, predicate, vreq);
this.data = Collections.unmodifiableMap(new HashMap<String, String>(data));
this.objectUri = data.get(objectKey);
@ -41,7 +43,8 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl
//to keep track of later
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
this.deleteUrl = makeDeleteUrl();
@ -50,24 +53,24 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl
private String makeDeleteUrl() {
// Is the delete link suppressed for this property?
if (new EditLinkSuppressor(vreq).isDeleteLinkSuppressed(propertyUri)) {
if (property.isDeleteLinkSuppressed()) {
return "";
}
// Determine whether the statement can be deleted
RequestedAction action = new DropObjectPropertyStatement(
vreq.getJenaOntModel(), subjectUri, propertyUri, objectUri);
vreq.getJenaOntModel(), subjectUri, property, objectUri);
if ( ! PolicyHelper.isAuthorizedForActions(vreq, action) ) {
return "";
}
if (propertyUri.equals(VitroVocabulary.IND_MAIN_IMAGE)) {
if (VitroVocabulary.IND_MAIN_IMAGE.equals(property.getURI())) {
return ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "delete");
}
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
"predicateUri", propertyUri,
"predicateUri", property.getURI(),
"objectUri", objectUri,
"cmd", "delete",
"objectKey", objectKey);
@ -92,7 +95,7 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl
private String makeEditUrl(ObjectPropertyStatement ops) {
// Is the edit link suppressed for this property?
if (new EditLinkSuppressor(vreq).isEditLinkSuppressed(propertyUri)) {
if (property.isEditLinkSuppressed()) {
return "";
}
@ -102,19 +105,26 @@ public class ObjectPropertyStatementTemplateModel extends PropertyStatementTempl
return "";
}
if (propertyUri.equals(VitroVocabulary.IND_MAIN_IMAGE)) {
if (VitroVocabulary.IND_MAIN_IMAGE.equals(property.getURI())) {
return ObjectPropertyTemplateModel.getImageUploadUrl(subjectUri, "edit");
}
ParamMap params = new ParamMap(
"subjectUri", subjectUri,
"predicateUri", propertyUri,
"predicateUri", property.getURI(),
"objectUri", objectUri);
if ( deleteUrl.isEmpty() ) {
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));
return UrlBuilder.getUrl(EDIT_PATH, params);

View file

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

View file

@ -36,8 +36,13 @@ public class PropertyGroupTemplateModel extends BaseTemplateModel {
properties = new ArrayList<PropertyTemplateModel>(propertyList.size());
for (Property p : propertyList) {
if (p instanceof ObjectProperty) {
ObjectProperty op = (ObjectProperty)p;
properties.add(ObjectPropertyTemplateModel.getObjectPropertyTemplateModel(op, subject, vreq, editing, populatedObjectPropertyList));
ObjectProperty op = (ObjectProperty) p;
ObjectPropertyTemplateModel tm = ObjectPropertyTemplateModel.getObjectPropertyTemplateModel(
op, subject, vreq, editing, populatedObjectPropertyList);
if (!tm.isEmpty() || (editing && !tm.getAddUrl().isEmpty())) {
properties.add(tm);
}
} else {
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;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
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 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.subjectUri = subjectUri;
this.propertyUri = propertyUri;
this.property = property;
}
/* Template properties */

View file

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

View file

@ -41,7 +41,7 @@ public class UncollatedObjectPropertyTemplateModel extends ObjectPropertyTemplat
String objectKey = getObjectKey();
for (Map<String, String> map : statementData) {
statements.add(new ObjectPropertyStatementTemplateModel(subjectUri,
propertyUri, objectKey, map, getTemplateName(), vreq));
op, objectKey, map, getTemplateName(), vreq));
}
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.EditObjectPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class SelfEditingPolicyTest extends AbstractTestClass {
@ -55,8 +56,8 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
private static final String UNSAFE_RESOURCE = UNSAFE_NS
+ "otherIndividual99999";
private static final String SAFE_PREDICATE = SAFE_NS + "hasHairStyle";
private static final String UNSAFE_PREDICATE = UNSAFE_NS + "hasSuperPowers";
private static final Property SAFE_PREDICATE = new Property(SAFE_NS + "hasHairStyle");
private static final Property UNSAFE_PREDICATE = new Property(UNSAFE_NS + "hasSuperPowers");
private ServletContextStub ctx;
@ -95,19 +96,19 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
PropertyRestrictionPolicyHelper.setBean(ctx, prph);
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));
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));
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));
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));
whatToAuth = new AddObjectPropertyStatement(ontModel, SAFE_RESOURCE,
@ -132,11 +133,11 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new AddDataPropertyStatement(ontModel, SELFEDITOR_URI,
SAFE_PREDICATE);
SAFE_PREDICATE.getURI());
assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth));
whatToAuth = new AddDataPropertyStatement(ontModel, SELFEDITOR_URI,
UNSAFE_PREDICATE);
UNSAFE_PREDICATE.getURI());
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
}
@ -218,16 +219,16 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
//
@Test
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));
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, UNSAFE_PREDICATE);
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, UNSAFE_PREDICATE.getURI());
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));
whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE);
whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE.getURI());
assertDecision(INCONCLUSIVE, policy.isAuthorized(ids, whatToAuth));
}
@ -287,7 +288,7 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
public void twoSEIsFindDataPropertySubject() {
setUpTwoSEIs();
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, SAFE_PREDICATE);
whatToAuth = new EditDataPropertyStatement(ontModel, SELFEDITOR_URI, SAFE_PREDICATE.getURI());
assertDecision(AUTHORIZED, policy.isAuthorized(ids, whatToAuth));
}
@ -295,7 +296,7 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
public void twoSEIsDontFindInDataProperty() {
setUpTwoSEIs();
whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE);
whatToAuth = new EditDataPropertyStatement(ontModel, SAFE_RESOURCE, SAFE_PREDICATE.getURI());
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.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
public class SelfEditingPolicy_2_Test extends AbstractTestClass {
@ -123,7 +124,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass {
@Test
public void nullIdentifierBundle() {
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);
Assert.assertNotNull(dec);
Assert.assertEquals(Authorization.INCONCLUSIVE, dec.getAuthorized());
@ -277,7 +278,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass {
private void assertAddObjectPropStmt(String uriOfSub, String uriOfPred,
String uriOfObj, Authorization expectedAuthorization) {
AddObjectPropertyStatement whatToAuth = new AddObjectPropertyStatement(
ontModel, uriOfSub, uriOfPred, uriOfObj);
ontModel, uriOfSub, new Property(uriOfPred), uriOfObj);
PolicyDecision dec = policy.isAuthorized(ids, whatToAuth);
log.debug(dec);
Assert.assertNotNull(dec);
@ -291,7 +292,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass {
private void assertEditObjPropStmt(String uriOfSub, String uriOfPred,
String uriOfObj, Authorization expectedAuthorization) {
EditObjectPropertyStatement whatToAuth = new EditObjectPropertyStatement(
ontModel, uriOfSub, uriOfPred, uriOfObj);
ontModel, uriOfSub, new Property(uriOfPred), uriOfObj);
PolicyDecision dec = policy.isAuthorized(ids, whatToAuth);
log.debug(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.LogFactory;
import org.apache.log4j.Level;
import org.junit.Before;
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.Property;
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.webapp.beans.BaseResourceBean;
@ -58,17 +59,25 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
// 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
public void createTheBean() {
Map<String, RoleLevel> displayLevels = new HashMap<String, BaseResourceBean.RoleLevel>();
displayLevels.put("http://predicates#display_self", SELF);
displayLevels.put("http://predicates#display_curator", CURATOR);
displayLevels.put("http://predicates#display_hidden", NOBODY);
Map<Pair<String, Pair<String,String>>, RoleLevel> displayLevels =
new HashMap<Pair<String, Pair<String,String>>, RoleLevel>();
mapPut("http://predicates#display_curator", CURATOR, displayLevels);
mapPut("http://predicates#display_hidden", NOBODY, displayLevels);
Map<String, RoleLevel> modifyLevels = new HashMap<String, BaseResourceBean.RoleLevel>();
modifyLevels.put("http://predicates#modify_self", SELF);
modifyLevels.put("http://predicates#modify_curator", CURATOR);
modifyLevels.put("http://predicates#modify_hidden", NOBODY);
Map<Pair<String, Pair<String,String>>, RoleLevel> modifyLevels =
new HashMap<Pair<String, Pair<String,String>>, RoleLevel>();
mapPut("http://predicates#modify_self", SELF, modifyLevels);
mapPut("http://predicates#modify_curator", CURATOR, modifyLevels);
mapPut("http://predicates#modify_hidden", NOBODY, modifyLevels);
bean = new PropertyRestrictionPolicyHelper(
Arrays.asList(PROHIBITED_NAMESPACES),
@ -125,68 +134,75 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
@Test
public void displayPredicateNoRestriction() {
assertEquals("displayPredicate: open", true,
bean.canDisplayPredicate("http://predicates#open", PUBLIC));
bean.canDisplayPredicate(createVitroProperty(
"http://predicates#open"), PUBLIC));
}
@Test
public void displayPredicateRestrictionLower() {
assertEquals("displayPredicate: lower restriction", true,
bean.canDisplayPredicate("http://predicates#display_self",
CURATOR));
bean.canDisplayPredicate(createVitroProperty(
"http://predicates#display_self"), CURATOR));
}
@Test
public void displayPredicateRestrictionEqual() {
assertEquals("displayPredicate: equal restriction", true,
bean.canDisplayPredicate("http://predicates#display_curator",
CURATOR));
bean.canDisplayPredicate(createVitroProperty(
"http://predicates#display_curator"), CURATOR));
}
@Test
public void displayPredicateRestrictionHigher() {
assertEquals("displayPredicate: higher restriction", false,
bean.canDisplayPredicate("http://predicates#display_hidden",
CURATOR));
bean.canDisplayPredicate(createVitroProperty(
"http://predicates#display_hidden"), CURATOR));
}
@Test
public void modifyPredicateNoRestriction() {
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
public void modifyPredicateRestrictionLower() {
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));
}
@Test
public void modifyPredicateRestrictionEqual() {
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));
}
@Test
public void modifyPredicateRestrictionHigher() {
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));
}
@Test
public void modifyPredicateProhibitedNamespace() {
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));
}
@Test
public void modifyPredicatePermittedException() {
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
public void buildDisplayThresholds() {
Map<String, RoleLevel> expectedMap = new HashMap<String, BaseResourceBean.RoleLevel>();
expectedMap.put("http://thresholds#display_public", PUBLIC);
expectedMap.put("http://thresholds#display_hidden", NOBODY);
Map<Pair<String, Pair<String,String>>, BaseResourceBean.RoleLevel> expectedMap =
new HashMap<Pair<String, Pair<String,String>>, BaseResourceBean.RoleLevel>();
mapPut("http://thresholds#display_public", PUBLIC, expectedMap);
mapPut("http://thresholds#display_hidden", NOBODY, expectedMap);
Map<String, RoleLevel> actualMap = populateThresholdMap(PROPERTY_DISPLAY_THRESHOLD);
assertEquals("display thresholds", expectedMap, actualMap);
@ -205,9 +222,10 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
@Test
public void buildModifyThresholds() {
Map<String, RoleLevel> expectedMap = new HashMap<String, BaseResourceBean.RoleLevel>();
expectedMap.put("http://thresholds#modify_editor", EDITOR);
expectedMap.put("http://thresholds#modify_curator", CURATOR);
Map<Pair<String, Pair<String,String>>, BaseResourceBean.RoleLevel> expectedMap =
new HashMap<Pair<String, Pair<String,String>>, BaseResourceBean.RoleLevel>();
mapPut("http://thresholds#modify_editor", EDITOR, expectedMap);
mapPut("http://thresholds#modify_curator", CURATOR, expectedMap);
Map<String, RoleLevel> actualMap = populateThresholdMap(PROPERTY_MODIFY_THRESHOLD);
assertEquals("modify thresholds", expectedMap, actualMap);
@ -244,4 +262,9 @@ public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
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);
Assert.assertTrue(inf.contains(b,Q,a));
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

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.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.beans.BaseResourceBean.RoleLevel;
@ -43,10 +45,15 @@ public class PropertyRestrictionPolicyHelperStub extends
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) {
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(
Set<String> modifyRestrictedNamespaces,
Set<String> modifyPermittedExceptions,
Map<String, RoleLevel> displayThresholds,
Map<String, RoleLevel> modifyThresholds) {
Map<Pair<String, Pair<String,String>>, RoleLevel> displayThresholds,
Map<Pair<String, Pair<String,String>>, RoleLevel> modifyThresholds) {
super(modifyRestrictedNamespaces, modifyPermittedExceptions,
displayThresholds, modifyThresholds, ModelFactory.createDefaultModel());
}

View file

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

View file

@ -216,7 +216,7 @@ public class ObjectPropertyStatementDaoStub implements
@Override
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) {
throw new RuntimeException(
"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.ModelMakerSetup
edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase
edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup
edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil$Setup
@ -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.UpdateKnowledgeBase
# Must run after JenaDataSourceSetup
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
upload_photo = Upload a 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
minimum_image_dimensions = Minimum image dimensions: {0} x {1} pixels
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. \
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_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.errorNoPhotoSelected = Please browse and select a photo.
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
@ -84,27 +84,27 @@ last_login = Last Login
add_new_account = Add new account
edit_account = Edit account
external_auth_only = Externally Authenticated Only
reset_password = Reset password
reset_password = Reset password
reset_password_note = Note: Instructions for resetting the password will \
be emailed to the address entered above. The password will not \
be reset until the user follows the link provided in this email.
be emailed to the address entered above. The password will not \
be reset until the user follows the link provided in this email.
new_password = New password
confirm_password = Confirm new password
minimum_password_length = Minimum of {0} characters in length.
leave_password_unchanged = Leaving this blank means that the password will not be changed.
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_title = new account
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_2 = has been updated.
updated_account_title = updated account
updated_account_notification = A confirmation email has been sent to {0} \
with instructions for resetting a password. \
The password will not be reset until the user follows the link provided in this email.
with instructions for resetting a password. \
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}.
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
new_account_note = Note: An email will be sent to the address entered above \
notifying that an account has been created. \
It will include instructions for activating the account and creating a password.
notifying that an account has been created. \
It will include instructions for activating the account and creating a password.
initial_password = Initial password
submit_add_new_account = Add new account
@ -177,22 +177,22 @@ first_time_login = First time log in
create_account = Create account
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.
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_changed_subject = Password changed.
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_please_login = Your password has been saved. Please log in.
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 \
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_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}.
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.");
who_can_edit_profile = Who can edit my profile
add_profile_editor = Add profile editor
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_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_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_last_name = You must supply a last name.
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.
logged_in_but_no_profile = You have logged in, but the system contains no profile for you.
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
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.
#
# "partial" individual templates ( /templates/freemarker/body/partials/individual )
# "partial" individual templates ( /templates/freemarker/body/partials/individual )
#
manage_publications = manage publications
manage_grants_and_projects = manage grants & projects
@ -307,7 +304,7 @@ search_index_not_connected = The search index is not connected.
failed = failed
check_startup_status = Check startup status page and/or Tomcat logs for more information.
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
reset_search_index = Reset the search index and re-populate it.
preparing_to_rebuild_index = Preparing to rebuild the search index.
@ -322,7 +319,7 @@ warning = Warning
warnings_issued = {0} issued warnings during startup.
startup_trace = Startup trace
full_list_startup = The full list of startup events and messages.
startup_status = Startup Status
startup_status = Startup status
continue = Continue
#
@ -479,7 +476,7 @@ hide_show_properties = hide/show properties
hide_properties = hide properties
property_hierarchy = Property Hierarchy
all_x_properties = All {0} Properties
property_groups = Property Groups
property_groups = Property groups
add_new = Add new
object = object
data = data
@ -496,7 +493,7 @@ object_property_hierarchy = Object property hierarchy
data_property_hierarchy = Data property hierarchy
site_config = Site Configuration
internal_class = Institutional internal class
internal_class_i_capped = Institutional internal class
manage_profile_editing = Manage profile editing
page_management = Page management
menu_ordering_mixed_caps = Menu ordering
@ -504,6 +501,18 @@ restrict_logins_mixed_caps = Restrict logins
site_information = Site information
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 )
#
@ -521,24 +530,12 @@ page_link = page link
next_capitalized = Next
#
# 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}''
#
# shortview templates ( /templates/freemarker/body/partials/shortview )
# shortview templates ( /templates/freemarker/body/partials/shortview )
#
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_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
#
# 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.
browse_capitalized = Browse
browse_by = Browse by
#
# partial account templates ( /templates/freemarker/body/partials/accounts )
# partial account templates ( /templates/freemarker/body/partials/accounts )
#
delete_button = Delete
accounts = accounts
@ -567,7 +564,7 @@ accounts_per_page = accounts per page
update_button = Update
#
# pagemanagement templates ( /templates/freemarker/body/pagemanagement )
# pagemanagement templates ( /templates/freemarker/body/pagemanagement )
#
title_capitalized = Title
type_capitalized = Type
@ -588,7 +585,7 @@ use_capitalized = Use
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.
implement_capitalized = Implement
@ -599,10 +596,10 @@ no_html_specified = No HTML specified.
page_text = page text
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_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
#
# page partials templates ( /templates/freemarker/page/partials )
# page partials templates ( /templates/freemarker/page/partials )
#
copyright = copyright
all_rights_reserved = All Rights Reserved.
@ -650,7 +647,7 @@ menu_item = menu item
version = Version
#
# widget templates ( /templates/freemarker/widgets )
# widget templates ( /templates/freemarker/widgets )
#
individual_name = individual name
vclassAlpha_not_implemented = vclassAlpha is not yet implemented.
@ -668,11 +665,10 @@ account = account
change_password_to_login = Change Password to Log in
new_password_capitalized = New Password
confirm_password_capitalized = Confirm Password
minimum_password_length = Minimum of {0} characters in length.
already_logged_in = You are already logged in.
#
# lib templates ( /templates/freemarker/lib )
# lib templates ( /templates/freemarker/lib )
#
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.
#
# edit templates ( /templates/freemarker/edit and edit/forms )
# edit templates ( /templates/freemarker/edit and edit/forms )
#
edit_capitalized = Edit
add_capitalized = Add
@ -764,7 +760,7 @@ label = label
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
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
#
# custom form javascript variables ( /templates/freemarker/edit/js)
# custom form javascript variables ( /templates/freemarker/edit/js)
#
select_an_existing = Select an existing
or_create_new_one = or create a new one.
@ -805,7 +801,7 @@ october = October
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.

View file

@ -18,7 +18,7 @@
<#-- List the menu items -->
<ul class="menuItems">
<#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>
</ul>

View file

@ -8,7 +8,7 @@
<ul role="navigation">
<#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 siteConfig.manageProxies?has_content>

View file

@ -144,7 +144,7 @@ var customForm = {
// Put this case first, because in edit mode with
// validation errors we just want initFormFullView.
// 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();
}
else if (this.findValidationErrors()) {
@ -321,8 +321,12 @@ var customForm = {
},
complete: function(xhr, status) {
// Not sure why, but we need an explicit json parse here.
var results = $.parseJSON(xhr.responseText),
filteredResults = customForm.filterAcResults(results);
var results = $.parseJSON(xhr.responseText);
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;
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) {
// hide the acSelector field and set it's value to the selected ac item
this.hideFields($(selectedObj).parent());

View file

@ -108,13 +108,13 @@ name will be used as the label. -->
<#if editable>
<#local url = property.addUrl>
<#if url?has_content>
<@showAddLink property.localName label url />
<@showAddLink property.localName property.name label url />
</#if>
</#if>
</#macro>
<#macro showAddLink propertyLocalName label url>
<#if propertyLocalName == "informationResourceInAuthorship" || propertyLocalName == "webpage" || propertyLocalName == "hasResearchArea">
<#macro showAddLink propertyLocalName propertyName label url>
<#if propertyName == "informationResourceInAuthorship" || propertyName == "webpage" || propertyLocalName == "hasResearchArea">
<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>
<#else>
@ -131,30 +131,42 @@ name will be used as the label. -->
<#macro propertyListItem property statement editable >
<li role="listitem">
<#nested>
<@editingLinks "${property.localName}" statement editable/>
<@editingLinks "${property.localName}" "${property.name}" statement editable/>
</li>
</#macro>
<#macro editingLinks propertyLocalName statement editable>
<#if editable && (propertyLocalName != "informationResourceInAuthorship" && propertyLocalName != "webpage" && propertyLocalName != "hasResearchArea")>
<@editLink propertyLocalName statement />
<@deleteLink propertyLocalName statement />
<#macro editingLinks propertyLocalName propertyName statement editable>
<#if editable && (propertyName != "authors" && propertyName != "webpage" && propertyLocalName != "hasResearchArea")>
<@editLink propertyLocalName propertyName statement />
<@deleteLink propertyLocalName propertyName statement />
</#if>
</#macro>
<#macro editLink propertyLocalName statement>
<#macro editLink propertyLocalName propertyName 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>
</#if>
<#if url?has_content>
<@showEditLink propertyLocalName url />
</#if>
</#macro>
<#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>
</#macro>
<#macro deleteLink propertyLocalName statement>
<#macro deleteLink propertyLocalName propertyName statement>
<#local url = statement.deleteUrl>
<#if url?has_content>
<@showDeleteLink propertyLocalName url />
@ -197,7 +209,7 @@ name will be used as the label. -->
<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!}" />
</a>
<@editingLinks "${mainImage.localName}" mainImage.first() editable />
<@editingLinks "${mainImage.localName}" "" mainImage.first() editable />
<#else>
<#local imageLabel><@addLinkWithLabel mainImage editable "${i18n().photo}" /></#local>
${imageLabel}
@ -218,7 +230,7 @@ name will be used as the label. -->
<#local label = individual.nameStatement>
${label.value}
<#if useEditLink>
<@editingLinks "label" label editable />
<@editingLinks "label" "" label editable />
<#elseif editable || (labelCount > 1)>
<#--We display the link even when the user is not logged in case of multiple labels-->
<#if editable>