diff --git a/core/pom.xml b/core/pom.xml index ce94401..74e58f3 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -17,6 +17,11 @@ + + org.incenp + linkml-core + 0.1.0-SNAPSHOT + org.antlr antlr4-runtime diff --git a/core/src/main/java/org/incenp/obofoundry/kgcl/KGCLHelper.java b/core/src/main/java/org/incenp/obofoundry/kgcl/KGCLHelper.java index 433b1e2..3bbc5a2 100644 --- a/core/src/main/java/org/incenp/obofoundry/kgcl/KGCLHelper.java +++ b/core/src/main/java/org/incenp/obofoundry/kgcl/KGCLHelper.java @@ -22,9 +22,12 @@ import java.io.IOException; import java.io.StringReader; import java.time.ZonedDateTime; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.incenp.linkml.core.ConverterContext; +import org.incenp.linkml.core.LinkMLRuntimeException; import org.incenp.obofoundry.kgcl.model.Change; import org.incenp.obofoundry.kgcl.owl.OntologyPatcher; import org.incenp.obofoundry.kgcl.owl.ProvisionalOWLTranslator; @@ -33,6 +36,9 @@ import org.semanticweb.owlapi.reasoner.OWLReasoner; import org.semanticweb.owlapi.util.DefaultPrefixManager; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; + /** * A class providing static helper methods to work with KGCL. */ @@ -210,6 +216,59 @@ private static List doParse(KGCLReader reader, PrefixManager prefixManag return reader.getChangeSet(); } + /** + * Parses a changeset serialised in YAML form. + * + * @param kgcl The YAML file from which to read the changeset. That file is + * expected to contain a list of KGCL change objects. + * @param prefixMap A map of prefix names to prefix IRIs. May be {@code null}. + * @return A KGCL changeset. + * @throws IOException If any error occurs. Note that, contrary to the methods + * that read from the KGCL controlled natural language, here + * this includes post-I/O errors caused by invalid KGCL + * contents within the source file. + */ + public static List parseYAML(File kgcl, Map prefixMap) throws IOException { + List changeset = new ArrayList<>(); + + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + @SuppressWarnings("unchecked") + List rawChanges = mapper.readValue(kgcl, List.class); + + ConverterContext ctx = new ConverterContext(); + if ( prefixMap != null ) { + prefixMap.forEach(ctx::addPrefix); + } + try { + for ( Object rawChange : rawChanges ) { + changeset.add((Change) ctx.getConverter(Change.class).convert(rawChange, ctx)); + } + ctx.finalizeAssignments(); + } catch ( LinkMLRuntimeException e ) { + throw new IOException("Cannot read KGCL file: invalid content", e); + } + + return changeset; + } + + /** + * Parses a changeset serialised in YAML form. + * + * @param kgcl The YAML file from which to read the changeset. That + * file is expected to contain a list of KGCL + * change objects. + * @param prefixManager A prefix manager to expand CURIEs into IRIs. May be + * {@code null}. + * @return A KGCL changeset. + * @throws IOException If any error occurs. Note that, contrary to the methods + * that read from the KGCL controlled natural language, here + * this includes post-I/O errors caused by invalid KGCL + * contents within the source file. + */ + public static List parseYAML(File kgcl, PrefixManager prefixManager) throws IOException { + return parseYAML(kgcl, prefixManager != null ? prefixManager.getPrefixName2PrefixMap() : null); + } + /** * Gets the "pending" (provisional) changes that are stored as KGCL annotations * in the ontology, diff --git a/core/src/main/java/org/incenp/obofoundry/kgcl/KGCLTextTranslator.java b/core/src/main/java/org/incenp/obofoundry/kgcl/KGCLTextTranslator.java index 23d21f4..8a3c91d 100644 --- a/core/src/main/java/org/incenp/obofoundry/kgcl/KGCLTextTranslator.java +++ b/core/src/main/java/org/incenp/obofoundry/kgcl/KGCLTextTranslator.java @@ -292,7 +292,22 @@ public String visit(NodeDeletion v) { @Override public String visit(NodeCreation v) { - return String.format("create %s %s %s", v.getAboutNode().getOwlType(), renderNode(v.getAboutNode()), + String nodeType = null; + switch ( v.getAboutNode().getOwlType() ) { + case ANNOTATION_PROPERTY: + nodeType = "annotation property"; + break; + case CLASS: + nodeType = "class"; + break; + case NAMED_INDIVIDUAL: + nodeType = "instance"; + break; + case OBJECT_PROPERTY: + nodeType = "relation"; + break; + } + return String.format("create %s %s %s", nodeType, renderNode(v.getAboutNode()), renderNewValue(v)); } diff --git a/core/src/main/java/org/incenp/obofoundry/kgcl/SimpleChangeConverter.java b/core/src/main/java/org/incenp/obofoundry/kgcl/SimpleChangeConverter.java new file mode 100644 index 0000000..b1be54b --- /dev/null +++ b/core/src/main/java/org/incenp/obofoundry/kgcl/SimpleChangeConverter.java @@ -0,0 +1,89 @@ +/* + * KGCL-Java - KGCL library for Java + * Copyright © 2026 Damien Goutte-Gattat + * + * 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 . + */ + +package org.incenp.obofoundry.kgcl; + +import java.util.Map; + +import org.incenp.linkml.core.ConverterContext; +import org.incenp.linkml.core.LinkMLRuntimeException; +import org.incenp.linkml.core.ObjectConverter; +import org.incenp.obofoundry.kgcl.model.SimpleChange; + +/** + * A custom LinkML converter for SimpleChange objects. + *

+ * A custom converter is needed here because, even though the + * new_value and old_value slots of the + * {@link SimpleChange} class are typed as strings, they are sometimes expected + * to contain CURIEs, when the value that is being affected by the change is + * itself an IRI (for example, when the change is a + * PredicateChange). + *

+ * When that happens, the fact that old_value (resp. + * new_value) is a CURIE is indicated by the + * old_value_type (resp. new_value_type) slot, which + * is set to curie. This is a KGCL-specific mechanism that cannot + * be handled generically at the level of the LinkML runtime, so we must deal + * with it here. + *

+ * An alternative option would be to deal with those values in a post-parsing + * step, in which we iterate over SimpleChange-typed changes and expand their + * old_value / new_value slots as needed. But custom + * converters offer a nice way of ensuring that expansion is done for us during + * the parsing phase. + */ +public class SimpleChangeConverter extends ObjectConverter { + + public SimpleChangeConverter(Class type) { + super(type); + } + + @Override + public void convertTo(Map raw, Object dest, ConverterContext ctx) throws LinkMLRuntimeException { + // Let the default converter do most of the job + super.convertTo(raw, dest, ctx); + + // Then expand the old_value/new_value slots if needed + SimpleChange c = (SimpleChange) dest; + if ( c.getOldValueType() != null && c.getOldValueType().equals("curie") && c.getOldValue() != null ) { + c.setOldValue(ctx.resolve(c.getOldValue())); + } + if ( c.getNewValueType() != null && c.getNewValueType().equals("curie") && c.getNewValue() != null ) { + c.setNewValue(ctx.resolve(c.getNewValue())); + } + } + + @Override + public Map serialise(Object object, boolean withIdentifier, ConverterContext ctx) + throws LinkMLRuntimeException { + // Same approach as above: we let the default converter do its job + Map serialised = super.serialise(object, withIdentifier, ctx); + + // Then we overwrite the new/old_value slots if needed + SimpleChange c = (SimpleChange) object; + if ( c.getOldValueType() != null && c.getOldValueType().equals("curie") && c.getOldValue() != null ) { + serialised.put("old_value", ctx.compact(c.getOldValue())); + } + if ( c.getNewValueType() != null && c.getNewValueType().equals("curie") && c.getNewValue() != null ) { + serialised.put("new_value", ctx.compact(c.getNewValue())); + } + + return serialised; + } +} diff --git a/core/src/main/java/org/incenp/obofoundry/kgcl/model/OwlType.java b/core/src/main/java/org/incenp/obofoundry/kgcl/model/OwlType.java deleted file mode 100644 index 507ca4b..0000000 --- a/core/src/main/java/org/incenp/obofoundry/kgcl/model/OwlType.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * KGCL-Java - KGCL library for Java - * Copyright © 2024 Damien Goutte-Gattat - * - * 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 . - */ - -package org.incenp.obofoundry.kgcl.model; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - * Represents the type of a node, when the knowledge graph is backed by an OWL - * ontology. - */ -public enum OwlType { - CLASS("class"), - OBJECT_PROPERTY("relation"), - NAMED_INVIDIDUAL("instance"), - ANNOTATION_PROPERTY("annotation property"); - - private final static Map MAP; - - static { - Map map = new HashMap(); - for ( OwlType value : OwlType.values() ) { - map.put(value.toString(), value); - } - - MAP = Collections.unmodifiableMap(map); - } - - private final String repr; - - OwlType(String repr) { - this.repr = repr; - } - - @Override - public String toString() { - return repr; - } - - /** - * Parses a string into a OwlType enum value. - * - * @param v The string to parse. - * @return The corresponding enumeration value, or {@code null} if the string - * does not match any allowed value. - */ - public static OwlType fromString(String v) { - return MAP.get(v); - } -} diff --git a/core/src/main/java/org/incenp/obofoundry/kgcl/owl/DirectOWLTranslator.java b/core/src/main/java/org/incenp/obofoundry/kgcl/owl/DirectOWLTranslator.java index ab62db2..bb3d4ee 100644 --- a/core/src/main/java/org/incenp/obofoundry/kgcl/owl/DirectOWLTranslator.java +++ b/core/src/main/java/org/incenp/obofoundry/kgcl/owl/DirectOWLTranslator.java @@ -576,7 +576,7 @@ public List visit(NodeCreation v) { addedClasses.add(nodeIRI); } break; - case NAMED_INVIDIDUAL: + case NAMED_INDIVIDUAL: if ( ontology.containsIndividualInSignature(nodeIRI) ) { onReject(v, "Invididual <%s> already exists", nodeIRI.toString()); } else { diff --git a/core/src/main/java/org/incenp/obofoundry/kgcl/parser/ParseTree2ChangeVisitor.java b/core/src/main/java/org/incenp/obofoundry/kgcl/parser/ParseTree2ChangeVisitor.java index fcac84f..c0c850e 100644 --- a/core/src/main/java/org/incenp/obofoundry/kgcl/parser/ParseTree2ChangeVisitor.java +++ b/core/src/main/java/org/incenp/obofoundry/kgcl/parser/ParseTree2ChangeVisitor.java @@ -249,7 +249,23 @@ public Void visitChangeDefinition(KGCLParser.ChangeDefinitionContext ctx) { @Override public Void visitNewNode(KGCLParser.NewNodeContext ctx) { NodeCreation change = null; - OwlType type = OwlType.fromString(ctx.nodeType().getText()); + OwlType type = null; + switch (ctx.nodeType().getText()) { + case "class": + type = OwlType.CLASS; + break; + case "relation": + type = OwlType.OBJECT_PROPERTY; + break; + + case "instance": + type = OwlType.NAMED_INDIVIDUAL; + break; + + case "annotation property": + type = OwlType.ANNOTATION_PROPERTY; + break; + } switch ( type ) { case CLASS: diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Activity.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Activity.java index cdc3172..cc8afaf 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Activity.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Activity.java @@ -1,19 +1,34 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * a provence-generating activity */ @Data @EqualsAndHashCode(callSuper=false) public class Activity extends ProvElement { + @Identifier + @Converter(CurieConverter.class) private String id; + @SlotName("started_at_time") private String startedAtTime; + @SlotName("ended_at_time") private String endedAtTime; + @SlotName("was_informed_by") private Activity wasInformedBy; + @SlotName("was_associated_with") private Agent wasAssociatedWith; private String used; private String description;} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/AddNodeToSubset.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/AddNodeToSubset.java index 3b9ef76..ff9a02b 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/AddNodeToSubset.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/AddNodeToSubset.java @@ -1,16 +1,27 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * Places a node inside a subset, by annotating that node */ @Data @EqualsAndHashCode(callSuper=true) public class AddNodeToSubset extends NodeChange { + @SlotName("in_subset") private OntologySubset inSubset; + private OntologyElement about; public T accept(IChangeVisitor v) { return v.visit(this); } diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/AddToSubset.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/AddToSubset.java deleted file mode 100644 index 260c33e..0000000 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/AddToSubset.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.incenp.obofoundry.kgcl.model; - -import java.util.List; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * placing an element inside a subset - */ -@Data -@EqualsAndHashCode(callSuper=true) -public class AddToSubset extends SubsetMembershipChange {} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Agent.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Agent.java index 1104ec7..047154b 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Agent.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Agent.java @@ -1,15 +1,28 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * a provence-generating agent */ @Data @EqualsAndHashCode(callSuper=false) public class Agent extends ProvElement { + @Identifier + @Converter(CurieConverter.class) private String id; + @SlotName("acted_on_behalf_of") private Agent actedOnBehalfOf; + @SlotName("was_informed_by") private Activity wasInformedBy;} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/AllowsAutomaticReplacementOfEdges.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/AllowsAutomaticReplacementOfEdges.java deleted file mode 100644 index 27d5802..0000000 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/AllowsAutomaticReplacementOfEdges.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.incenp.obofoundry.kgcl.model; - -import java.util.List; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * Applies to an obsoletion in which annotations or edges pointing at the obsoleted node can be automatically rewired to point to a target - */ -@Data -@EqualsAndHashCode(callSuper=false) -public class AllowsAutomaticReplacementOfEdges extends Obsoletion {} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Annotation.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Annotation.java index 7a5c7b4..cac901f 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Annotation.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Annotation.java @@ -1,15 +1,27 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * owl annotations. Not to be confused with annotations sensu GO */ @Data @EqualsAndHashCode(callSuper=true) public class Annotation extends PropertyValue { + @SlotName("annotation_set") private Annotation annotationSet; + @SlotName("property_type") private String propertyType; + @SlotName("filler_type") private String fillerType;} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Change.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Change.java index ffc4678..bc47337 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Change.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Change.java @@ -2,24 +2,47 @@ import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * Any change perform on an ontology or knowledge graph */ @Data @EqualsAndHashCode(callSuper=false) public class Change extends ChangeLanguageElement { + @Identifier + @Converter(CurieConverter.class) private String id; + @TypeDesignator private String type; + @SlotName("was_generated_by") private Activity wasGeneratedBy; + @SlotName("see_also") private String seeAlso; + @SlotName("pull_request") private String pullRequest; + @SlotName("term_tracker_issue") + private String termTrackerIssue; private String creator; + @SlotName("change_date") private ZonedDateTime changeDate; private String contributor; + @SlotName("has_undo") private Change hasUndo; + @SlotName("change_description") + private String changeDescription; + @SlotName("associated_change_set") + @Inlined(asList = true) + private List associatedChangeSet; public T accept(IChangeVisitor v) { return v.visit(this); } diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ChangeLanguageElement.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ChangeLanguageElement.java index 3916736..22a109d 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ChangeLanguageElement.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ChangeLanguageElement.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A broad grouping for all elements of the change language */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ChangeMixin.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ChangeMixin.java deleted file mode 100644 index d826cb6..0000000 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ChangeMixin.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.incenp.obofoundry.kgcl.model; - -import java.util.List; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * root class for all change mixins - */ -@Data -@EqualsAndHashCode(callSuper=false) -public class ChangeMixin {} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ChangeSetSummaryStatistic.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ChangeSetSummaryStatistic.java index 8b46587..6bd4ddc 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ChangeSetSummaryStatistic.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ChangeSetSummaryStatistic.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A summary statistic for a set of changes of the same type, grouped by zero or more node properties */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ClassCreation.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ClassCreation.java index 8d41fa4..ad763a0 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ClassCreation.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ClassCreation.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node creation where the owl type is 'owl:Class' */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ClassNode.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ClassNode.java index e160f30..074d818 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ClassNode.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ClassNode.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node that is a class */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ComplexChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ComplexChange.java index 0899fba..3bb5775 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ComplexChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ComplexChange.java @@ -1,15 +1,26 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A change that is is a composition of other changes */ @Data @EqualsAndHashCode(callSuper=true) public class ComplexChange extends Change { + @SlotName("change_set") + @Inlined(asList = true) private List changeSet; public T accept(IChangeVisitor v) { return v.visit(this); diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Configuration.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Configuration.java index 0cd57fa..f8bd1d7 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Configuration.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Configuration.java @@ -1,22 +1,42 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * The meaning of operations can be configured */ @Data @EqualsAndHashCode(callSuper=false) public class Configuration extends ChangeLanguageElement { + @SlotName("name_predicate") private String namePredicate; + @SlotName("definition_predicate") private String definitionPredicate; + @SlotName("main_synonym_predicate") private String mainSynonymPredicate; + @SlotName("synonym_predicates") private String synonymPredicates; + @SlotName("creator_predicate") private String creatorPredicate; + @SlotName("contributor_predicate") private String contributorPredicate; + @SlotName("obsolete_node_label_prefix") private String obsoleteNodeLabelPrefix; + @SlotName("obsoletion_workflow") private String obsoletionWorkflow; - private List obsoletionPolicies; + @SlotName("obsoletion_policies") + private List obsoletionPolicies; + @SlotName("obsolete_subclass_of_shadow_property") + @Converter(CurieConverter.class) private String obsoleteSubclassOfShadowProperty;} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Creation.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Creation.java deleted file mode 100644 index bddc80d..0000000 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Creation.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.incenp.obofoundry.kgcl.model; - -import java.util.List; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * Creation of an element. - */ -@Data -@EqualsAndHashCode(callSuper=false) -public class Creation extends ChangeMixin {} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/DatatypeChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/DatatypeChange.java deleted file mode 100644 index 8f66b94..0000000 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/DatatypeChange.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.incenp.obofoundry.kgcl.model; - -import java.util.List; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * None - */ -@Data -@EqualsAndHashCode(callSuper=false) -public class DatatypeChange extends DatatypeOrLanguageTagChange {} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/DatatypeOrLanguageTagChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/DatatypeOrLanguageTagChange.java deleted file mode 100644 index fdca948..0000000 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/DatatypeOrLanguageTagChange.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.incenp.obofoundry.kgcl.model; - -import java.util.List; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * A change in a value assertion where the value remain unchanged but either the datatype or language changes - */ -@Data -@EqualsAndHashCode(callSuper=false) -public class DatatypeOrLanguageTagChange extends ChangeMixin {} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Deletion.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Deletion.java deleted file mode 100644 index 82ade6d..0000000 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Deletion.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.incenp.obofoundry.kgcl.model; - -import java.util.List; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * Removal of an element. - */ -@Data -@EqualsAndHashCode(callSuper=false) -public class Deletion extends ChangeMixin {} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Edge.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Edge.java index b570aa1..89a880c 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Edge.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Edge.java @@ -1,11 +1,33 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A relationship between two nodes. +Currently the only kinds of edges supported in KGCL: + + * A subClassOf B <==> Edge(subject=A, predicate=owl:subClassOf, object=B) + * A subClassOf P some B <==> Edge(subject=A, predicate=P, object=B) + * P subPropertyOf Q <==> Edge(subject=P, predicate=owl:subPropertyOf, object=Q) + +These represent the most common kind of pairwise relationship between classes, and classes are the dominant node type in ontologies. +In future a wider variety of OWL axiom types will be supportedn through the use of an additional edge property/slot to indicate the interpretation of the axiom, following owlstar (https://github.com/cmungall/owlstar). +For example: + * `A subClassOf R only B <==> Edge(subject=A, predicate=P, object=B, interpretation=AllOnly)` + * `A Annotation(P,B) <==> Edge(subject=A, predicate=P, object=B, interpretation=annotationAssertion)` + +Note that not all axioms are intended to map to edges. Axioms/triples where the object is a literal would be represented as node properties. Complex OWL axioms involving nesting would have their own dedicated construct, or may be represented generically. These are out of scope for the current version of KGCL */ @Data @EqualsAndHashCode(callSuper=false) @@ -13,7 +35,11 @@ public class Edge extends OntologyElement { private Node subject; private Node predicate; private Node object; + @SlotName("subject_representation") private String subjectRepresentation; + @SlotName("predicate_representation") private String predicateRepresentation; + @SlotName("object_representation") private String objectRepresentation; - private Annotation annotationSet;} + @SlotName("annotation_set") + private Annotation annotationSet;} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeChange.java index 64d797f..b830dac 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeChange.java @@ -1,16 +1,27 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A change in which the element that is the focus of the change is an edge. */ @Data @EqualsAndHashCode(callSuper=true) public class EdgeChange extends SimpleChange { + @SlotName("about_edge") private Edge aboutEdge; + @SlotName("object_type") private String objectType; private String language; private String datatype; diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeCreation.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeCreation.java index 09e9c8b..7489efa 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeCreation.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeCreation.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * An edge change in which a de-novo edge is created. The edge is potentially annotated in the same action. */ @@ -13,9 +22,13 @@ public class EdgeCreation extends EdgeChange { private Node subject; private Node predicate; private Node object; + @SlotName("subject_type") private String subjectType; + @SlotName("predicate_type") private String predicateType; + @SlotName("annotation_set") private Annotation annotationSet; + private OntologyElement about; public T accept(IChangeVisitor v) { return v.visit(this); } diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeDeletion.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeDeletion.java index fe30533..4f8b62d 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeDeletion.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeDeletion.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * An edge change in which an edge is removed. All edge annotations/properies are removed in the same action. */ @@ -13,9 +22,13 @@ public class EdgeDeletion extends EdgeChange { private Node subject; private Node predicate; private Node object; + @SlotName("subject_type") private String subjectType; + @SlotName("predicate_type") private String predicateType; + @SlotName("annotation_set") private Annotation annotationSet; + private OntologyElement about; public T accept(IChangeVisitor v) { return v.visit(this); } diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeLogicalInterpretationChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeLogicalInterpretationChange.java index b44b512..cf9dd66 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeLogicalInterpretationChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeLogicalInterpretationChange.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * An edge change where the subject, object, and predicate are unchanged, but the logical interpretation changes */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeObsoletion.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeObsoletion.java index 0babc3c..f170852 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeObsoletion.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeObsoletion.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * An edge change in which an edge is obsoleted. */ @@ -13,7 +22,9 @@ public class EdgeObsoletion extends EdgeChange { private Node subject; private Node predicate; private Node object; + @SlotName("annotation_set") private Annotation annotationSet; + private OntologyElement about; public T accept(IChangeVisitor v) { return v.visit(this); } diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeRewiring.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeRewiring.java index 1923186..3377942 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeRewiring.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/EdgeRewiring.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * An edge change where one node is replaced with another, as in the case of obsoletion with replacement */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/InstanceNode.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/InstanceNode.java index d29449e..a6b845d 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/InstanceNode.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/InstanceNode.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node that is an individual */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/LanguageTagChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/LanguageTagChange.java deleted file mode 100644 index d7e6be5..0000000 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/LanguageTagChange.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.incenp.obofoundry.kgcl.model; - -import java.util.List; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * None - */ -@Data -@EqualsAndHashCode(callSuper=false) -public class LanguageTagChange extends DatatypeOrLanguageTagChange {} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/LogicalAxiomChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/LogicalAxiomChange.java index 6ab1f76..9fc0e6a 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/LogicalAxiomChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/LogicalAxiomChange.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A simple change where a logical axiom is changed, where the logical axiom cannot be represented as an edge */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/LogicalDefinition.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/LogicalDefinition.java index 46cf4cf..430f4cb 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/LogicalDefinition.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/LogicalDefinition.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * None */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MappingCreation.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MappingCreation.java index 4867ba8..3df7583 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MappingCreation.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MappingCreation.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A specific kind of edge creation in which the created edge is a mapping. */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MappingPredicateChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MappingPredicateChange.java index 7465b12..cb876c9 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MappingPredicateChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MappingPredicateChange.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node mapping change where the predicate of a mapping is changed. */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MappingReplacement.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MappingReplacement.java index 8fdbe7b..91de5a3 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MappingReplacement.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MappingReplacement.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node mapping change where the object of a mapping is changed */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MetadataAssertionPredicateChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MetadataAssertionPredicateChange.java index 234d17d..a47b92e 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MetadataAssertionPredicateChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MetadataAssertionPredicateChange.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node metadata assertion change where the predicate of a metadata assertion is changed. */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MetadataAssertionReplacement.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MetadataAssertionReplacement.java index 1003576..c7a092c 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MetadataAssertionReplacement.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MetadataAssertionReplacement.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node metadata assertion change where the object of a metadata assertion is changed */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MultiNodeObsoletion.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MultiNodeObsoletion.java index b0171f8..98ea7e4 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MultiNodeObsoletion.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/MultiNodeObsoletion.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A complex change consisting of multiple obsoletions. */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NameBecomesSynonym.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NameBecomesSynonym.java index c131be2..95eb052 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NameBecomesSynonym.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NameBecomesSynonym.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node synonym where the name NAME of an node NODE moves to a synonym, and NODE receives a new name. This change consists of compose of (1) a node rename where NAME is replaced by a different name (2) a new synonym */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewMapping.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewMapping.java index 043f6bd..216232a 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewMapping.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewMapping.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node mapping change where a mapping is added to a node */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewMetadataAssertion.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewMetadataAssertion.java index 45e1327..cd7a442 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewMetadataAssertion.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewMetadataAssertion.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node metadata assertion change where a metadata assertion is added to a node */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewSynonym.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewSynonym.java index eb3f407..f48cb91 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewSynonym.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewSynonym.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node synonym change where a de-novo synonym is created */ @@ -11,6 +20,7 @@ @EqualsAndHashCode(callSuper=true) public class NewSynonym extends NodeSynonymChange { private String qualifier; + private Node predicate; public T accept(IChangeVisitor v) { return v.visit(this); } diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewTextDefinition.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewTextDefinition.java index 929d5ef..afc1e20 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewTextDefinition.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NewTextDefinition.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node change where a de-novo text definition is created */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Node.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Node.java index ed4410a..57ece2d 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Node.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Node.java @@ -1,16 +1,29 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * Any named entity in an ontology. May be a class, individual, property */ @Data @EqualsAndHashCode(callSuper=false) public class Node extends OntologyElement { + @Identifier + @Converter(CurieConverter.class) private String id; private String name; + @SlotName("annotation_set") private Annotation annotationSet; - private OwlType owlType;} + @SlotName("owl_type") + private OwlType owlType;} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeAnnotationChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeAnnotationChange.java index b69d588..5ee7ed7 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeAnnotationChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeAnnotationChange.java @@ -1,16 +1,27 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node change where the change alters node properties/annotations. TODO */ @Data @EqualsAndHashCode(callSuper=true) public class NodeAnnotationChange extends NodeChange { + @SlotName("annotation_property") private String annotationProperty; + @SlotName("annotation_property_type") private String annotationPropertyType; public T accept(IChangeVisitor v) { return v.visit(this); diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeAnnotationReplacement.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeAnnotationReplacement.java index c2ec0f9..76f6124 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeAnnotationReplacement.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeAnnotationReplacement.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node annotation change where the change replaces a particular property value. TODO */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeChange.java index 37e7185..83f8842 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeChange.java @@ -1,16 +1,27 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A simple change where the change is about a node */ @Data @EqualsAndHashCode(callSuper=true) public class NodeChange extends SimpleChange { + @SlotName("about_node") private Node aboutNode; + @SlotName("about_node_representation") private String aboutNodeRepresentation; private String language; public T accept(IChangeVisitor v) { diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeCreation.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeCreation.java index 86a7135..a72162d 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeCreation.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeCreation.java @@ -1,20 +1,33 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * a node change in which a new node is created */ @Data @EqualsAndHashCode(callSuper=true) public class NodeCreation extends NodeChange { + @SlotName("node_id") private Node nodeId; private String name; + @SlotName("owl_type") private OwlType owlType; + @SlotName("annotation_set") private Annotation annotationSet; + private OntologyElement about; public T accept(IChangeVisitor v) { return v.visit(this); } -} +} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeDeepening.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeDeepening.java index 55e637d..418866e 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeDeepening.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeDeepening.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node move in which a node where the destination is a proper descendant of the original location. Note that here descendant applied not just to subclass, but edges of any predicate in the relational graph */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeDeletion.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeDeletion.java index 72ed30a..f36e71c 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeDeletion.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeDeletion.java @@ -1,15 +1,25 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * Deletion of a node from the graph. Note it is recommended nodes are obsoleted and never merged, but this operation exists to represent deletions in ontologies, accidental or otherwise */ @Data @EqualsAndHashCode(callSuper=true) public class NodeDeletion extends NodeChange { + private OntologyElement about; public T accept(IChangeVisitor v) { return v.visit(this); } diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeDirectMerge.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeDirectMerge.java index 9ea6a8e..e9f912f 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeDirectMerge.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeDirectMerge.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * An obsoletion change in which all metadata (including name/label) from the source node is deleted and added to the target node, and edges can automatically be rewired to point to the target node */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeMappingChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeMappingChange.java index f634ac0..4a49b19 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeMappingChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeMappingChange.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node change where the mappings for that node are altered */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeMetadataAssertionChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeMetadataAssertionChange.java index d403d41..9bd293a 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeMetadataAssertionChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeMetadataAssertionChange.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node change where the metadata assertion (OWL annotations) for that node are altered */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeMove.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeMove.java index 82985a9..6062cb0 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeMove.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeMove.java @@ -1,16 +1,27 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node move is a combination of deleting a parent edge and adding a parent edge, where the predicate is preserved and the object/parent node changes */ @Data @EqualsAndHashCode(callSuper=true) public class NodeMove extends EdgeChange { + @SlotName("old_object_type") private String oldObjectType; + @SlotName("new_object_type") private String newObjectType; public T accept(IChangeVisitor v) { return v.visit(this); diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeObsoletion.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeObsoletion.java index 6045b7f..cc14d4a 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeObsoletion.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeObsoletion.java @@ -1,17 +1,29 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * Obsoletion of a node deprecates usage of that node, but does not delete it. */ @Data @EqualsAndHashCode(callSuper=true) public class NodeObsoletion extends NodeChange { + @SlotName("has_direct_replacement") private Node hasDirectReplacement; + @SlotName("has_nondirect_replacement") private List hasNondirectReplacement; + private OntologyElement about; public T accept(IChangeVisitor v) { return v.visit(this); } diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeObsoletionWithDirectReplacement.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeObsoletionWithDirectReplacement.java index 65f13f9..3f9a6b8 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeObsoletionWithDirectReplacement.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeObsoletionWithDirectReplacement.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * An obsoletion change in which information from the obsoleted node is selectively copied to a single target, and edges can automatically be rewired to point to the target node */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeObsoletionWithNoDirectReplacement.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeObsoletionWithNoDirectReplacement.java index 1ddfe92..1d16c64 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeObsoletionWithNoDirectReplacement.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeObsoletionWithNoDirectReplacement.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * An obsoletion change in which there is no direct replacement */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeRename.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeRename.java index 2af09f8..1609dd9 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeRename.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeRename.java @@ -1,15 +1,25 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node change where the name (aka rdfs:label) of the node changes */ @Data @EqualsAndHashCode(callSuper=true) public class NodeRename extends NodeChange { + @SlotName("has_textual_diff") private TextualDiff hasTextualDiff; public T accept(IChangeVisitor v) { return v.visit(this); diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeShallowing.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeShallowing.java index d2473e6..dd91007 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeShallowing.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeShallowing.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * The opposite of node deepening */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeSynonymChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeSynonymChange.java index bb693c2..b5dc2e6 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeSynonymChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeSynonymChange.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * None */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeTextDefinitionChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeTextDefinitionChange.java index 15f7078..e870c9a 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeTextDefinitionChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeTextDefinitionChange.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node change where the text definition is changed */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeUnobsoletion.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeUnobsoletion.java index 7c289fa..8e95ddc 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeUnobsoletion.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/NodeUnobsoletion.java @@ -1,15 +1,29 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * unobsoletion of a node deprecates usage of that node. Rarely applied. */ @Data @EqualsAndHashCode(callSuper=true) public class NodeUnobsoletion extends NodeChange { + @SlotName("has_direct_replacement") + private Node hasDirectReplacement; + @SlotName("has_nondirect_replacement") + private List hasNondirectReplacement; + private OntologyElement about; public T accept(IChangeVisitor v) { return v.visit(this); } diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ObjectPropertyCreation.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ObjectPropertyCreation.java index 6787386..8ef3759 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ObjectPropertyCreation.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ObjectPropertyCreation.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node creation where the owl type is 'ObjectProperty' */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Obsoletion.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Obsoletion.java deleted file mode 100644 index 95c460a..0000000 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Obsoletion.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.incenp.obofoundry.kgcl.model; - -import java.util.List; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * Obsoletion of an element deprecates usage of that element, but does not delete that element. - */ -@Data -@EqualsAndHashCode(callSuper=false) -public class Obsoletion extends ChangeMixin {} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ObsoletionPolicyEnum.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ObsoletionPolicyEnum.java new file mode 100644 index 0000000..ba2e763 --- /dev/null +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ObsoletionPolicyEnum.java @@ -0,0 +1,48 @@ +package org.incenp.obofoundry.kgcl.model; + +import java.util.Map; +import java.util.HashMap; +import java.util.Collections; + +import com.fasterxml.jackson.annotation.JsonCreator; + +public enum ObsoletionPolicyEnum { + + /** + * The obsoletion policy is that there MUST NOT be logical axioms about an obsolete node + */ + NOLOGICALAXIOMSONOBSOLETES("NoLogicalAxiomsOnObsoletes"), + + /** + * The obsoletion policy is that any label on an obsolete node MUST be prefixed with 'obsolete' or similar + */ + OBSOLETELABELSAREPREFIXED("ObsoleteLabelsArePrefixed"); + + private final static Map MAP; + + static { + Map map = new HashMap(); + for ( ObsoletionPolicyEnum value : ObsoletionPolicyEnum.values() ) { + map.put(value.toString(), value); + } + + MAP = Collections.unmodifiableMap(map); + } + + private final String repr; + + ObsoletionPolicyEnum(String repr) { + this.repr = repr; + } + + @Override + public String toString() { + return repr; + } + + @JsonCreator + public static ObsoletionPolicyEnum fromString(String v) { + return MAP.get(v); + } + +} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/OntologyElement.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/OntologyElement.java index 97f4ae6..c025716 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/OntologyElement.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/OntologyElement.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * Any component of an ontology or knowledge graph */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/OntologySubset.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/OntologySubset.java index c75a95c..e639218 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/OntologySubset.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/OntologySubset.java @@ -1,12 +1,21 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * None */ @Data -@EqualsAndHashCode(callSuper=false) -public class OntologySubset extends Node {} +@EqualsAndHashCode(callSuper=true) +public class OntologySubset extends Node {} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/OwlType.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/OwlType.java new file mode 100644 index 0000000..9bd0307 --- /dev/null +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/OwlType.java @@ -0,0 +1,46 @@ +package org.incenp.obofoundry.kgcl.model; + +import java.util.Map; +import java.util.HashMap; +import java.util.Collections; + +import com.fasterxml.jackson.annotation.JsonCreator; + +public enum OwlType { + + CLASS("CLASS"), + + OBJECT_PROPERTY("OBJECT_PROPERTY"), + + NAMED_INDIVIDUAL("NAMED_INDIVIDUAL"), + + ANNOTATION_PROPERTY("ANNOTATION_PROPERTY"); + + private final static Map MAP; + + static { + Map map = new HashMap(); + for ( OwlType value : OwlType.values() ) { + map.put(value.toString(), value); + } + + MAP = Collections.unmodifiableMap(map); + } + + private final String repr; + + OwlType(String repr) { + this.repr = repr; + } + + @Override + public String toString() { + return repr; + } + + @JsonCreator + public static OwlType fromString(String v) { + return MAP.get(v); + } + +} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/PlaceUnder.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/PlaceUnder.java index 872be8f..bd46d3f 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/PlaceUnder.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/PlaceUnder.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * An edge creation where the predicate is owl:subClassOf */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/PredicateChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/PredicateChange.java index 0795566..6387445 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/PredicateChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/PredicateChange.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * An edge change where the predicate (relationship type) is modified. */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/PropertyValue.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/PropertyValue.java index 8ae782f..56b2cf2 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/PropertyValue.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/PropertyValue.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * a property-value pair */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ProvElement.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ProvElement.java index c226594..f12983c 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ProvElement.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/ProvElement.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A grouping for prov elements */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveFromSubset.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveFromSubset.java deleted file mode 100644 index 3b83425..0000000 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveFromSubset.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.incenp.obofoundry.kgcl.model; - -import java.util.List; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * removing an element from a subset - */ -@Data -@EqualsAndHashCode(callSuper=true) -public class RemoveFromSubset extends SubsetMembershipChange {} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveMapping.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveMapping.java index 55fd5e3..4593b68 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveMapping.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveMapping.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node mapping change where a mapping is deleted */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveMetadataAssertion.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveMetadataAssertion.java index 1ca5dc2..792a33b 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveMetadataAssertion.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveMetadataAssertion.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node metadata assertion change where a metadata assertion is deleted */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveNodeFromSubset.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveNodeFromSubset.java index abb337b..7adaca9 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveNodeFromSubset.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveNodeFromSubset.java @@ -1,16 +1,27 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * Removes a node from a subset, by removing an annotation */ @Data @EqualsAndHashCode(callSuper=true) public class RemoveNodeFromSubset extends NodeChange { + @SlotName("in_subset") private OntologySubset inSubset; + private OntologyElement about; public T accept(IChangeVisitor v) { return v.visit(this); } diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveSynonym.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveSynonym.java index 172d061..35f69f2 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveSynonym.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveSynonym.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node synonym change where a synonym is deleted */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveTextDefinition.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveTextDefinition.java index c977d15..3c594c3 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveTextDefinition.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveTextDefinition.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node change where a text definition is deleted */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveUnder.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveUnder.java index 4d42f15..20f95c0 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveUnder.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/RemoveUnder.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * An edge deletion where the predicate is owl:subClassOf diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Session.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Session.java index 0798b79..99b93b2 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Session.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Session.java @@ -1,14 +1,26 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A session consists of a set of change sets bundled with the activities that generated those change sets */ @Data @EqualsAndHashCode(callSuper=false) public class Session extends ChangeLanguageElement { + @SlotName("change_set") + @Inlined(asList = true) private List changeSet; + @SlotName("activity_set") private List activitySet;} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SetLanguageForName.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SetLanguageForName.java index e1479d4..1a3313b 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SetLanguageForName.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SetLanguageForName.java @@ -1,15 +1,25 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node change where the string value for the name is unchanged but the language tag is set */ @Data @EqualsAndHashCode(callSuper=true) public class SetLanguageForName extends NodeChange { + private OntologyElement about; public T accept(IChangeVisitor v) { return v.visit(this); } diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SimpleChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SimpleChange.java index 3444991..045452d 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SimpleChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SimpleChange.java @@ -1,22 +1,41 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; +import org.incenp.obofoundry.kgcl.SimpleChangeConverter; + /** * A change that is about a single ontology element */ @Data @EqualsAndHashCode(callSuper=true) +@Converter(SimpleChangeConverter.class) public class SimpleChange extends Change { + @SlotName("old_value") private String oldValue; + @SlotName("new_value") private String newValue; + @SlotName("old_value_type") private String oldValueType; + @SlotName("new_value_type") private String newValueType; + @SlotName("new_language") private String newLanguage; + @SlotName("old_language") private String oldLanguage; + @SlotName("new_datatype") private String newDatatype; + @SlotName("old_datatype") private String oldDatatype; public T accept(IChangeVisitor v) { return v.visit(this); diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SubsetMembershipChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SubsetMembershipChange.java deleted file mode 100644 index 1982a48..0000000 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SubsetMembershipChange.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.incenp.obofoundry.kgcl.model; - -import java.util.List; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * A change in the membership status of a node with respect to a subset (view) - */ -@Data -@EqualsAndHashCode(callSuper=false) -public class SubsetMembershipChange extends ChangeMixin { - private OntologySubset inSubset;} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SynonymPredicateChange.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SynonymPredicateChange.java index 0066787..f5a3bd3 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SynonymPredicateChange.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SynonymPredicateChange.java @@ -1,16 +1,27 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node synonym change where the predicate of a synonym is changed. Background: synonyms can be represented by a variety of predicates. For example, many OBO ontologies make use of predicates such as oio:hasExactSynonym, oio:hasRelatedSynonym, etc */ @Data @EqualsAndHashCode(callSuper=true) public class SynonymPredicateChange extends NodeSynonymChange { + @SlotName("has_textual_diff") private TextualDiff hasTextualDiff; + private String target; public T accept(IChangeVisitor v) { return v.visit(this); } diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SynonymReplacement.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SynonymReplacement.java index 7a189b5..89e9aa0 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SynonymReplacement.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SynonymReplacement.java @@ -1,15 +1,26 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node synonym change where the text of a synonym is changed */ @Data @EqualsAndHashCode(callSuper=true) public class SynonymReplacement extends NodeSynonymChange { + private String qualifier; + @SlotName("has_textual_diff") private TextualDiff hasTextualDiff; public T accept(IChangeVisitor v) { return v.visit(this); diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SynonymScopeEnum.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SynonymScopeEnum.java new file mode 100644 index 0000000..9a57479 --- /dev/null +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/SynonymScopeEnum.java @@ -0,0 +1,46 @@ +package org.incenp.obofoundry.kgcl.model; + +import java.util.Map; +import java.util.HashMap; +import java.util.Collections; + +import com.fasterxml.jackson.annotation.JsonCreator; + +public enum SynonymScopeEnum { + + RELATED("related"), + + BROAD("broad"), + + NARROW("narrow"), + + EXACT("exact"); + + private final static Map MAP; + + static { + Map map = new HashMap(); + for ( SynonymScopeEnum value : SynonymScopeEnum.values() ) { + map.put(value.toString(), value); + } + + MAP = Collections.unmodifiableMap(map); + } + + private final String repr; + + SynonymScopeEnum(String repr) { + this.repr = repr; + } + + @Override + public String toString() { + return repr; + } + + @JsonCreator + public static SynonymScopeEnum fromString(String v) { + return MAP.get(v); + } + +} \ No newline at end of file diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/TextDefinitionReplacement.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/TextDefinitionReplacement.java index a1215ae..8a76a64 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/TextDefinitionReplacement.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/TextDefinitionReplacement.java @@ -1,15 +1,25 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A node change where a text definition is modified */ @Data @EqualsAndHashCode(callSuper=true) public class TextDefinitionReplacement extends NodeTextDefinitionChange { + @SlotName("has_textual_diff") private TextualDiff hasTextualDiff; public T accept(IChangeVisitor v) { return v.visit(this); diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/TextualDiff.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/TextualDiff.java index e21d877..44237fc 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/TextualDiff.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/TextualDiff.java @@ -1,9 +1,18 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A summarizing of a change on a piece of text. This could be rendered in a number of different ways */ diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Transaction.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Transaction.java index 92675f6..4762e10 100644 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Transaction.java +++ b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Transaction.java @@ -1,15 +1,26 @@ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; + /** * A change that is a composition of a set of changes, where those changes are treated as a single unit. Could be a single change, or the results of an ontology diff */ @Data @EqualsAndHashCode(callSuper=true) public class Transaction extends Change { + @SlotName("change_set") + @Inlined(asList = true) private List changeSet; public T accept(IChangeVisitor v) { return v.visit(this); diff --git a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Unobsoletion.java b/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Unobsoletion.java deleted file mode 100644 index fb3bedf..0000000 --- a/core/src/main/lombok/org/incenp/obofoundry/kgcl/model/Unobsoletion.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.incenp.obofoundry.kgcl.model; - -import java.util.List; -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * Opposite operation of obsoletion. Rarely performed. - */ -@Data -@EqualsAndHashCode(callSuper=false) -public class Unobsoletion extends ChangeMixin {} \ No newline at end of file diff --git a/core/src/test/java/org/incenp/obofoundry/kgcl/KGCLReaderTest.java b/core/src/test/java/org/incenp/obofoundry/kgcl/KGCLReaderTest.java index ba1baad..957052c 100644 --- a/core/src/test/java/org/incenp/obofoundry/kgcl/KGCLReaderTest.java +++ b/core/src/test/java/org/incenp/obofoundry/kgcl/KGCLReaderTest.java @@ -473,7 +473,7 @@ void testNewObjectPropertyChange() { void testNewIndividualChange() { NodeCreation change = new NodeCreation(); change.setAboutNode(util.getNode("0001")); - change.getAboutNode().setOwlType(OwlType.NAMED_INVIDIDUAL); + change.getAboutNode().setOwlType(OwlType.NAMED_INDIVIDUAL); change.setNewValue("new label"); testParse("create instance EX:0001 'new label'", change); diff --git a/core/src/test/java/org/incenp/obofoundry/kgcl/KGCLTextTranslatorTest.java b/core/src/test/java/org/incenp/obofoundry/kgcl/KGCLTextTranslatorTest.java index 2fb3cad..8064e38 100644 --- a/core/src/test/java/org/incenp/obofoundry/kgcl/KGCLTextTranslatorTest.java +++ b/core/src/test/java/org/incenp/obofoundry/kgcl/KGCLTextTranslatorTest.java @@ -207,7 +207,7 @@ void testRenderObjectPropertyCreation() { void testRenderIndividualCreation() { NodeCreation change = new NodeCreation(); change.setAboutNode(defaultNode); - change.getAboutNode().setOwlType(OwlType.NAMED_INVIDIDUAL); + change.getAboutNode().setOwlType(OwlType.NAMED_INDIVIDUAL); change.setNewValue("new label"); render(change, "create instance EX:0001 \"new label\""); diff --git a/core/src/test/java/org/incenp/obofoundry/kgcl/YAMLReaderTest.java b/core/src/test/java/org/incenp/obofoundry/kgcl/YAMLReaderTest.java new file mode 100644 index 0000000..899f2da --- /dev/null +++ b/core/src/test/java/org/incenp/obofoundry/kgcl/YAMLReaderTest.java @@ -0,0 +1,89 @@ +/* + * KGCL-Java - KGCL library for Java + * Copyright © 2026 Damien Goutte-Gattat + * + * 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 . + */ + +package org.incenp.obofoundry.kgcl; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.incenp.obofoundry.kgcl.model.AddNodeToSubset; +import org.incenp.obofoundry.kgcl.model.Change; +import org.incenp.obofoundry.kgcl.model.EdgeCreation; +import org.incenp.obofoundry.kgcl.model.NewSynonym; +import org.incenp.obofoundry.kgcl.model.NodeObsoletionWithDirectReplacement; +import org.incenp.obofoundry.kgcl.model.NodeRename; +import org.incenp.obofoundry.kgcl.model.PredicateChange; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class YAMLReaderTest { + + @Test + void testReadingYAMLFile() throws IOException { + Map prefixMap = new HashMap<>(); + prefixMap.put("CHANGE:", "https://example.org/"); + prefixMap.put("GO:", "http://purl.obolibrary.org/obo/GO_"); + prefixMap.put("BFO:", "http://purl.obolibrary.org/obo/BFO_"); + prefixMap.put("rdfs:", "http://www.w3.org/2000/01/rdf-schema#"); + List changeset = KGCLHelper.parseYAML(new File("src/test/resources/samples.yaml"), prefixMap); + + Assertions.assertEquals(19, changeset.size()); + + Assertions.assertEquals("https://example.org/000", changeset.get(0).getId()); + Assertions.assertInstanceOf(NodeRename.class, changeset.get(0)); + Assertions.assertEquals("nuclear envelope", ((NodeRename) changeset.get(0)).getOldValue()); + Assertions.assertEquals("foo bar", ((NodeRename) changeset.get(0)).getNewValue()); + Assertions.assertEquals("http://purl.obolibrary.org/obo/GO_0005635", + ((NodeRename) changeset.get(0)).getAboutNode().getId()); + + Assertions.assertInstanceOf(NodeObsoletionWithDirectReplacement.class, changeset.get(2)); + Assertions.assertEquals("http://purl.obolibrary.org/obo/GO_0005634", + ((NodeObsoletionWithDirectReplacement) changeset.get(2)).getAboutNode().getId()); + Assertions.assertEquals("http://purl.obolibrary.org/obo/GO_999", + ((NodeObsoletionWithDirectReplacement) changeset.get(2)).getHasDirectReplacement().getId()); + + Assertions.assertInstanceOf(NewSynonym.class, changeset.get(3)); + Assertions.assertEquals("exact", ((NewSynonym) changeset.get(3)).getQualifier()); + + Assertions.assertInstanceOf(AddNodeToSubset.class, changeset.get(6)); + Assertions.assertEquals("foo", ((AddNodeToSubset) changeset.get(6)).getInSubset().getId()); + + Assertions.assertInstanceOf(EdgeCreation.class, changeset.get(10)); + Assertions.assertEquals("http://purl.obolibrary.org/obo/GO_0005634", + ((EdgeCreation) changeset.get(10)).getSubject().getId()); + Assertions.assertEquals("http://purl.obolibrary.org/obo/BFO_0000050", + ((EdgeCreation) changeset.get(10)).getPredicate().getId()); + Assertions.assertEquals("http://purl.obolibrary.org/obo/GO_0009411", + ((EdgeCreation) changeset.get(10)).getObject().getId()); + + Assertions.assertInstanceOf(PredicateChange.class, changeset.get(12)); + Assertions.assertEquals("http://purl.obolibrary.org/obo/BFO_0000050", + ((PredicateChange) changeset.get(12)).getOldValue()); + Assertions.assertEquals("http://www.w3.org/2000/01/rdf-schema#subClassOf", + ((PredicateChange) changeset.get(12)).getNewValue()); + Assertions.assertEquals("http://purl.obolibrary.org/obo/GO_0005635", + ((PredicateChange) changeset.get(12)).getAboutEdge().getSubject().getId()); + Assertions.assertEquals("http://purl.obolibrary.org/obo/BFO_0000050", + ((PredicateChange) changeset.get(12)).getAboutEdge().getPredicate().getId()); + Assertions.assertEquals("http://purl.obolibrary.org/obo/GO_0005634", + ((PredicateChange) changeset.get(12)).getAboutEdge().getObject().getId()); + } +} diff --git a/core/src/test/resources/samples.yaml b/core/src/test/resources/samples.yaml new file mode 100644 index 0000000..9a87485 --- /dev/null +++ b/core/src/test/resources/samples.yaml @@ -0,0 +1,109 @@ +- id: CHANGE:000 + type: NodeRename + old_value: nuclear envelope + new_value: foo bar + about_node: GO:0005635 + +- id: CHANGE:001 + type: NodeObsoletion + about_node: GO:0005634 + +- id: CHANGE:002 + type: NodeObsoletionWithDirectReplacement + about_node: GO:0005634 + has_direct_replacement: GO:999 + +- id: CHANGE:003 + type: NewSynonym + new_value: foo + about_node: GO:0005634 + qualifier: exact + +- id: CHANGE:004 + type: RemoveSynonym + old_value: foo + about_node: GO:0005634 + +- id: CHANGE:005 + type: SynonymReplacement + old_value: cell nucleus + new_value: cell NUCLEUS + about_node: GO:0005634 + +- id: CHANGE:006 + type: AddNodeToSubset + about_node: GO:0005634 + in_subset: foo + +- id: CHANGE:007 + type: RemoveNodeFromSubset + about_node: GO:0005634 + in_subset: foo + +- id: CHANGE:008 + type: ClassCreation + about_node: GO:9999999 + +- id: CHANGE:009 + type: NodeCreation + about_node: GO:9999999 + name: foo + +- id: CHANGE:010 + type: EdgeCreation + subject: GO:0005634 + predicate: BFO:0000050 + object: GO:0009411 + +- id: CHANGE:011 + type: PlaceUnder + subject: GO:0005634 + predicate: rdfs:subClassOf + object: GO:0009411 + +- id: CHANGE:012 + type: PredicateChange + old_value: BFO:0000050 + old_value_type: curie + new_value: rdfs:subClassOf + new_value_type: curie + about_edge: + subject: GO:0005635 + predicate: BFO:0000050 + object: GO:0005634 + +- id: CHANGE:013 + type: RemoveUnder + subject: GO:0005634 + predicate: rdfs:subClassOf + object: GO:0043231 + +- id: CHANGE:014 + type: EdgeDeletion + subject: GO:0005635 + predicate: BFO:0000050 + object: GO:0005634 + +- id: CHANGE:015 + type: NodeDeepening + old_value: GO:0043231 + old_value_type: curie + new_value: GO:0005634 + new_value_type: curie + about_edge: + subject: GO:0005739 + object: GO:0043231 + +- id: CHANGE:016 + type: NewTextDefinition + new_value: this is dummy description + about_node: GO:0005635 + +- id: CHANGE:017 + type: NodeTextDefinitionChange + new_value: this is dummy description + about_node: GO:0005635 + +- id: CHANGE:018 + type: RemoveTextDefinition + about_node: GO:0005634 diff --git a/linkml/basics.yaml b/linkml/basics.yaml new file mode 100644 index 0000000..2f94c09 --- /dev/null +++ b/linkml/basics.yaml @@ -0,0 +1,25 @@ +id: https://w3id.org/kgcl/basics +name: basics +title: basic predicates +description: Core predicates +license: https://creativecommons.org/publicdomain/zero/1.0/ +prefixes: + basics: https://w3id.org/kgcl/basics/ + linkml: https://w3id.org/linkml/ +default_prefix: basics +default_range: string +default_curi_maps: +- semweb_context +imports: +- linkml:types +types: + LanguageTag: + base: str + uri: xml:lang +slots: + id: + identifier: true + range: uriorcurie + description: + slot_uri: dcterms:description + diff --git a/linkml/custom-javagen.py b/linkml/custom-javagen.py index f7571bb..8d10d90 100644 --- a/linkml/custom-javagen.py +++ b/linkml/custom-javagen.py @@ -9,19 +9,52 @@ class_template = """\ package org.incenp.obofoundry.kgcl.model; +import java.time.ZonedDateTime; import java.util.List; + import lombok.Data; import lombok.EqualsAndHashCode; +import org.incenp.linkml.core.annotations.Converter; +import org.incenp.linkml.core.annotations.Identifier; +import org.incenp.linkml.core.annotations.Inlined; +import org.incenp.linkml.core.annotations.SlotName; +import org.incenp.linkml.core.annotations.TypeDesignator; +import org.incenp.linkml.core.CurieConverter; +{%- if cls.name == "SimpleChange" %} +import org.incenp.obofoundry.kgcl.SimpleChangeConverter; +{%- endif %} + /** * {{ cls.description|e }} */ @Data @EqualsAndHashCode(callSuper={% if gen.parent_has_slots(cls) %}true{% else %}false{% endif %}) +{%- if cls.name == "SimpleChange" %} +@Converter(SimpleChangeConverter.class) +{%- endif %} public class {{ cls.name }} {% if cls.is_a -%} extends {{ cls.is_a }} {%- endif %} { {%- for f in cls.fields %} - private {% if f.source_slot.range == 'owl_type' %}OwlType - {%- else %}{{ f.range }}{% endif %} {{ f.name }}; + {%- if f.source_slot.identifier %} + @Identifier + {%- endif %} + {%- if f.source_slot.designates_type %} + @TypeDesignator + {%- endif %} + {%- if f.source_slot.name != f.name %} + @SlotName("{{ f.source_slot.name }}") + {%- endif %} + {%- if f.source_slot.inlined %} + {%- if f.source_slot.inlined_as_list %} + @Inlined(asList = true) + {%- else %} + @Inlining + {%- endif %} + {%- endif %} + {%- if f.source_slot.range == "uriorcurie" %} + @Converter(CurieConverter.class) + {%- endif %} + private {{ f.range }} {{ f.name }}; {%- endfor -%} {% if cls.name == "Change" or gen.has_ancestor(cls, "Change") %} @@ -67,8 +100,15 @@ def serialize(self, directory, extras=[]): template_obj = Template(class_template) oodocs = self.create_documents() for oodoc in oodocs: - cls = oodoc.classes[0] - code = template_obj.render(doc=oodoc, cls=cls, gen=self) + if oodoc.classes: + cls = oodoc.classes[0] + if cls.mixin: + continue + code = template_obj.render(doc=oodoc, cls=cls, gen=self) + else: + # Use default enum template + enum_templ = self.template_cache.get_template(oodoc.name, "enum") + code = enum_templ.render(doc=oodoc, enum=oodoc.enums[0], gen=self) path = os.path.join(directory, f"{oodoc.name}.java") with open(path, "w", encoding="UTF-8") as stream: @@ -123,12 +163,15 @@ def get_descendants(self, name, _descendants=[]): return _descendants -@click.argument("yamlfile", type=click.Path(exists=True, dir_okay=False)) @click.option("--output-directory", default="output", show_default=True) @click.command() -def cli(yamlfile, output_directory=None): - gen = CustomJavaGenerator(yamlfile) - gen.serialize(output_directory, [("IChangeVisitor.java", visitor_template)]) +def cli(output_directory=None): + for schema in ["basics", "ontology_model", "prov", "kgcl"]: + gen = CustomJavaGenerator(schema + ".yaml", true_enums=True, package="org.incenp.obofoundry.kgcl.model") + extra_templates = [] + if schema == "kgcl": + extra_templates.append(("IChangeVisitor.java", visitor_template)) + gen.serialize(output_directory, extra_templates) if __name__ == "__main__": cli() diff --git a/linkml/kgcl.yaml b/linkml/kgcl.yaml new file mode 100644 index 0000000..3ed3f42 --- /dev/null +++ b/linkml/kgcl.yaml @@ -0,0 +1,975 @@ +id: https://w3id.org/kgcl +name: kgcl_schema +title: Knowledge Graph Change Language +description: 'A data model for describing change operations at a high level on an + ontology or ontology-like artefact, such as a Knowledge Graph. + + * [Browse Schema](https://cmungall.github.io/knowledge-graph-change-language/) + + * [GitHub](https://github.com/cmungall/knowledge-graph-change-language)' +license: https://creativecommons.org/publicdomain/zero/1.0/ +version: 0.0.1 +prefixes: + kgcl: http://w3id.org/kgcl/ + dcterms: http://purl.org/dc/terms/ + IAO: http://purl.obolibrary.org/obo/IAO_ + oio: http://www.geneontology.org/formats/oboInOwl# + xml: http://www.w3.org/XML/1998/namespace# + linkml: https://w3id.org/linkml/ + rdfs: http://www.w3.org/2000/01/rdf-schema# +default_prefix: kgcl +default_range: string +imports: +- linkml:types +- ontology_model +- prov +types: + ChangeClassType: + typeof: uriorcurie + description: CURIE for a class within this data model. E.g. kgcl:NodeObsoletion +classes: + ChangeLanguageElement: + abstract: true + description: A broad grouping for all elements of the change language + Change: + abstract: true + is_a: ChangeLanguageElement + description: Any change perform on an ontology or knowledge graph + slots: + - id + - type + - was_generated_by + - see_also + - pull_request + - term_tracker_issue + - creator + - change_date + - contributor + - has_undo + - change_description + - associated_change_set + slot_usage: + was_generated_by: + comments: + - we use the PROV model to represent the agent making a change + see_also: + comments: + - If this change is in relationship to an issue on a system like github, include + the URL here + pull_request: + comments: + - If this change has a pull request on a system like github, include the URL + here + term_tracker_issue: + comments: + - If this change has an issue on a system like github, include the URL + here + creator: + slot_uri: dcterms:creator + comments: + - This should be the composition of 'was generated by' and 'was associated with' + change_date: + comments: + - This should be the composition of 'was generated by' and 'ended at time' + SimpleChange: + abstract: true + aliases: + - atomic change + is_a: Change + description: A change that is about a single ontology element + slots: + - old_value + - new_value + - old_value_type + - new_value_type + - new_language + - old_language + - new_datatype + - old_datatype + ComplexChange: + abstract: true + is_a: Change + description: A change that is is a composition of other changes + slots: + - change_set + MultiNodeObsoletion: + aliases: + - multi node deprecation + - multi class obsoletion + - multi term obsoletion + - multi concept obsoletion + is_a: ComplexChange + description: A complex change consisting of multiple obsoletions. + see_also: + - https://github.com/cmungall/obo-scripts/blob/master/obo-obsoletify.pl + slot_usage: + change_set: + range: NodeObsoletion + change_description: + string_serialization: obsolete multiple {change set} + associated_change_set: + description: >- + All changes associated with a set of obsoletions. This change + set is the composed change set rather than the set of individual changes. + For example, if previous state is:\n `A subClassOf B subClassOf C subClassOf + D` and we obsolete {B,C}, then the individual changes are `A moves from + B to C` and `B moves from C to D`, but the composed change set is `A moves + from B to D`" + + Transaction: + is_a: Change + description: A change that is a composition of a set of changes, where those changes + are treated as a single unit. Could be a single change, or the results of an + ontology diff + slots: + - change_set + ChangeSetSummaryStatistic: + is_a: ChangeLanguageElement + description: A summary statistic for a set of changes of the same type, grouped + by zero or more node properties + slot_usage: + #change type: + # range: ChangeClassType + #count: + # range: integer + #property_value_set: + # description: Summary statistic is grouped by these constraints + ChangeMixin: + mixin: true + description: root class for all change mixins + slots: + - about + - has_undo + - old_value + - new_value + Obsoletion: + aliases: + - deprecation + - retiring + is_a: ChangeMixin + mixin: true + description: Obsoletion of an element deprecates usage of that element, but does + not delete that element. + comments: + - In OWL, deprecation is handled by the deprecation axiom. In OBO, we use this, + but place additional requirements and expectations on obsolete elements + see_also: + - http://wiki.geneontology.org/index.php/Obsoleting_an_Existing_Ontology_Term + - https://mondo.readthedocs.io/en/latest/editors-guide/merging-and-obsoleting/ + slot_usage: + about: + description: The element that is obsoleted by this change. + has_undo: + range: Obsoletion + DatatypeOrLanguageTagChange: + is_a: ChangeMixin + mixin: true + description: A change in a value assertion where the value remain unchanged but + either the datatype or language changes + LanguageTagChange: + is_a: DatatypeOrLanguageTagChange + mixin: true + slot_usage: + old_value: + multivalued: false + range: LanguageTag + new_value: + multivalued: false + range: LanguageTag + DatatypeChange: + is_a: DatatypeOrLanguageTagChange + mixin: true + AllowsAutomaticReplacementOfEdges: + is_a: Obsoletion + mixin: true + description: Applies to an obsoletion in which annotations or edges pointing at + the obsoleted node can be automatically rewired to point to a target + Unobsoletion: + is_a: ChangeMixin + mixin: true + description: Opposite operation of obsoletion. Rarely performed. + see_also: + - http://wiki.geneontology.org/index.php/Restoring_an_Obsolete_Ontology_Term + slot_usage: + has_undo: + range: Obsoletion + Deletion: + is_a: ChangeMixin + mixin: true + description: Removal of an element. + comments: + - In general, for OBO ontologies, node elements should never be deleted, always + obsolete. However, edge deletion is more common. + Creation: + is_a: ChangeMixin + mixin: true + description: Creation of an element. + slot_usage: + has_undo: + range: Deletion + SubsetMembershipChange: + is_a: ChangeMixin + mixin: true + description: A change in the membership status of a node with respect to a subset + (view) + slots: + - in_subset + AddToSubset: + is_a: SubsetMembershipChange + mixin: true + description: placing an element inside a subset + slot_usage: + in_subset: + description: subset that the element is being placed inside. + RemoveFromSubset: + is_a: SubsetMembershipChange + mixin: true + description: removing an element from a subset + slot_usage: + in_subset: + description: subset that the element is being removed from + has_undo: + range: AddToSubset + EdgeChange: + abstract: true + aliases: + - axiom change + - triple change + is_a: SimpleChange + description: A change in which the element that is the focus of the change is + an edge. + slots: + - about_edge + - object_type + - language + - datatype + slot_usage: + about_edge: + comments: + - if subject is empty, use the about field of the last node change + todos: + - decide on flat serialization, see https://github.com/cmungall/knowledge-graph-change-language/issues/7 + EdgeCreation: + aliases: + - relationship creation + is_a: EdgeChange + description: An edge change in which a de-novo edge is created. The edge is potentially + annotated in the same action. + mixins: + - Creation + slots: + - subject + - predicate + - object + - subject_type + - predicate_type + - object_type + - annotation_set + slot_usage: + change_description: + string_serialization: create edge {edge.subject} {edge.predicate} {edge.object} + see_also: + - http://wiki.geneontology.org/index.php/Guidelines_for_creating_relationships_between_terms + PlaceUnder: + is_a: EdgeCreation + description: An edge creation where the predicate is owl:subClassOf + EdgeDeletion: + aliases: + - relationship deletion + is_a: EdgeChange + description: An edge change in which an edge is removed. All edge annotations/properies + are removed in the same action. + mixins: + - Deletion + slots: + - subject + - predicate + - object + - subject_type + - predicate_type + - object_type + - annotation_set + slot_usage: + change_description: + string_serialization: delete edge {edge.subject} {edge.predicate} {edge.object} + RemoveUnder: + is_a: EdgeDeletion + description: "An edge deletion where the predicate is owl:subClassOf\n " + EdgeObsoletion: + aliases: + - relationship obsoletion + is_a: EdgeChange + description: An edge change in which an edge is obsoleted. + comments: + - Note there is not yet consensus in how this should be done in rdf/owl implementations. + Simply marking the edge deprecated with render it visible to most clients. Care + must be taken because simply adding a deprecation tag to an axiom does not silence + it -- it is still asserted. It is therefore more common to obsolete an edge + by shadowing the axiom as an annotation. See the Mondo docs for example + see_also: + - https://mondo.readthedocs.io/en/latest/editors-guide/g-logical-axioms/#excluded-subclassof + mixins: + - Obsoletion + slots: + - subject + - predicate + - object + - annotation_set + slot_usage: + change_description: + string_serialization: obsolete edge {edge.subject} {edge.predicate} {edge.object} + EdgeRewiring: + is_a: EdgeChange + description: An edge change where one node is replaced with another, as in the + case of obsoletion with replacement + examples: + - value: changing G1 annotated-to T1 to G1 annotated-to T2, after obsoletion of + T1 and replacement with T2 + MappingCreation: + deprecated: use NewMapping + aliases: + - xref creation + is_a: EdgeCreation + description: A specific kind of edge creation in which the created edge is a mapping. + mixins: + - Creation + slots: + - subject + - predicate + - object + - annotation_set + slot_usage: + change_description: + string_serialization: create mapping {subject} {predicate} {object} + subject: + description: This corresponds to subject_id in SSSOM + predicate: + description: This corresponds to predicate_id in SSSOM. The value of this + is typically a predicate from SKOS + object: + description: This corresponds to object_id in SSSOM + todos: + - decide whether to make a corresponding change to the datamodel + NodeMove: + is_a: EdgeChange + description: A node move is a combination of deleting a parent edge and adding + a parent edge, where the predicate is preserved and the object/parent node changes + slots: + - old_object_type + - new_object_type + examples: + - value: changing a is-a b to a is-a c + slot_usage: + change_description: + string_serialization: move {about_edge.subject} {about_edge.predicate} {about_edge.object} from {old_value} to {new_value} + NodeDeepening: + is_a: NodeMove + description: A node move in which a node where the destination is a proper descendant + of the original location. Note that here descendant applied not just to subclass, + but edges of any predicate in the relational graph + examples: + - value: changing a is-a b to a is-a c, where c is a subclass of b + slot_usage: + change_description: + string_serialization: deepen {about_edge.subject} {about_edge.predicate} {about_edge.object} from {old_value} to {new_value} + NodeShallowing: + is_a: NodeMove + description: The opposite of node deepening + examples: + - value: changing a is-a c to a is-a b, where c is a subclass of b + slot_usage: + change_description: + string_serialization: lift {about_node} from {old_value} to {new_value} + PredicateChange: + is_a: EdgeChange + description: An edge change where the predicate (relationship type) is modified. + examples: + - value: changing a is-a b to a part-of b + slot_usage: + change_description: + string_serialization: change edge type between {about.subject} and {about.object} + from {old_value} to {new_value} + EdgeLogicalInterpretationChange: + is_a: EdgeChange + description: An edge change where the subject, object, and predicate are unchanged, + but the logical interpretation changes + examples: + - value: changing a SubClassOf r some b to a subClassOf r only b + LogicalAxiomChange: + is_a: SimpleChange + description: A simple change where a logical axiom is changed, where the logical + axiom cannot be represented as an edge + NodeChange: + abstract: true + is_a: SimpleChange + description: A simple change where the change is about a node + slots: + - about_node + - about_node_representation + - language + NodeRename: + is_a: NodeChange + description: A node change where the name (aka rdfs:label) of the node changes + slots: + - old_value + - new_value + - has_textual_diff + - new_language + - old_language + slot_usage: + old_value: + multivalued: false + new_value: + multivalued: false + change_description: + string_serialization: rename {about_node} from {old_value} to {new_value} + examples: + - value: rename UBERON:0002398 from 'manus' to 'hand' + description: replacing the rdfs:label of 'manus' on an uberon class with the + rdfs:label 'hand' + SetLanguageForName: + is_a: NodeChange + mixins: + - LanguageTagChange + description: A node change where the string value for the name is unchanged but + the language tag is set + slots: + - old_value + - new_value + slot_usage: + change_description: + string_serialization: changed {about_node} name language from {old_value} + to {new_value} + NodeAnnotationChange: + description: A node change where the change alters node properties/annotations. + TODO + is_a: NodeChange + slots: + - annotation_property + - annotation_property_type + NodeAnnotationReplacement: + is_a: NodeAnnotationChange + description: A node annotation change where the change replaces a particular property + value. TODO + NodeSynonymChange: + is_a: NodeChange + NewSynonym: + description: A node synonym change where a de-novo synonym is created + is_a: NodeSynonymChange + slots: + - new_value + - language + - qualifier + - predicate + aliases: + - new alias + - create synonym + - add synonym + NameBecomesSynonym: + is_a: NodeSynonymChange + description: A node synonym where the name NAME of an node NODE moves to a synonym, + and NODE receives a new name. This change consists of compose of (1) a node + rename where NAME is replaced by a different name (2) a new synonym + slot_usage: + #change_1: + # range: NodeRename + #change 2: + # range: NewSynonym + # description: '' + change_description: + string_serialization: synonym {synonym} becomes new name of {about_node}, + and name {name} becomes a synonym + RemoveSynonym: + description: A node synonym change where a synonym is deleted + is_a: NodeSynonymChange + slots: + - old_value + SynonymReplacement: + description: A node synonym change where the text of a synonym is changed + is_a: NodeSynonymChange + slots: + - old_value + - new_value + - qualifier + - has_textual_diff + SynonymPredicateChange: + aliases: + - node scope change + description: 'A node synonym change where the predicate of a synonym is changed. + Background: synonyms can be represented by a variety of predicates. For example, + many OBO ontologies make use of predicates such as oio:hasExactSynonym, oio:hasRelatedSynonym, + etc' + is_a: NodeSynonymChange + slots: + - old_value + - new_value + - has_textual_diff + - target + NodeMappingChange: + description: A node change where the mappings for that node are altered + is_a: NodeChange + aliases: + - xref change + NewMapping: + description: A node mapping change where a mapping is added to a node + is_a: NodeMappingChange + slots: + - object + - predicate + aliases: + - xref change + RemoveMapping: + description: A node mapping change where a mapping is deleted + is_a: NodeMappingChange + slots: + - object + - predicate + MappingReplacement: + description: A node mapping change where the object of a mapping is changed + is_a: NodeMappingChange + slots: + - old_value + - new_value + MappingPredicateChange: + aliases: + - node scope change + description: A node mapping change where the predicate of a mapping is changed. + is_a: NodeMappingChange + slots: + - old_value + - new_value + NodeMetadataAssertionChange: + description: A node change where the metadata assertion (OWL annotations) for + that node are altered + is_a: NodeChange + aliases: + - NodeAnnotationChange + NewMetadataAssertion: + description: A node metadata assertion change where a metadata assertion is added + to a node + is_a: NodeMetadataAssertionChange + slots: + - object + - predicate + aliases: + - xref change + RemoveMetadataAssertion: + description: A node metadata assertion change where a metadata assertion is deleted + is_a: NodeMetadataAssertionChange + slots: + - object + - predicate + MetadataAssertionReplacement: + description: A node metadata assertion change where the object of a metadata assertion + is changed + is_a: NodeMetadataAssertionChange + slots: + - old_value + - new_value + MetadataAssertionPredicateChange: + aliases: + - node scope change + description: A node metadata assertion change where the predicate of a metadata + assertion is changed. + is_a: NodeMetadataAssertionChange + slots: + - old_value + - new_value + NodeTextDefinitionChange: + abstract: true + is_a: NodeChange + description: A node change where the text definition is changed + NewTextDefinition: + description: A node change where a de-novo text definition is created + is_a: NodeTextDefinitionChange + slots: + - new_value + RemoveTextDefinition: + description: A node change where a text definition is deleted + is_a: NodeTextDefinitionChange + slots: + - old_value + TextDefinitionReplacement: + description: A node change where a text definition is modified + is_a: NodeTextDefinitionChange + slots: + - old_value + - new_value + - has_textual_diff + AddNodeToSubset: + aliases: + - add term to slim + is_a: NodeChange + mixins: + - AddToSubset + description: Places a node inside a subset, by annotating that node + see_also: + - http://wiki.geneontology.org/index.php/Adding_a_Term_to_a_GO_Subset_(Slim) + RemoveNodeFromSubset: + aliases: + - remove term from slim + is_a: NodeChange + mixins: + - RemoveFromSubset + description: Removes a node from a subset, by removing an annotation + slot_usage: + change_description: + string_serialization: removing {about_node} from {subset} + about_node: + description: The node that is removed from the subset + in_subset: + description: The subset from which the node is to be removed + NodeObsoletion: + aliases: + - node deprecation + - class obsoletion + - term obsoletion + - concept obsoletion + is_a: NodeChange + mixins: + - Obsoletion + description: Obsoletion of a node deprecates usage of that node, but does not + delete it. + slots: + - has_direct_replacement + - has_nondirect_replacement + slot_usage: + change_description: + string_serialization: obsoleting {about_node} + associated_change_set: + is_a: change_set + description: 'All changes forced as a result of this obsoletion. For example, + starting with `A subClassOf B subClassOf C`, if we obsolete node B, then + we may decide to bundle in a node move change of A from B to C. Note: this + change set is not considered a part of the obsoletion, as obsoletion is + considered atomic/simple. Instead this is a reference to a change set that + may exist elsewhere' + see_also: + - http://wiki.geneontology.org/index.php/Obsoleting_an_Existing_Ontology_Term + NodeUnobsoletion: + aliases: + - node undeprecation + - class unobsoletion + - term unobsoletion + - concept unobsoletion + is_a: NodeChange + mixins: + - Unobsoletion + description: unobsoletion of a node deprecates usage of that node. Rarely applied. + slots: + - has_direct_replacement + - has_nondirect_replacement + slot_usage: + change_description: + string_serialization: unobsoleting {about_node} + see_also: + - http://wiki.geneontology.org/index.php/Restoring_an_Obsolete_Ontology_Term + NodeCreation: + is_a: NodeChange + mixins: + - Creation + description: a node change in which a new node is created + slots: + - node_id + - name + - owl_type + - annotation_set + - language + slot_usage: + change_description: + string_serialization: creating node {id} {label} with {annotation set} + todos: + - allow this for the creation of an instance from a class. This may include metaclasses + (templates) + see_also: + - http://wiki.geneontology.org/index.php/Guidelines_for_creating_a_GO_term + ClassCreation: + is_a: NodeCreation + description: A node creation where the owl type is 'owl:Class' + slots: + - superclass + slot_usage: + change_description: + string_serialization: create class {about_node} + ObjectPropertyCreation: + is_a: NodeCreation + description: A node creation where the owl type is 'ObjectProperty' + slot_usage: + change_description: + string_serialization: create object property {about_node} + NodeDeletion: + is_a: NodeChange + mixins: + - Deletion + description: Deletion of a node from the graph. Note it is recommended nodes are + obsoleted and never merged, but this operation exists to represent deletions + in ontologies, accidental or otherwise + slot_usage: + change_description: + string_serialization: delete {about_node} + NodeDirectMerge: + is_a: NodeObsoletion + mixins: + - AllowsAutomaticReplacementOfEdges + description: An obsoletion change in which all metadata (including name/label) + from the source node is deleted and added to the target node, and edges can + automatically be rewired to point to the target node + comments: + - In the OBO format serialization of the graph, the source node vanishes from + the file as a distinct entry and is retained only as an alt_id + slot_usage: + has_direct_replacement: + required: true + about_node: + aliases: + - alt_id + change_description: + string_serialization: merge {about_node} into {has_direct_replacement} + see_also: + - http://wiki.geneontology.org/index.php/Merging_Ontology_Terms + - http://wiki.geneontology.org/index.php/Principles_for_merging_terms + NodeObsoletionWithDirectReplacement: + is_a: NodeObsoletion + mixins: + - AllowsAutomaticReplacementOfEdges + description: An obsoletion change in which information from the obsoleted node + is selectively copied to a single target, and edges can automatically be rewired + to point to the target node + slot_usage: + has_direct_replacement: + required: true + change_description: + string_serialization: obsolete {about_node} with replacement {has_direct_replacement} + see_also: + - http://wiki.geneontology.org/index.php/Merging_Ontology_Terms + - http://wiki.geneontology.org/index.php/Principles_for_merging_terms + NodeObsoletionWithNoDirectReplacement: + is_a: NodeObsoletion + description: An obsoletion change in which there is no direct replacement + slot_usage: + has_nondirect_replacement: + required: true + change_description: + string_serialization: obsolete {about_node} with alternative {has_nondirect_replacement} + TextualDiff: + is_a: ChangeLanguageElement + description: A summarizing of a change on a piece of text. This could be rendered + in a number of different ways + Configuration: + is_a: ChangeLanguageElement + description: The meaning of operations can be configured + attributes: + name_predicate: null + definition_predicate: null + main_synonym_predicate: null + synonym_predicates: null + creator_predicate: null + contributor_predicate: null + obsolete_node_label_prefix: + range: string + description: A prefix to add to the label of an obsolete node. This may include + a space at the end. + obsoletion_workflow: null + obsoletion_policies: + multivalued: true + range: ObsoletionPolicyEnum + obsolete_subclass_of_shadow_property: + range: uriorcurie + description: >- + specifies the annotation property to be used to create a shadow annotation assertion triple when + a subclass edge is deleted. + Session: + is_a: ChangeLanguageElement + description: A session consists of a set of change sets bundled with the activities + that generated those change sets + tree_root: true + slots: + - change_set + - activity_set +slots: + type: + designates_type: true + slot_uri: rdf:type + pull_request: null + see_also: + slot_uri: rdfs:seeAlso + creator: + slot_uri: dcterms:creator + contributor: + slot_uri: dcterms:creator + change_date: + slot_uri: dcterms:date + range: datetime + term_tracker_issue: + exact_mappings: + - IAO:0000233 + has_undo: + domain: Change + description: A change that reverses this change + range: Change + multivalued: false + node_id: + description: id of a node to be created + todos: + - consider using 'about' instead + range: Node + superclass: + range: Node + language: + range: LanguageTag + description: The language tag of a literal + about: + description: The 'focus' entity on which the change operates + multivalued: false + range: OntologyElement + about_node: + is_a: about + multivalued: false + range: Node + about_edge: + is_a: about + multivalued: false + range: Edge + about_node_representation: + deprecated: no longer required + description: 'The representation of a node (URI, CURIE, label) ' + target: + description: The secondary entity on which the change operates + old_value: + description: The value of a property held in the old instance of the ontology + new_value: + description: The value of a property held in the new instance of the ontology + datatype: + description: The datatype of a literal + new_datatype: + description: The new datatype of a literal + old_datatype: + description: The old datatype of a literal + new_language: + description: The new language tag of a literal + old_language: + description: The old language tag of a literal + qualifier: + description: The qualifier of a change operation + subclass: + description: The subclass of a subsumption axiom + new_subclass: + description: The new subclass of a subsumption axiom + new_property: + description: The new property of an OWL restriction + new_filler: + description: The new filler of an OWL restriction + object_type: + deprecated: no longer required + description: The type (IRI or Literal) of an object + new_object_type: + deprecated: no longer required + description: The type (IRI or Literal) of a new object + old_object_type: + deprecated: no longer required + description: The type (IRI or Literal) of an old object + new_value_type: + deprecated: no longer required + description: The type (IRI or Literal) of a new value + old_value_type: + deprecated: no longer required + description: The type (IRI or Literal) of an old value + subject_type: + deprecated: no longer required + description: The type (IRI or Literal) of an edge's subject + subclass_type: + deprecated: no longer required + description: The type of a subclass + superclass_type: + deprecated: no longer required + description: The type of a superclass + predicate_type: + deprecated: no longer required + description: The type (IRI or Literal) of an edge's subject + in_subset: + description: The subset that pertains to this change + range: OntologySubset + annotation_property: + description: An annotation property + annotation_property_type: + deprecated: no longer required + description: 'The type of a property (URI, CURIE, label) ' + change_description: + description: A string serialization of the change. This should be both human-readable, + and parseable. + comments: + - Form 1: IRIs are denoted by CURIEs, optionally followed by label in parenthesis + - Form 2: IRIs are denoted by the rdfs:label in single quotes, e.g. 'nervous system' + examples: + - value: rename UBERON:0002398 from 'manus' to 'hand' + - value: move 'hand' from 'part of' 'hindlimb' to 'part of' 'forelimb' + - value: merge 'cellular metabolic process' into 'metabolic process' + - value: search and replace 'metabolic process' with 'metabolism' in all labels + under 'biological process' + - value: search and replace 'metabolic process' with 'metabolism' in all labels + under 'biological process' retaining as 'exact synonym' + has_textual_diff: + description: A representation of character-level changes on a textual literal + property. For example, if a text definition may change by only a single character + such as addition of a period, it is useful to be able to see this visually. + comments: + - this is NOT for representing the diff of the change as a whole. + domain: Change + range: TextualDiff + change_set: + description: A collection of changes + range: Change + multivalued: true + inlined: true + inlined_as_list: true + associated_change_set: + is_a: change_set + description: 'All changes forced as a result of this obsoletion. For example, + starting with `A subClassOf B subClassOf C`, if we obsolete node B, then + we may decide to bundle in a node move change of A from B to C. Note: this + change set is not considered a part of the obsoletion, as obsoletion is + considered atomic/simple. Instead this is a reference to a change set that + may exist elsewhere' + has_replacement: + domain: NodeObsoletion + range: Node + abstract: true + is_a: target + description: A single node obsoletion event may be accompanied by one or more + suggested replacement nodes + comments: + - In OBO, the replacement term is indicated using IAO:nnnnnn + has_direct_replacement: + range: Node + multivalued: false + close_mappings: + - IAO:0100001 + description: An obsoletion replacement where it IS valid to automatically update + annotations/edges pointing at the node with its direct replacement + comments: + - if a node obsoletion C, C about N1, and C has direct replacement N2, and there + exists an edge with an edge property referencing N1, it is possible to replace + with N2 + - if a node obsoletion C C about N1, and Chas direct replacement N2, then N1 IAO:0100001 + N2 + has_nondirect_replacement: + range: Node + multivalued: true + description: An obsoletion replacement where it is NOT valid to automatically + update annotations/edges pointing at the node with its direct replacement + close_mappings: + - oio:consider + comments: + - if a node obsoletion C, C about N1, and C has direct replacement N2, and there + exists an edge with an edge property referencing N1, it is possible to replace + with N2 + - if a node obsoletion C C about N1, and Chas direct replacement N2, then N1 oio:consider + N2 +enums: + ObsoletionPolicyEnum: + permissible_values: + NoLogicalAxiomsOnObsoletes: + description: The obsoletion policy is that there MUST NOT be logical axioms about an obsolete node + ObsoleteLabelsArePrefixed: + description: The obsoletion policy is that any label on an obsolete node MUST be prefixed with 'obsolete' or similar + diff --git a/linkml/ontology_model.yaml b/linkml/ontology_model.yaml new file mode 100644 index 0000000..31325c3 --- /dev/null +++ b/linkml/ontology_model.yaml @@ -0,0 +1,160 @@ +id: https://w3id.org/kgcl/ontology +name: kgcl_schema-ontology-model +title: knowledge graph change language ontology model +description: A basic bare-bones model of an ontology or ontology-like structure. The + purpose is not to provide a complete model, rather just sufficient structure for + domain and range constraints in the ocl model +license: https://creativecommons.org/publicdomain/zero/1.0/ +version: 0.0.1 +prefixes: + om: http://w3id.org/kgcl/om/ + dcterms: http://purl.org/dc/terms/ + linkml: https://w3id.org/linkml/ + oio: http://www.geneontology.org/formats/oboInOwl# +default_prefix: om +default_range: string +imports: +- linkml:types +- basics +classes: + OntologyElement: + aliases: + - entity + description: Any component of an ontology or knowledge graph + PropertyValue: + is_a: OntologyElement + description: a property-value pair + slots: + - property + - filler + Annotation: + is_a: PropertyValue + description: owl annotations. Not to be confused with annotations sensu GO + slots: + - property + - filler + - annotation_set + - property_type + - filler_type + mappings: + - owl:Annotation + Node: + aliases: + - entity + - term + is_a: OntologyElement + description: Any named entity in an ontology. May be a class, individual, property + slots: + - id + - name + - annotation_set + - owl_type + ClassNode: + aliases: + - concept + is_a: Node + description: A node that is a class + class_uri: owl:Class + InstanceNode: + aliases: + - named individual + is_a: Node + description: A node that is an individual + class_uri: owl:NamedIndividual + Edge: + aliases: + - triple + - axiom + - relationship + is_a: OntologyElement + description: >- + A relationship between two nodes. + + Currently the only kinds of edges supported in KGCL: + + * A subClassOf B <==> Edge(subject=A, predicate=owl:subClassOf, object=B) + * A subClassOf P some B <==> Edge(subject=A, predicate=P, object=B) + * P subPropertyOf Q <==> Edge(subject=P, predicate=owl:subPropertyOf, object=Q) + + These represent the most common kind of pairwise relationship between classes, + and classes are the dominant node type in ontologies. + + In future a wider variety of OWL axiom types will be supportedn through the use + of an additional edge property/slot to indicate the interpretation of the axiom, + following owlstar (https://github.com/cmungall/owlstar). + + For example: + * `A subClassOf R only B <==> Edge(subject=A, predicate=P, object=B, interpretation=AllOnly)` + * `A Annotation(P,B) <==> Edge(subject=A, predicate=P, object=B, interpretation=annotationAssertion)` + + Note that not all axioms are intended to map to edges. Axioms/triples where the object is a literal + would be represented as node properties. Complex OWL axioms involving nesting would have their own + dedicated construct, or may be represented generically. These are out of scope for the current + version of KGCL + + mappings: + - owl:Axiom + - rdf:Statement + slots: + - subject + - predicate + - object + - subject_representation + - predicate_representation + - object_representation + - annotation_set + LogicalDefinition: + is_a: OntologyElement + OntologySubset: + is_a: Node +slots: + owl_type: + range: OwlType + name: {} + subject: + range: Node + object: + range: Node + predicate: + range: Node + annotation_set: + range: Annotation + property: + range: Node + filler: null + property_type: + deprecated: no longer required + filler_type: + deprecated: no longer required + subject_representation: + deprecated: no longer required + predicate_representation: + deprecated: no longer required + object_representation: + deprecated: no longer required + property_value_set: + range: PropertyValue + multivalued: true + inlined: true +enums: + OwlType: + permissible_values: + CLASS: + meaning: owl:Class + OBJECT_PROPERTY: + meaning: owl:ObjectProperty + NAMED_INDIVIDUAL: + meaning: owl:NamedIndividual + ANNOTATION_PROPERTY: + meaning: owl:AnnotationProperty + SynonymScopeEnum: + permissible_values: + related: + meaning: oio:hasNarrowSynonym + broad: + meaning: oio:hasBroadSynonym + narrow: + meaning: oio:hasNarrowSynonym + exact: + meaning: oio:hasExactSynonym + diff --git a/linkml/prov.yaml b/linkml/prov.yaml new file mode 100644 index 0000000..321d28b --- /dev/null +++ b/linkml/prov.yaml @@ -0,0 +1,72 @@ +id: https://w3id.org/kgcl/prov +name: KGCL-PROV +title: KGCL Rendering of prov schema +description: See https://www.w3.org/TR/prov-o/ +license: https://creativecommons.org/publicdomain/zero/1.0/ +prefixes: + prov: http://www.w3.org/ns/prov# + linkml: https://w3id.org/linkml/ +default_prefix: prov +default_range: string +default_curi_maps: +- semweb_context +imports: +- linkml:types +- basics +classes: + + ProvElement: + abstract: true + description: A grouping for prov elements + + Activity: + is_a: ProvElement + description: a provence-generating activity + slots: + - id + - started_at_time + - ended_at_time + - was_informed_by + - was_associated_with + - used + - description + mappings: + - prov:Activity + Agent: + is_a: ProvElement + description: a provence-generating agent + slots: + - id + - acted_on_behalf_of + - was_informed_by + class_uri: prov:Agent +slots: + started_at_time: + slot_uri: prov:startedAtTime + ended_at_time: + slot_uri: prov:endedAtTime + was_informed_by: + range: Activity + slot_uri: prov:wasInformedBy + was_associated_with: + range: Agent + slot_uri: prov:wasAssociatedWith + inlined: false + acted_on_behalf_of: + range: Agent + slot_uri: prov:actedOnBehalfOf + was_generated_by: + range: Activity + slot_uri: prov:wasGeneratedBy + used: + domain: Activity + slot_uri: prov:used + activity_set: + range: Activity + multivalued: true + inlined_as_list: true + agent_set: + range: Agent + multivalued: true + inlined_as_list: true + diff --git a/pom.xml b/pom.xml index 39d2887..f472d2c 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,19 @@ + + + central-snapshots + https://central.sonatype.com/repository/maven-snapshots + + false + + + true + + + + UTF-8 diff --git a/robot/src/main/java/org/incenp/obofoundry/kgcl/robot/ApplyCommand.java b/robot/src/main/java/org/incenp/obofoundry/kgcl/robot/ApplyCommand.java index 668e007..a7e66c1 100644 --- a/robot/src/main/java/org/incenp/obofoundry/kgcl/robot/ApplyCommand.java +++ b/robot/src/main/java/org/incenp/obofoundry/kgcl/robot/ApplyCommand.java @@ -32,8 +32,8 @@ import org.apache.commons.cli.Options; import org.incenp.obofoundry.dicer.IAutoIDGenerator; import org.incenp.obofoundry.dicer.IDException; -import org.incenp.obofoundry.dicer.IDRange; import org.incenp.obofoundry.dicer.IDPolicyHelper; +import org.incenp.obofoundry.dicer.IDRange; import org.incenp.obofoundry.dicer.OWLExistenceChecker; import org.incenp.obofoundry.dicer.RandomizedIDGenerator; import org.incenp.obofoundry.kgcl.AutoIDAllocator; @@ -74,6 +74,7 @@ public ApplyCommand() { options.addOption("c", "create", false, "create a new ontology with the changes"); options.addOption("k", "kgcl", true, "apply a single change"); options.addOption("K", "kgcl-file", true, "apply all changes in specified file"); + options.addOption("Y", "kgcl-yaml", true, "apply all changes in the specified YAML file"); options.addOption(null, "no-partial-apply", false, "apply all changes or none at all"); options.addOption("R", "reject-file", true, "write rejected change in specified file"); options.addOption(null, "no-reject-file", false, "do no write rejected change to a file"); @@ -163,6 +164,12 @@ public CommandState execute(CommandState state, String[] args) throws Exception changeset.addAll(KGCLHelper.parse(f, prefixManager, errors, labelResolver)); } } + if ( line.hasOption('Y') ) { + for ( String yamlFile : line.getOptionValues('Y') ) { + File f = new File(yamlFile); + changeset.addAll(KGCLHelper.parseYAML(f, prefixManager)); + } + } if ( !errors.isEmpty() ) { for ( KGCLSyntaxError error : errors ) {