From bb94311f5c66e6c7088e6bb5947fc034a149f9b3 Mon Sep 17 00:00:00 2001 From: Yevgeny Kazakov Date: Tue, 11 Jun 2024 12:39:42 +0200 Subject: [PATCH 1/6] Process escape characters when searching for entities, fix #1217 Previously this was done only when searching for OWLClasses --- .../editor/owl/model/find/OWLEntityFinderImpl.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/find/OWLEntityFinderImpl.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/find/OWLEntityFinderImpl.java index 6fd3f61b8..eacaabad8 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/find/OWLEntityFinderImpl.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/find/OWLEntityFinderImpl.java @@ -57,7 +57,8 @@ private String stripAndEscapeRendering(String rendering) { } public OWLClass getOWLClass(String rendering) { - OWLClass cls = renderingCache.getOWLClass(stripAndEscapeRendering(rendering)); + rendering = stripAndEscapeRendering(rendering); + OWLClass cls = renderingCache.getOWLClass(rendering); if (cls == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)) { cls = renderingCache.getOWLClass(RenderingEscapeUtils.getEscapedRendering(rendering)); } @@ -70,6 +71,7 @@ public Set getOWLEntities(String rendering) { } public OWLObjectProperty getOWLObjectProperty(String rendering) { + rendering = stripAndEscapeRendering(rendering); OWLObjectProperty prop = renderingCache.getOWLObjectProperty(rendering); if (prop == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)){ prop = renderingCache.getOWLObjectProperty(RenderingEscapeUtils.getEscapedRendering(rendering)); @@ -79,6 +81,7 @@ public OWLObjectProperty getOWLObjectProperty(String rendering) { public OWLDataProperty getOWLDataProperty(String rendering) { + rendering = stripAndEscapeRendering(rendering); OWLDataProperty prop = renderingCache.getOWLDataProperty(rendering); if (prop == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)){ prop = renderingCache.getOWLDataProperty(RenderingEscapeUtils.getEscapedRendering(rendering)); @@ -88,6 +91,7 @@ public OWLDataProperty getOWLDataProperty(String rendering) { public OWLAnnotationProperty getOWLAnnotationProperty(String rendering) { + rendering = stripAndEscapeRendering(rendering); OWLAnnotationProperty prop = renderingCache.getOWLAnnotationProperty(rendering); if (prop == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)){ prop = renderingCache.getOWLAnnotationProperty(RenderingEscapeUtils.getEscapedRendering(rendering)); @@ -97,6 +101,7 @@ public OWLAnnotationProperty getOWLAnnotationProperty(String rendering) { public OWLNamedIndividual getOWLIndividual(String rendering) { + rendering = stripAndEscapeRendering(rendering); OWLNamedIndividual individual = renderingCache.getOWLIndividual(rendering); if (individual == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)){ individual = renderingCache.getOWLIndividual(RenderingEscapeUtils.getEscapedRendering(rendering)); @@ -106,6 +111,7 @@ public OWLNamedIndividual getOWLIndividual(String rendering) { public OWLDatatype getOWLDatatype(String rendering) { + rendering = stripAndEscapeRendering(rendering); OWLDatatype dataType = renderingCache.getOWLDatatype(rendering); if (dataType == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)){ dataType = renderingCache.getOWLDatatype(RenderingEscapeUtils.getEscapedRendering(rendering)); @@ -115,6 +121,7 @@ public OWLDatatype getOWLDatatype(String rendering) { public OWLEntity getOWLEntity(String rendering) { + rendering = stripAndEscapeRendering(rendering); OWLEntity entity = renderingCache.getOWLEntity(rendering); if (entity == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)){ entity = renderingCache.getOWLEntity(RenderingEscapeUtils.getEscapedRendering(rendering)); From 8bc06672f7c2c1b993640210e3f84a77263b2a11 Mon Sep 17 00:00:00 2001 From: Yevgeny Kazakov Date: Tue, 11 Jun 2024 17:32:03 +0200 Subject: [PATCH 2/6] Fix saving equivalent objects in OWLCellRenderer. Fixes #910 --- .../org/protege/editor/owl/ui/renderer/OWLCellRenderer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/renderer/OWLCellRenderer.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/renderer/OWLCellRenderer.java index b80a8154d..040e92d68 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/renderer/OWLCellRenderer.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/renderer/OWLCellRenderer.java @@ -255,6 +255,8 @@ public void save() { tmp.crossedOutEntities.addAll(crossedOutEntities); tmp.unsatisfiableNames.clear(); tmp.unsatisfiableNames.addAll(unsatisfiableNames); + tmp.equivalentObjects.clear(); + tmp.equivalentObjects.addAll(equivalentObjects); tmp.boxedNames.clear(); tmp.boxedNames.addAll(boxedNames); unlock(); From 1743a003ab6530018baaa3e3b3b9c2e3f8ce8871 Mon Sep 17 00:00:00 2001 From: Yevgeny Kazakov Date: Tue, 11 Jun 2024 21:47:35 +0200 Subject: [PATCH 3/6] Update object tree if only equivalences were added or removed When adding OWLEquivalentClasses(:A :B) for which A and B already appear in the asserted class hierarchy, there was no change in the model of the tree component because no child or parent nodes were added or removed. Consequently, the tree component did not refresh, and the new labels A = B and B = A of the nodes A and B were truncated. This commit make sure that the model gets notified about the changes of the node. See https://github.com/protegeproject/protege/issues/910#issuecomment-2160903704 --- .../hierarchy/OWLObjectHierarchyProviderListener.java | 4 ++-- .../org/protege/editor/owl/ui/tree/OWLObjectTree.java | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/hierarchy/OWLObjectHierarchyProviderListener.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/hierarchy/OWLObjectHierarchyProviderListener.java index 6f5d2a4b9..e6a14724a 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/hierarchy/OWLObjectHierarchyProviderListener.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/hierarchy/OWLObjectHierarchyProviderListener.java @@ -15,8 +15,8 @@ public interface OWLObjectHierarchyProviderListener { /** - * Notifies the listener that the parents and or children - * of the specified node might have changed. This is usually + * Notifies the listener that the equivalent objects, parents and or + * children of the specified node might have changed. This is usually * called in response to an add/remove axiom change. */ public void nodeChanged(N node); diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/tree/OWLObjectTree.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/tree/OWLObjectTree.java index fddeb1494..1b925b051 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/tree/OWLObjectTree.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/tree/OWLObjectTree.java @@ -283,8 +283,8 @@ public String getToolTipText(MouseEvent event) { @SuppressWarnings("unchecked") private void updateNode(N node) { - // This method is called when the parents or children of - // a node might have changed. We handle the following possibilities + // This method is called when the node, its parents or children + // might have changed. We handle the following possibilities // 1) The node had a child added // 2) The node had a child removed // If we are displaying the node which had the child added or removed @@ -292,8 +292,12 @@ private void updateNode(N node) { final Set> treeNodes = nodeMap.get(node); - // The parents/children might have changed + // The node/parents/children might have changed if (treeNodes != null && !treeNodes.isEmpty()) { + // The node equivalent objects might have changed + // @@TODO: use provider to check if this were the case + treeNodes.forEach(((DefaultTreeModel) getModel())::nodeChanged); + // Remove children that aren't there any more Set children = provider.getChildren(node); From 36ff6f34dffd41d45f4da58a4014e7002b07d86f Mon Sep 17 00:00:00 2001 From: Yevgeny Kazakov Date: Wed, 12 Jun 2024 09:34:13 +0200 Subject: [PATCH 4/6] Improve render string escaping for backslash and double quotes so that the result is parsed by Manchester OWL syntax parser Specifically: - Escape double quotes - Escape backslashes - Enclose in single quotes if the original string contains backslash These changes are to mirror ManchesterOWLSyntaxTokenizer Examples of rdfs:label of classes, tested to parse in Class expression editor: - [Foo'Bar] becomes [Foo\'Bar] - [Foo"Bar] becomes [Foo\"Bar] - [Foo\Bar] becomes ['Foo\\Bar'] - [Foo\'Bar] becomes ['Foo\\\'Bar'] - [Foo\\Bar] becomes ['Foo\\\\Bar'] Improve test cases to include escaping roundtrip --- .../owl/ui/renderer/RenderingEscapeUtils.java | 22 +++--- .../RenderingEscapeUtils_TestCase.java | 75 ++++++++++--------- 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/renderer/RenderingEscapeUtils.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/renderer/RenderingEscapeUtils.java index 34ef061f1..50840dd6e 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/renderer/RenderingEscapeUtils.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/renderer/RenderingEscapeUtils.java @@ -33,8 +33,12 @@ public enum RenderingEscapeSetting { * @return The escaped rendering. */ public static String getEscapedRendering(String originalRendering) { - originalRendering = originalRendering.replace("'", "\\'"); + String rendering = originalRendering; + rendering = rendering.replace("\\", "\\\\"); + rendering = rendering.replace("'", "\\'"); + rendering = rendering.replace("\"", "\\\""); if (originalRendering.indexOf(' ') != -1 + || originalRendering.indexOf('\\') != -1 || originalRendering.indexOf(',') != -1 || originalRendering.indexOf('<') != -1 || originalRendering.indexOf('>') != -1 @@ -47,22 +51,20 @@ public static String getEscapedRendering(String originalRendering) { || originalRendering.indexOf(']') != -1 || originalRendering.indexOf('(') != -1 || originalRendering.indexOf(')') != -1) { - return "'" + originalRendering + "'"; - } - else { - return originalRendering; + rendering = "'" + rendering + "'"; } + return rendering; } @Nonnull public static String unescape(@Nonnull String rendering) { - rendering = rendering.replace("\\'", "'"); if(rendering.startsWith("'") && rendering.endsWith("'")) { - return rendering.substring(1, rendering.length() - 1); - } - else { - return rendering; + rendering = rendering.substring(1, rendering.length() - 1); } + rendering = rendering.replace("\\\"", "\""); + rendering = rendering.replace("\\'", "'"); + rendering = rendering.replace("\\\\", "\\"); + return rendering; } } diff --git a/protege-editor-owl/src/test/java/org/protege/editor/owl/ui/renderer/RenderingEscapeUtils_TestCase.java b/protege-editor-owl/src/test/java/org/protege/editor/owl/ui/renderer/RenderingEscapeUtils_TestCase.java index 15bd06492..e7ee7bc52 100644 --- a/protege-editor-owl/src/test/java/org/protege/editor/owl/ui/renderer/RenderingEscapeUtils_TestCase.java +++ b/protege-editor-owl/src/test/java/org/protege/editor/owl/ui/renderer/RenderingEscapeUtils_TestCase.java @@ -1,11 +1,11 @@ package org.protege.editor.owl.ui.renderer; -import org.hamcrest.Matchers; -import org.junit.Test; - import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import org.hamcrest.Matchers; +import org.junit.Test; + /** * Matthew Horridge * Stanford Center for Biomedical Informatics Research @@ -13,100 +13,101 @@ */ public class RenderingEscapeUtils_TestCase { + private static void assertEscaped(String original, String escaped) { + String actualEscaped = RenderingEscapeUtils.getEscapedRendering(original); + assertThat(actualEscaped, Matchers.is(escaped)); + String actualUnescaped = RenderingEscapeUtils.unescape(escaped); + assertThat(actualUnescaped, Matchers.is(original)); + } + @Test public void shouldNotEscapeRendering() { - String rendering = RenderingEscapeUtils.getEscapedRendering("AB"); - assertThat(rendering, is("AB")); + assertEscaped("AB", "AB"); } @Test - public void shouldEscapeRenderingContainingSpace() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A B"); - assertThat(rendering, is("'A B'")); - } + public void shouldEscapeRenderingContainingSpace() { + assertEscaped("A B", "'A B'"); + } @Test public void shouldEscapeRenderingContainingComma() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A,B"); - assertThat(rendering, is("'A,B'")); + assertEscaped("A,B", "'A,B'"); } @Test public void shouldEscapeRenderingContainingLeftBracket() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A(B"); - assertThat(rendering, is("'A(B'")); + assertEscaped("A(B", "'A(B'"); } @Test public void shouldEscapeRenderingContainingRightBracket() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A)B"); - assertThat(rendering, is("'A)B'")); + assertEscaped("A)B", "'A)B'"); } @Test public void shouldEscapeRenderingContainingLeftSquareBracket() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A[B"); - assertThat(rendering, is("'A[B'")); + assertEscaped("A[B", "'A[B'"); } @Test public void shouldEscapeRenderingContainingRightSquareBracket() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A]B"); - assertThat(rendering, is("'A]B'")); + assertEscaped("A]B", "'A]B'"); } @Test public void shouldEscapeRenderingContainingLeftBrace() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A{B"); - assertThat(rendering, is("'A{B'")); + assertEscaped("A{B", "'A{B'"); } @Test public void shouldEscapeRenderingContainingRightBrace() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A}B"); - assertThat(rendering, is("'A}B'")); + assertEscaped("A}B", "'A}B'"); } @Test public void shouldEscapeRenderingContainingHat() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A^B"); - assertThat(rendering, is("'A^B'")); + assertEscaped("A^B", "'A^B'"); } @Test public void shouldEscapeRenderingContainingAt() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A@B"); - assertThat(rendering, is("'A@B'")); + assertEscaped("A@B", "'A@B'"); } @Test public void shouldEscapeRenderingContainingLessThan() { - String rendering = RenderingEscapeUtils.getEscapedRendering("AB"); - assertThat(rendering, is("'A>B'")); + assertEscaped("A>B", "'A>B'"); } @Test public void shouldEscapeRenderingContainingEquals() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A=B"); - assertThat(rendering, is("'A=B'")); + assertEscaped("A=B", "'A=B'"); } @Test public void shouldEscapeSingleQuote() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A's"); - assertThat(rendering, is("A\\'s")); + assertEscaped("A'B", "A\\'B"); + } + + @Test + public void shouldEscapeDoubleQuote() { + assertEscaped("A\"B", "A\\\"B"); + } + + @Test + public void shouldEscapeBackslash() { + assertEscaped("A\\B", "'A\\\\B'"); } @Test public void shouldEscapeSingleQuoteWithSpaces() { - String rendering = RenderingEscapeUtils.getEscapedRendering("A's and B's"); - assertThat(rendering, is("'A\\'s and B\\'s'")); + assertEscaped("A's and B's", "'A\\'s and B\\'s'"); } @Test From a25f9bea4f762c3de88b795bd646f733222531ae Mon Sep 17 00:00:00 2001 From: Yevgeny Kazakov Date: Wed, 12 Jun 2024 11:22:38 +0200 Subject: [PATCH 5/6] Simplify owl entity finder because stripAndEscapeRendering() should already return a canonical (unique) rendering representation, e.g., ['foo\'bar'] => [foo\'bar] --- .../owl/model/find/OWLEntityFinderImpl.java | 63 +++---------------- 1 file changed, 10 insertions(+), 53 deletions(-) diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/find/OWLEntityFinderImpl.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/find/OWLEntityFinderImpl.java index eacaabad8..dd653d1da 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/model/find/OWLEntityFinderImpl.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/model/find/OWLEntityFinderImpl.java @@ -41,28 +41,15 @@ public OWLEntityFinderImpl(OWLModelManagerImpl mngr, OWLEntityRenderingCache ren this.renderingCache = renderingCache; } - - private static final String ESCAPE_CHAR = "'"; - - private String stripAndEscapeRendering(String rendering) { - String strippedRendering; - if(rendering.startsWith("'") && rendering.endsWith("'") && rendering.length() > 1) { - strippedRendering = rendering.substring(1, rendering.length() - 1); + if (rendering.startsWith("'") && rendering.endsWith("'") && rendering.length() > 1) { + rendering = rendering.substring(1, rendering.length() - 1); } - else { - strippedRendering = rendering; - } - return RenderingEscapeUtils.getEscapedRendering(strippedRendering); + return RenderingEscapeUtils.getEscapedRendering(rendering); } public OWLClass getOWLClass(String rendering) { - rendering = stripAndEscapeRendering(rendering); - OWLClass cls = renderingCache.getOWLClass(rendering); - if (cls == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)) { - cls = renderingCache.getOWLClass(RenderingEscapeUtils.getEscapedRendering(rendering)); - } - return cls; + return renderingCache.getOWLClass(stripAndEscapeRendering(rendering)); } @Override @@ -71,62 +58,32 @@ public Set getOWLEntities(String rendering) { } public OWLObjectProperty getOWLObjectProperty(String rendering) { - rendering = stripAndEscapeRendering(rendering); - OWLObjectProperty prop = renderingCache.getOWLObjectProperty(rendering); - if (prop == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)){ - prop = renderingCache.getOWLObjectProperty(RenderingEscapeUtils.getEscapedRendering(rendering)); - } - return prop; + return renderingCache.getOWLObjectProperty(stripAndEscapeRendering(rendering)); } public OWLDataProperty getOWLDataProperty(String rendering) { - rendering = stripAndEscapeRendering(rendering); - OWLDataProperty prop = renderingCache.getOWLDataProperty(rendering); - if (prop == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)){ - prop = renderingCache.getOWLDataProperty(RenderingEscapeUtils.getEscapedRendering(rendering)); - } - return prop; + return renderingCache.getOWLDataProperty(stripAndEscapeRendering(rendering)); } public OWLAnnotationProperty getOWLAnnotationProperty(String rendering) { - rendering = stripAndEscapeRendering(rendering); - OWLAnnotationProperty prop = renderingCache.getOWLAnnotationProperty(rendering); - if (prop == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)){ - prop = renderingCache.getOWLAnnotationProperty(RenderingEscapeUtils.getEscapedRendering(rendering)); - } - return prop; + return renderingCache.getOWLAnnotationProperty(stripAndEscapeRendering(rendering)); } public OWLNamedIndividual getOWLIndividual(String rendering) { - rendering = stripAndEscapeRendering(rendering); - OWLNamedIndividual individual = renderingCache.getOWLIndividual(rendering); - if (individual == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)){ - individual = renderingCache.getOWLIndividual(RenderingEscapeUtils.getEscapedRendering(rendering)); - } - return individual; + return renderingCache.getOWLIndividual(stripAndEscapeRendering(rendering)); } public OWLDatatype getOWLDatatype(String rendering) { - rendering = stripAndEscapeRendering(rendering); - OWLDatatype dataType = renderingCache.getOWLDatatype(rendering); - if (dataType == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)){ - dataType = renderingCache.getOWLDatatype(RenderingEscapeUtils.getEscapedRendering(rendering)); - } - return dataType; + return renderingCache.getOWLDatatype(stripAndEscapeRendering(rendering)); } public OWLEntity getOWLEntity(String rendering) { - rendering = stripAndEscapeRendering(rendering); - OWLEntity entity = renderingCache.getOWLEntity(rendering); - if (entity == null && !rendering.startsWith(ESCAPE_CHAR) && !rendering.endsWith(ESCAPE_CHAR)){ - entity = renderingCache.getOWLEntity(RenderingEscapeUtils.getEscapedRendering(rendering)); - } - return entity; + return renderingCache.getOWLEntity(stripAndEscapeRendering(rendering)); } From 1ea8ed0bd814319f79162e884641071c80f70e38 Mon Sep 17 00:00:00 2001 From: Yevgeny Kazakov Date: Wed, 12 Jun 2024 13:06:45 +0200 Subject: [PATCH 6/6] Update owl tree nodes if rendering of equivalent entities has changed Each element of equivalent entities, e.g., resulted from OWLEquivalentClasses(:A :B) is rendered in the asserted hierarchy as the list of rendering of all equivalent classes, e.g.: > A = B > B = A When rendering of one of the entities has changed, e.g., due to editing of rdfs:label, other equivalent entities did not get automatically updated in the model. In particular, their rendering in the hierarchy could get truncated if the label becomes longer. See: https://github.com/protegeproject/protege/issues/910#issuecomment-2162709234 This commit notifies the tree model about the changes of every node for equivalent entities. Also, use nodeChanged() instead of nodeStructureChanged() because rendering does not change children or parents of nodes. --- .../protege/editor/owl/ui/tree/OWLModelManagerTree.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/tree/OWLModelManagerTree.java b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/tree/OWLModelManagerTree.java index ac31b018e..e297e6108 100644 --- a/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/tree/OWLModelManagerTree.java +++ b/protege-editor-owl/src/main/java/org/protege/editor/owl/ui/tree/OWLModelManagerTree.java @@ -125,7 +125,12 @@ private void handleRenderingChanged(OWLEntity entity) { try { for (OWLObjectTreeNode node : getNodes(entity)) { DefaultTreeModel model = (DefaultTreeModel) getModel(); - model.nodeStructureChanged(node); + model.nodeChanged(node); + for (N equivalentEntity: node.getEquivalentObjects()) { + for (OWLObjectTreeNode equivalentNode : getNodes(equivalentEntity)) { + model.nodeChanged(equivalentNode); + } + } } } catch (ClassCastException e) {