Skip to content

Commit

Permalink
Support for language tag specification per assertion - Sesame driver.
Browse files Browse the repository at this point in the history
  • Loading branch information
ledsoft committed Jun 11, 2017
1 parent 6771cdd commit 3da75f3
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@

import java.net.URI;

final class AnnotationPropertyAssertion extends PropertyAssertion {
final class AnnotationPropertyAssertion extends Assertion {

AnnotationPropertyAssertion(URI assertionIdentifier, boolean isInferred) {
super(assertionIdentifier, isInferred);
}

AnnotationPropertyAssertion(URI assertionIdentifier, String language, boolean isInferred) {
super(assertionIdentifier, language, isInferred);
}

@Override
public AssertionType getType() {
return AssertionType.ANNOTATION_PROPERTY;
Expand All @@ -37,4 +41,9 @@ public int hashCode() {
public boolean equals(Object obj) {
return this == obj || super.equals(obj) && getClass() == obj.getClass();
}

@Override
public String toString() {
return super.toString() + (language != null ? " @" + language : "");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*/
public abstract class Assertion extends NamedResource {

private static final long serialVersionUID = 2641835840569464452L;
protected final String language;

private final boolean inferred;

Expand All @@ -42,6 +42,13 @@ public enum AssertionType {
protected Assertion(URI identifier, boolean isInferred) {
super(identifier);
this.inferred = isInferred;
this.language = null;
}

protected Assertion(URI identifier, String language, boolean isInferred) {
super(identifier);
this.inferred = isInferred;
this.language = language;
}

/**
Expand Down Expand Up @@ -72,6 +79,17 @@ public boolean isClassAssertion() {
*/
public abstract AssertionType getType();

/**
* Gets the language tag carried by this assertion.
* <p>
* The language tag applies only to string-based literals.
*
* @return Language tag, e.g. {@code en}, can be {@code null}
*/
public String getLanguage() {
return language;
}

@Override
public int hashCode() {
final int prime = 31;
Expand Down Expand Up @@ -121,6 +139,19 @@ public static Assertion createUnspecifiedPropertyAssertion(boolean isInferred) {
return new PropertyAssertion(isInferred);
}

/**
* Creates a property assertion without specifying the assertion identifier.
* <p>
* Note that the returned instances are all equal as long as their inferred status is the same.
*
* @param language Language tag, optional
* @param isInferred Whether the assertion uses inferred values
* @return Assertion
*/
public static Assertion createUnspecifiedPropertyAssertion(String language, boolean isInferred) {
return new PropertyAssertion(language, isInferred);
}

/**
* Creates new property assertion without specifying what kind of property it is.
*
Expand All @@ -132,15 +163,26 @@ public static Assertion createPropertyAssertion(URI assertionIdentifier, boolean
return new PropertyAssertion(assertionIdentifier, isInferred);
}

/**
* Creates new property assertion without specifying what kind of property it is.
*
* @param assertionIdentifier Assertion identifier
* @param language Language tag, optional
* @param isInferred Whether the assertion uses inferred values
* @return Assertion
*/
public static Assertion createPropertyAssertion(URI assertionIdentifier, String language, boolean isInferred) {
return new PropertyAssertion(assertionIdentifier, language, isInferred);
}

/**
* Creates new object property assertion.
*
* @param assertionIdentifier Assertion identifier
* @param isInferred Whether the assertion uses inferred values
* @return Assertion
*/
public static Assertion createObjectPropertyAssertion(URI assertionIdentifier,
boolean isInferred) {
public static Assertion createObjectPropertyAssertion(URI assertionIdentifier, boolean isInferred) {
return new ObjectPropertyAssertion(assertionIdentifier, isInferred);
}

Expand All @@ -155,15 +197,39 @@ public static Assertion createDataPropertyAssertion(URI assertionIdentifier, boo
return new DataPropertyAssertion(assertionIdentifier, isInferred);
}

/**
* Creates new data property assertion.
*
* @param assertionIdentifier Assertion identifier
* @param language Language tag, optional
* @param isInferred Whether the assertion uses inferred values
* @return Assertion
*/
public static Assertion createDataPropertyAssertion(URI assertionIdentifier, String language, boolean isInferred) {
return new DataPropertyAssertion(assertionIdentifier, language, isInferred);
}

/**
* Creates new annotation property assertion.
*
* @param assertionIdentifier Assertion identifier
* @param isInferred Whether the assertion uses inferred values
* @return Assertion
*/
public static Assertion createAnnotationPropertyAssertion(URI assertionIdentifier,
boolean isInferred) {
public static Assertion createAnnotationPropertyAssertion(URI assertionIdentifier, boolean isInferred) {
return new AnnotationPropertyAssertion(assertionIdentifier, isInferred);
}

/**
* Creates new annotation property assertion.
*
* @param assertionIdentifier Assertion identifier
* @param language Language tag, optional
* @param isInferred Whether the assertion uses inferred values
* @return Assertion
*/
public static Assertion createAnnotationPropertyAssertion(URI assertionIdentifier, String language,
boolean isInferred) {
return new AnnotationPropertyAssertion(assertionIdentifier, language, isInferred);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@

import java.net.URI;

class DataPropertyAssertion extends PropertyAssertion {
class DataPropertyAssertion extends Assertion {

DataPropertyAssertion(URI assertionIdentifier, boolean isInferred) {
super(assertionIdentifier, isInferred);
}

DataPropertyAssertion(URI identifier, String language, boolean isInferred) {
super(identifier, language, isInferred);
}

@Override
public AssertionType getType() {
return AssertionType.DATA_PROPERTY;
Expand All @@ -37,4 +41,9 @@ public int hashCode() {
public boolean equals(Object obj) {
return this == obj || super.equals(obj) && getClass() == obj.getClass();
}

@Override
public String toString() {
return super.toString() + (language != null ? " @" + language : "");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ public AssertionType getType() {
return AssertionType.OBJECT_PROPERTY;
}

/**
* Always returns {@code null}, because language is irrelevant for object properties.
*
* @return {@code null}
*/
@Override
public String getLanguage() {
return null;
}

@Override
public int hashCode() {
int prime = 31;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,27 @@ class PropertyAssertion extends Assertion {

private static final URI UNSPECIFIED_PROPERTY = URI.create("http://" + new Random().nextInt());

private String language;

PropertyAssertion(boolean isInferred) {
super(UNSPECIFIED_PROPERTY, isInferred);
}

PropertyAssertion(String language, boolean isInferred) {
super(UNSPECIFIED_PROPERTY, language, isInferred);
}

PropertyAssertion(URI identifier, boolean isInferred) {
super(identifier, isInferred);
}

PropertyAssertion(URI identifier, String language, boolean isInferred) {
super(identifier, language, isInferred);
}

@Override
public AssertionType getType() {
return AssertionType.PROPERTY;
}

/**
* Gets the language tag carried by this assertion.
* <p>
* The language tag applies only to string-based literals.
*
* @return Language tag, e.g. {@code en}, can be {@code null}
*/
public String getLanguage() {
return language;
}

public void setLanguage(String language) {
this.language = language;
}

@Override
public int hashCode() {
int prime = 31;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ private Optional<Value<?>> resolveValue(Statement stmt, Assertion assertion) {
if (assertion == null || SesameUtils.isBlankNode(stmt.getObject())) {
return Optional.empty();
}
return createValue(assertion.getType(), stmt.getObject());
return createValue(assertion, stmt.getObject());
}

public Axiom<?> statementToAxiom(Statement statement, Assertion assertion) {
Expand All @@ -74,10 +74,11 @@ private Assertion resolveAssertion(IRI predicate) {
return assertion;
}

private Optional<Value<?>> createValue(Assertion.AssertionType assertionType, org.eclipse.rdf4j.model.Value value) {
private Optional<Value<?>> createValue(Assertion assertion, org.eclipse.rdf4j.model.Value value) {
final Assertion.AssertionType assertionType = assertion.getType();
switch (assertionType) {
case DATA_PROPERTY:
if (!(value instanceof Literal) || !SesameUtils.doesLanguageMatch((Literal) value, language)) {
if (!(value instanceof Literal) || !languageMatches(assertion, (Literal) value)) {
return Optional.empty();
}
return Optional.of(new Value<>(SesameUtils.getDataPropertyValue((Literal) value)));
Expand All @@ -93,19 +94,25 @@ private Optional<Value<?>> createValue(Assertion.AssertionType assertionType, or
return Optional.of(new Value<>(NamedResource.create(value.stringValue())));
case ANNOTATION_PROPERTY: // Intentional fall-through
case PROPERTY:
return resolveValue(value);
return resolveValue(assertion, value);
}
return Optional.empty();
}

private Optional<Value<?>> resolveValue(org.eclipse.rdf4j.model.Value object) {
if (object instanceof Literal) {
if (!SesameUtils.doesLanguageMatch((Literal) object, language)) {
private boolean languageMatches(Assertion assertion, Literal literal) {
// TODO What if the user specifies language per PU, but wants to override it for an attribute?
return SesameUtils
.doesLanguageMatch(literal, assertion.getLanguage() != null ? assertion.getLanguage() : language);
}

private Optional<Value<?>> resolveValue(Assertion assertion, org.eclipse.rdf4j.model.Value value) {
if (value instanceof Literal) {
if (!languageMatches(assertion, (Literal) value)) {
return Optional.empty();
}
return Optional.of(new Value<>(SesameUtils.getDataPropertyValue((Literal) object)));
return Optional.of(new Value<>(SesameUtils.getDataPropertyValue((Literal) value)));
} else {
return Optional.of(new Value<>(NamedResource.create(object.stringValue())));
return Optional.of(new Value<>(NamedResource.create(value.stringValue())));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package cz.cvut.kbss.ontodriver.sesame;

import cz.cvut.kbss.ontodriver.descriptor.AxiomDescriptor;
import cz.cvut.kbss.ontodriver.exception.OntoDriverException;
import cz.cvut.kbss.ontodriver.model.Assertion;
import cz.cvut.kbss.ontodriver.model.Axiom;
import cz.cvut.kbss.ontodriver.model.NamedResource;
Expand Down Expand Up @@ -306,12 +307,7 @@ public void loadAxiomsSkipsPropertyValueOfInvalidType_DP() throws Exception {
@Test
public void loadAxiomsLoadsStringLiteralWithCorrectLanguage() throws Exception {
final String individual = generatedData.individuals.get(Generator.randomIndex(generatedData.individuals));
final RepositoryConnection conn = connector.unwrap(Repository.class).getConnection();
conn.begin();
conn.add(vf.createStatement(vf.createIRI(individual), RDFS.LABEL, vf.createLiteral("a", "en")));
conn.add(vf.createStatement(vf.createIRI(individual), RDFS.LABEL, vf.createLiteral("b", "cs")));
conn.commit();
conn.close();
persistLanguageTaggedStrings(individual);

// Language is en
connector.begin();
Expand All @@ -324,15 +320,19 @@ public void loadAxiomsLoadsStringLiteralWithCorrectLanguage() throws Exception {
assertEquals("a", ax.getValue().getValue());
}

@Test
public void loadAxiomsLoadsStringLiteralWithCorrectLanguageForUnspecifiedPropertyType() throws Exception {
final String individual = generatedData.individuals.get(Generator.randomIndex(generatedData.individuals));
private void persistLanguageTaggedStrings(String individual) throws OntoDriverException {
final RepositoryConnection conn = connector.unwrap(Repository.class).getConnection();
conn.begin();
conn.add(vf.createStatement(vf.createIRI(individual), RDFS.LABEL, vf.createLiteral("a", "en")));
conn.add(vf.createStatement(vf.createIRI(individual), RDFS.LABEL, vf.createLiteral("b", "cs")));
conn.commit();
conn.close();
}

@Test
public void loadAxiomsLoadsStringLiteralWithCorrectLanguageForUnspecifiedPropertyType() throws Exception {
final String individual = generatedData.individuals.get(Generator.randomIndex(generatedData.individuals));
persistLanguageTaggedStrings(individual);

// Language is en
connector.begin();
Expand All @@ -343,4 +343,37 @@ public void loadAxiomsLoadsStringLiteralWithCorrectLanguageForUnspecifiedPropert
final Axiom<?> ax = axioms.iterator().next();
assertEquals("a", ax.getValue().getValue());
}

@Test
public void loadsStringLiteralWithCorrectLanguageTagWhenItIsSpecifiedInAssertion() throws Exception {
final String individual = generatedData.individuals.get(Generator.randomIndex(generatedData.individuals));
persistLanguageTaggedStrings(individual);

connector.begin();
final AxiomDescriptor descriptor = new AxiomDescriptor(NamedResource.create(individual));
final Assertion assertion =
Assertion.createDataPropertyAssertion(URI.create(RDFS.LABEL.stringValue()), "cs", false);
descriptor.addAssertion(assertion);
final Collection<Axiom<?>> axioms = axiomLoader.loadAxioms(descriptor);
assertEquals(1, axioms.size());
final Axiom<?> ax = axioms.iterator().next();
assertEquals("b", ax.getValue().getValue());
}

@Test
public void loadsStringLiteralWithCorrectLanguageTagWhenItIsSpecifiedInAssertionOfUnspecifiedProperty() throws
Exception {
final String individual = generatedData.individuals.get(Generator.randomIndex(generatedData.individuals));
persistLanguageTaggedStrings(individual);

connector.begin();
final AxiomDescriptor descriptor = new AxiomDescriptor(NamedResource.create(individual));
final Assertion assertion =
Assertion.createPropertyAssertion(URI.create(RDFS.LABEL.stringValue()), "cs", false);
descriptor.addAssertion(assertion);
final Collection<Axiom<?>> axioms = axiomLoader.loadAxioms(descriptor);
assertEquals(1, axioms.size());
final Axiom<?> ax = axioms.iterator().next();
assertEquals("b", ax.getValue().getValue());
}
}

0 comments on commit 3da75f3

Please sign in to comment.