Skip to content

Commit

Permalink
Backend API changes to support hierarchy descriptors
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewhorridge committed Oct 15, 2024
1 parent 43ca492 commit 01bccb8
Show file tree
Hide file tree
Showing 35 changed files with 1,119 additions and 88 deletions.
10 changes: 5 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<groupId>edu.stanford.protege</groupId>
<artifactId>webprotege-backend-api</artifactId>
<version>1.0.23</version>
<version>2.0.0-SNAPSHOT</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand All @@ -30,7 +30,7 @@
<maven.build.timestamp.format>yyyyMMdd</maven.build.timestamp.format>
<commonmark.version>0.11.0</commonmark.version>
<lucene.version>8.5.2</lucene.version>
<java.version>16</java.version>
<java.version>21</java.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>
</properties>

Expand Down Expand Up @@ -248,9 +248,9 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>16</source>
<target>16</target>
<release>16</release>
<source>17</source>
<target>17</target>
<release>17</release>
</configuration>
</plugin>
<plugin>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package edu.stanford.protege.webprotege.hierarchy;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import org.semanticweb.owlapi.model.OWLAnnotationProperty;
import org.semanticweb.owlapi.vocab.OWLRDFVocabulary;
import uk.ac.manchester.cs.owl.owlapi.OWLAnnotationPropertyImpl;
import uk.ac.manchester.cs.owl.owlapi.OWLObjectPropertyImpl;

import java.util.Set;

@JsonTypeName("AnnotationPropertyHierarchyDescriptor")
public record AnnotationPropertyHierarchyDescriptor(@JsonProperty("roots") Set<OWLAnnotationProperty> roots) implements HierarchyDescriptor {

public AnnotationPropertyHierarchyDescriptor(@JsonProperty("roots") Set<OWLAnnotationProperty> roots) {
this.roots = Set.copyOf(roots);
}

public static AnnotationPropertyHierarchyDescriptor create() {
return new AnnotationPropertyHierarchyDescriptor(Set.of());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package edu.stanford.protege.webprotege.hierarchy;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.vocab.OWLRDFVocabulary;
import uk.ac.manchester.cs.owl.owlapi.OWLClassImpl;

import java.util.Set;

@JsonTypeName("ClassHierarchyDescriptor")
public record ClassHierarchyDescriptor(@JsonProperty("roots") Set<OWLClass> roots) implements HierarchyDescriptor {

public ClassHierarchyDescriptor(Set<OWLClass> roots) {
this.roots = Set.copyOf(roots);
}

@JsonCreator
public static ClassHierarchyDescriptor create(@JsonProperty("roots") Set<OWLClass> roots) {
return new ClassHierarchyDescriptor(roots);
}

public static ClassHierarchyDescriptor create() {
return create(Set.of(new OWLClassImpl(OWLRDFVocabulary.OWL_THING.getIRI())));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package edu.stanford.protege.webprotege.hierarchy;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import org.semanticweb.owlapi.model.OWLDataProperty;
import org.semanticweb.owlapi.vocab.OWLRDFVocabulary;
import uk.ac.manchester.cs.owl.owlapi.OWLDataPropertyImpl;
import uk.ac.manchester.cs.owl.owlapi.OWLObjectPropertyImpl;

import java.util.Set;

@JsonTypeName("DataPropertyHierarchyDescriptor")
public record DataPropertyHierarchyDescriptor(@JsonProperty("roots") Set<OWLDataProperty> roots) implements HierarchyDescriptor {

public DataPropertyHierarchyDescriptor(Set<OWLDataProperty> roots) {
this.roots = Set.copyOf(roots);
}

public static DataPropertyHierarchyDescriptor create() {
return new DataPropertyHierarchyDescriptor(Set.of(new OWLDataPropertyImpl(OWLRDFVocabulary.OWL_TOP_DATA_PROPERTY.getIRI())));
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
package edu.stanford.protege.webprotege.hierarchy;


import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import edu.stanford.protege.webprotege.common.EventId;
import edu.stanford.protege.webprotege.common.ProjectEvent;
import edu.stanford.protege.webprotege.common.ProjectId;

import javax.annotation.Nonnull;
import java.util.Objects;

/**
* Matthew Horridge Stanford Center for Biomedical Informatics Research 1 Dec 2017
*/
@JsonTypeName("webprotege.events.hierarchies.EntityHierarchyChanged")
public record EntityHierarchyChangedEvent(@Nonnull EventId eventId,
@Nonnull ProjectId projectId,
@Nonnull HierarchyId hierarchyId,
@Nonnull GraphModelChangedEvent changeEvent) implements ProjectEvent {
public record EntityHierarchyChangedEvent(@JsonProperty("eventId") @Nonnull EventId eventId,
@JsonProperty("projectId") @Nonnull ProjectId projectId,
@JsonProperty("hierarchyDescriptor") @Nonnull HierarchyDescriptor hierarchyDescriptor,
@JsonProperty("changeEvent") @Nonnull GraphModelChangedEvent changeEvent) implements ProjectEvent {

public static final String CHANNEL = "webprotege.events.hierarchies.EntityHierarchyChanged";

public EntityHierarchyChangedEvent(@JsonProperty("eventId") @Nonnull EventId eventId, @JsonProperty("projectId") @Nonnull ProjectId projectId, @JsonProperty("hierarchyDescriptor") @Nonnull HierarchyDescriptor hierarchyDescriptor, @JsonProperty("changeEvent") @Nonnull GraphModelChangedEvent changeEvent) {
this.eventId = Objects.requireNonNull(eventId);
this.projectId = Objects.requireNonNull(projectId);
this.hierarchyDescriptor = Objects.requireNonNull(hierarchyDescriptor);
this.changeEvent = Objects.requireNonNull(changeEvent);
}

@Override
public String getChannel() {
return CHANNEL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
@JsonTypeName("webprotege.hierarchies.GetHierarchyChildren")
public record GetHierarchyChildrenAction(@JsonProperty("projectId") @Nonnull ProjectId projectId,
@JsonProperty("entity") @Nonnull OWLEntity entity,
@JsonProperty("hierarchyId") @Nonnull HierarchyId hierarchyId,
@JsonProperty("hierarchyDescriptor") @Nonnull HierarchyDescriptor hierarchyDescriptor,
@JsonProperty("pageRequest") @Nonnull PageRequest pageRequest) implements ProjectAction<GetHierarchyChildrenResult> {

public static final String CHANNEL = "webprotege.hierarchies.GetHierarchyChildren";
Expand All @@ -31,11 +31,11 @@ public String getChannel() {

public GetHierarchyChildrenAction(@JsonProperty("projectId") @Nonnull ProjectId projectId,
@JsonProperty("entity") @Nonnull OWLEntity entity,
@JsonProperty("hierarchyId") @Nonnull HierarchyId hierarchyId,
@JsonProperty("hierarchyDescriptor") @Nonnull HierarchyDescriptor hierarchyDescriptor,
@JsonProperty("pageRequest") @Nonnull PageRequest pageRequest) {
this.projectId = checkNotNull(projectId);
this.entity = checkNotNull(entity);
this.hierarchyId = checkNotNull(hierarchyId);
this.hierarchyDescriptor = checkNotNull(hierarchyDescriptor);
this.pageRequest = checkNotNull(pageRequest);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@
/**
* Matthew Horridge Stanford Center for Biomedical Informatics Research 28 Nov 2017
*/


@JsonTypeName("webprotege.hierarchies.GetHierarchyParents")
public record GetHierarchyParentsAction(@JsonProperty("projectId") @Nonnull ProjectId projectId,
@JsonProperty("entity") @Nonnull OWLEntity entity,
@JsonProperty("hierarchyId") @Nonnull HierarchyId hierarchyId) implements ProjectAction<GetHierarchyParentsResult> {
@JsonProperty("hierarchyDescriptor") @Nonnull HierarchyDescriptor hierarchyDescriptor) implements ProjectAction<GetHierarchyParentsResult> {

public static final String CHANNEL = "webprotege.hierarchies.GetHierarchyParents";

Expand All @@ -29,9 +27,9 @@ public String getChannel() {

public GetHierarchyParentsAction(@JsonProperty("projectId") @Nonnull ProjectId projectId,
@JsonProperty("entity") @Nonnull OWLEntity entity,
@JsonProperty("hierarchyId") @Nonnull HierarchyId hierarchyId) {
@JsonProperty("hierarchyDescriptor") @Nonnull HierarchyDescriptor hierarchyDescriptor) {
this.projectId = checkNotNull(projectId);
this.entity = checkNotNull(entity);
this.hierarchyId = checkNotNull(hierarchyId);
this.hierarchyDescriptor = checkNotNull(hierarchyDescriptor);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
@JsonTypeName("webprotege.hierarchies.GetHierarchyPathsToRoot")
public record GetHierarchyPathsToRootAction(@JsonProperty("projectId") @Nonnull ProjectId projectId,
@JsonProperty("entity") @Nonnull OWLEntity entity,
@JsonProperty("hierarchyId") @Nonnull HierarchyId hierarchyId) implements ProjectAction<GetHierarchyPathsToRootResult> {
@JsonProperty("hierarchyDescriptor") @Nonnull HierarchyDescriptor hierarchyDescriptor) implements ProjectAction<GetHierarchyPathsToRootResult> {

public static final String CHANNEL = "webprotege.hierarchies.GetHierarchyPathsToRoot";

Expand All @@ -29,9 +29,9 @@ public String getChannel() {

public GetHierarchyPathsToRootAction(@JsonProperty("projectId") @Nonnull ProjectId projectId,
@JsonProperty("entity") @Nonnull OWLEntity entity,
@JsonProperty("hierarchyId") @Nonnull HierarchyId hierarchyId) {
@JsonProperty("hierarchyDescriptor") @Nonnull HierarchyDescriptor hierarchyDescriptor) {
this.projectId = checkNotNull(projectId);
this.entity = checkNotNull(entity);
this.hierarchyId = checkNotNull(hierarchyId);
this.hierarchyDescriptor = checkNotNull(hierarchyDescriptor);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* Matthew Horridge Stanford Center for Biomedical Informatics Research 30 Nov 2017
*/
@JsonTypeName("webprotege.hierarchies.GetHierarchyRoots")
public record GetHierarchyRootsAction(@Nonnull ProjectId projectId, @Nonnull HierarchyId hierarchyId) implements ProjectAction<GetHierarchyRootsResult> {
public record GetHierarchyRootsAction(@Nonnull ProjectId projectId, @Nonnull HierarchyDescriptor hierarchyDescriptor) implements ProjectAction<GetHierarchyRootsResult> {

public static final String CHANNEL = "webprotege.hierarchies.GetHierarchyRoots";

Expand All @@ -21,8 +21,8 @@ public String getChannel() {
return CHANNEL;
}

public GetHierarchyRootsAction(@Nonnull ProjectId projectId, @Nonnull HierarchyId hierarchyId) {
public GetHierarchyRootsAction(@Nonnull ProjectId projectId, @Nonnull HierarchyDescriptor hierarchyDescriptor) {
this.projectId = checkNotNull(projectId);
this.hierarchyId = checkNotNull(hierarchyId);
this.hierarchyDescriptor = checkNotNull(hierarchyDescriptor);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
@JsonTypeName("webprotege.hierarchies.GetHierarchySiblings")
public record GetHierarchySiblingsAction(@JsonProperty("projectId") ProjectId projectId,
@JsonProperty("entity") OWLEntity entity,
@JsonProperty("hierarchyId") HierarchyId hierarchyId,
@JsonProperty("hierarchyDescriptor") HierarchyDescriptor hierarchyDescriptor,
@JsonProperty("pageRequest") PageRequest pageRequest) implements ProjectAction<GetHierarchySiblingsResult> {

public static final String CHANNEL = "webprotege.hierarchies.GetHierarchySiblings";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package edu.stanford.protege.webprotege.hierarchy;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({
@JsonSubTypes.Type(ClassHierarchyDescriptor.class),
@JsonSubTypes.Type(ObjectPropertyHierarchyDescriptor.class),
@JsonSubTypes.Type(DataPropertyHierarchyDescriptor.class),
@JsonSubTypes.Type(AnnotationPropertyHierarchyDescriptor.class)
})
public sealed interface HierarchyDescriptor permits ClassHierarchyDescriptor, ObjectPropertyHierarchyDescriptor, DataPropertyHierarchyDescriptor, AnnotationPropertyHierarchyDescriptor {


}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
@JsonTypeName("webprotege.hierarchies.MoveHierarchyNode")
public record MoveHierarchyNodeAction(@JsonProperty("changeRequestId") ChangeRequestId changeRequestId,
@JsonProperty("projectId") @Nonnull ProjectId projectId,
@JsonProperty("hierarchyId") @Nonnull HierarchyId hierarchyId,
@JsonProperty("hierarchyDescriptor") @Nonnull HierarchyDescriptor hierarchyDescriptor,
@JsonProperty("fromNodePath") @Nonnull Path<EntityNode> fromNodePath,
@JsonProperty("toNodeParentPath") @Nonnull Path<EntityNode> toNodeParentPath,
@JsonProperty("dropType") @Nonnull DropType dropType) implements ProjectAction<MoveHierarchyNodeResult>, ContentChangeRequest {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package edu.stanford.protege.webprotege.hierarchy;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.vocab.OWLRDFVocabulary;
import uk.ac.manchester.cs.owl.owlapi.OWLObjectPropertyImpl;

import java.util.Set;

@JsonTypeName("ObjectPropertyHierarchyDescriptor")
public record ObjectPropertyHierarchyDescriptor(@JsonProperty("roots") Set<OWLObjectProperty> roots) implements HierarchyDescriptor {

public ObjectPropertyHierarchyDescriptor(Set<OWLObjectProperty> roots) {
this.roots = Set.copyOf(roots);
}

public static ObjectPropertyHierarchyDescriptor create() {
return new ObjectPropertyHierarchyDescriptor(Set.of(new OWLObjectPropertyImpl(OWLRDFVocabulary.OWL_TOP_OBJECT_PROPERTY.getIRI())));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package edu.stanford.protege.webprotege.hierarchy;

import org.junit.jupiter.api.Test;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.json.JsonTest;
import org.springframework.boot.test.json.JacksonTester;

import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;

@JsonTest
class AnnotationPropertyHierarchyDescriptorJsonTest {


public static final String ROOT_IRI = "http://example.org/prop";
@Autowired
private JacksonTester<AnnotationPropertyHierarchyDescriptor> jacksonTester;

@Autowired
private OWLDataFactory dataFactory;

@Test
void testSerializeClassHierarchyDescriptor() throws Exception {
var prop = dataFactory.getOWLAnnotationProperty(IRI.create(ROOT_IRI));
var descriptor = new AnnotationPropertyHierarchyDescriptor(Set.of(prop));
var json = jacksonTester.write(descriptor);

// Check for the correct JSON structure
assertThat(json).hasJsonPathArrayValue("roots")
.extractingJsonPathStringValue("roots[0].iri")
.isEqualTo(ROOT_IRI);

// Assert that the @type is correct
assertThat(json).extractingJsonPathStringValue("['@type']")
.isEqualTo("AnnotationPropertyHierarchyDescriptor");
}

@Test
void testDeserializeClassHierarchyDescriptor() throws Exception {
var json = """
{
"@type": "AnnotationPropertyHierarchyDescriptor",
"roots": [
{
"@type" : "AnnotationProperty",
"iri": "http://example.org/prop"
}
]
}
""";

var objectContent = jacksonTester.parse(json);
var descriptor = objectContent.getObject();

assertThat(descriptor).isNotNull();
assertThat(descriptor.roots()).hasSize(1);
var rootClass = descriptor.roots().iterator().next();
assertThat(rootClass.getIRI().toString()).isEqualTo(ROOT_IRI);
}
}
Loading

0 comments on commit 01bccb8

Please sign in to comment.