Skip to content

Commit

Permalink
[Enhancement #73] Refactor OntoDriver API descriptors in preparation …
Browse files Browse the repository at this point in the history
…for supporting multiple contexts per assertion/subject.

AxiomValueDescriptor has been split from AxiomDescriptor, as it can contain only one context per assertion/subject to prevent ambiguity issues when saving values.
  • Loading branch information
ledsoft committed Sep 24, 2020
1 parent 8358f5e commit 91dc0cf
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 111 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package cz.cvut.kbss.ontodriver.descriptor;

import cz.cvut.kbss.ontodriver.model.Assertion;
import cz.cvut.kbss.ontodriver.model.NamedResource;

import java.net.URI;
import java.util.Objects;
import java.util.Set;

/**
* Defines common API for axiom descriptors.
*/
public abstract class AbstractAxiomDescriptor {

private final NamedResource subject;

protected AbstractAxiomDescriptor(NamedResource subject) {
this.subject = Objects.requireNonNull(subject);
}

public NamedResource getSubject() {
return subject;
}

/**
* Gets the set of assertions in this descriptor.
*
* @return Set of assertions
*/
public abstract Set<Assertion> getAssertions();

/**
* Checks whether this descriptor contains the specified assertion.
*
* @param assertion Assertion to look for
* @return {@code boolean} result
*/
public abstract boolean containsAssertion(Assertion assertion);

/**
* Gets the set of repository context identifiers in which this descriptor's subject may be.
*
* @return Set of context identifiers
*/
public abstract Set<URI> getSubjectContexts();

/**
* Gets the set of repository context identifiers in which the specified assertion values may be.
*
* @return Set of context identifiers
*/
public abstract Set<URI> getAssertionContexts(Assertion assertion);

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof AbstractAxiomDescriptor)) return false;
AbstractAxiomDescriptor that = (AbstractAxiomDescriptor) o;
return subject.equals(that.subject);
}

@Override
public int hashCode() {
return Objects.hash(subject);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,15 @@
* Additionally, it can specify context URIs for both the descriptor and individual properties so that the underlying
* driver knows where to look for the corresponding axioms.
*/
public class AxiomDescriptor {
public class AxiomDescriptor extends AbstractAxiomDescriptor {

private final NamedResource subject;
private final Set<Assertion> assertions;

private URI subjectContext;
private final Map<Assertion, URI> assertionContexts;

public AxiomDescriptor(NamedResource subject) {
this.subject = Objects.requireNonNull(subject);
super(subject);
this.assertions = new HashSet<>();
this.assertionContexts = new HashMap<>();
}
Expand Down Expand Up @@ -78,10 +77,6 @@ public void setAssertionContext(Assertion assertion, URI context) {
assertionContexts.put(assertion, context);
}

public NamedResource getSubject() {
return subject;
}

public URI getSubjectContext() {
return subjectContext;
}
Expand Down Expand Up @@ -122,39 +117,37 @@ public boolean containsAssertion(Assertion assertion) {
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + subject.hashCode();
result = prime * result + ((subjectContext == null) ? 0 : subjectContext.hashCode());
result = prime * result + assertions.hashCode();
result = prime * result + assertionContexts.hashCode();
return result;
public Set<URI> getSubjectContexts() {
// TODO
return Collections.singleton(getSubjectContext());
}

@Override
public Set<URI> getAssertionContexts(Assertion assertion) {
// TODO
return Collections.singleton(getAssertionContext(assertion));
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AxiomDescriptor other = (AxiomDescriptor) obj;
if (!subject.equals(other.subject))
return false;
if (subjectContext == null) {
if (other.subjectContext != null)
return false;
} else if (!subjectContext.equals(other.subjectContext))
return false;
return assertions.equals(other.assertions) && assertionContexts.equals(other.assertionContexts);
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof AxiomDescriptor)) return false;
if (!super.equals(o)) return false;
AxiomDescriptor that = (AxiomDescriptor) o;
return assertions.equals(that.assertions) &&
Objects.equals(subjectContext, that.subjectContext) &&
assertionContexts.equals(that.assertionContexts);
}

@Override
public int hashCode() {
return Objects.hash(super.hashCode(), assertions, subjectContext, assertionContexts);
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("[").append(subject);
sb.append("[").append(getSubject());
if (subjectContext != null) {
sb.append(" - ").append(subjectContext);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,120 @@
/**
* Copyright (C) 2020 Czech Technical University in Prague
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* <p>
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
* version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details. You should have received a copy of the GNU General Public License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*/
package cz.cvut.kbss.ontodriver.descriptor;

import cz.cvut.kbss.ontodriver.model.Assertion;
import cz.cvut.kbss.ontodriver.model.NamedResource;
import cz.cvut.kbss.ontodriver.model.Value;

import java.net.URI;
import java.util.*;

public class AxiomValueDescriptor extends AxiomDescriptor {
public class AxiomValueDescriptor extends AbstractAxiomDescriptor {

private final Map<Assertion, List<Value<?>>> values;
private URI subjectContext;

private final Map<Assertion, AssertionData> assertionData;

public AxiomValueDescriptor(NamedResource subject) {
super(subject);
this.values = new HashMap<>();
this.assertionData = new HashMap<>();
}

/**
* Sets subject context.
*
* @param context The context to use for subject
*/
public void setSubjectContext(URI context) {
this.subjectContext = context;
}

public URI getSubjectContext() {
return subjectContext;
}

/**
* Adds the specified assertion to this descriptor.
*
* @param assertion The assertion to add
* @throws NullPointerException When {@code assertion} is {@code null}
*/
public void addAssertion(Assertion assertion) {
Objects.requireNonNull(assertion);
assertionData.put(assertion, new AssertionData());
}

/**
* Gets unmodifiable view of the properties in this descriptor.
*
* @return Set of assertions in this descriptor
*/
public Set<Assertion> getAssertions() {
return Collections.unmodifiableSet(assertionData.keySet());
}

/**
* Checks whether this descriptor contains the specified assertion.
*
* @param assertion The assertion to check
* @return True if the assertion is already present in this descriptor, false otherwise
*/
public boolean containsAssertion(Assertion assertion) {
return assertionData.containsKey(assertion);
}

@Override
public Set<URI> getSubjectContexts() {
return Collections.singleton(getSubjectContext());
}

@Override
public Set<URI> getAssertionContexts(Assertion assertion) {
return Collections.singleton(getAssertionContext(assertion));
}

/**
* Gets context of the specified assertion.
* <p>
* If the context was not explicitly set, the same context as the subject's is returned.
*
* @param assertion Assertion for which context should be resolved
* @return Assertion context
*/
public URI getAssertionContext(Assertion assertion) {
Objects.requireNonNull(assertion);
if (!assertionData.containsKey(assertion) || !assertionData.get(assertion).hasContext) {
return subjectContext;
}
return assertionData.get(assertion).context;
}

/**
* Sets context for the specified assertion.
* <p>
* Note that the assertion has to be already present in this descriptor.
*
* @param assertion The property to set context for
* @param context Context URI
* @throws IllegalArgumentException If there is no such assertion in this descriptor
* @throws NullPointerException When {@code assertion} is {@code null}
*/
public void setAssertionContext(Assertion assertion, URI context) {
Objects.requireNonNull(assertion);
if (!assertionData.containsKey(assertion)) {
throw new IllegalArgumentException("Assertion " + assertion + " is not present in this descriptor.");
}
assertionData.get(assertion).setContext(context);
}

/**
Expand Down Expand Up @@ -55,43 +143,48 @@ public AxiomValueDescriptor addAssertionValue(Assertion assertion, Value<?> valu
*/
public List<Value<?>> getAssertionValues(Assertion assertion) {
Objects.requireNonNull(assertion);
if (!values.containsKey(assertion)) {
if (!assertionData.containsKey(assertion)) {
return Collections.emptyList();
}
return Collections.unmodifiableList(values.get(assertion));
return Collections.unmodifiableList(assertionData.get(assertion).values);
}

private List<Value<?>> getAssertionList(Assertion assertion) {
assert assertion != null;
if (!values.containsKey(assertion)) {
values.put(assertion, new ArrayList<>());
if (!assertionData.containsKey(assertion)) {
addAssertion(assertion);
}
return values.get(assertion);
return assertionData.get(assertion).values;
}

@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + values.hashCode();
return result;
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof AxiomValueDescriptor)) return false;
if (!super.equals(o)) return false;
AxiomValueDescriptor that = (AxiomValueDescriptor) o;
return Objects.equals(subjectContext, that.subjectContext) &&
assertionData.equals(that.assertionData);
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
AxiomValueDescriptor other = (AxiomValueDescriptor) obj;
return values.equals(other.values);
public int hashCode() {
return Objects.hash(super.hashCode(), subjectContext, assertionData);
}

@Override
public String toString() {
return super.toString() + ", property values: " + values;
return "AxiomValueDescriptor{<" + getSubject() + "> - " + assertionData + '}';
}

private static class AssertionData {
private final List<Value<?>> values = new ArrayList<>();
private URI context;
private boolean hasContext;

private void setContext(URI context) {
this.context = context;
this.hasContext = true;
}
}
}
Loading

0 comments on commit 91dc0cf

Please sign in to comment.