Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcbrun2017-05-16 08:39:31 +0000
committerSt├ęphane B├ęgaudeau2017-05-16 09:43:19 +0000
commit0f1b216f4a08bc964c7241ab53d1324b15f2b147 (patch)
tree584ebb19901adf759890bce319b0c3497e1bc950
parent14d5f6ccfb4a06e30417db3f8207b5b63e35a928 (diff)
downloadorg.eclipse.eef-0f1b216f4a08bc964c7241ab53d1324b15f2b147.tar.gz
org.eclipse.eef-0f1b216f4a08bc964c7241ab53d1324b15f2b147.tar.xz
org.eclipse.eef-0f1b216f4a08bc964c7241ab53d1324b15f2b147.zip
[516668] Introduce arbitrary ID's to identify EObjects
This commit introduce arbitrary ID's to identify EObject when a page is computed in order to stop relying on EcoreUtil.getURI() which has a number of problems - performance is not great when having deep models (but arguably this code is not a hot spot) - the URI might change over time for a given EObject, for instance in Ecore renaming an EClass will lead to a change of URI, and then a spurious reset of the page (and the widget focus gets lost) Bug: 516668 Change-Id: I392754c88fdee5bcaaf98043d4c2894559accc4b Signed-off-by: Cedric Brun <cedric.brun@obeo.fr>
-rw-r--r--plugins/org.eclipse.eef.ide.ui.properties/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.eef.ide.ui.properties/src/org/eclipse/eef/ide/ui/properties/api/EEFTabDescriptor.java18
-rw-r--r--plugins/org.eclipse.eef.ide.ui.properties/src/org/eclipse/eef/ide/ui/properties/internal/RefreshIdsHolder.java86
3 files changed, 103 insertions, 4 deletions
diff --git a/plugins/org.eclipse.eef.ide.ui.properties/META-INF/MANIFEST.MF b/plugins/org.eclipse.eef.ide.ui.properties/META-INF/MANIFEST.MF
index 14d184f0d..3d0b6593f 100644
--- a/plugins/org.eclipse.eef.ide.ui.properties/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.eef.ide.ui.properties/META-INF/MANIFEST.MF
@@ -16,5 +16,6 @@ Require-Bundle: org.eclipse.emf.ecore;bundle-version="[2.8.0,3.0.0)",
org.eclipse.jface;bundle-version="[3.0.0,4.0.0)",
org.eclipse.ui;bundle-version="[3.0.0,4.0.0)",
org.eclipse.ui.views;bundle-version="[3.0.0,4.0.0)"
-Export-Package: org.eclipse.eef.ide.ui.properties.api;version="2.0.0"
+Export-Package: org.eclipse.eef.ide.ui.properties.api;version="2.0.0",
+ org.eclipse.eef.ide.ui.properties.internal;version="2.0.0";x-internal:=true
Import-Package: org.eclipse.sirius.common.interpreter.api;version="1.0.0"
diff --git a/plugins/org.eclipse.eef.ide.ui.properties/src/org/eclipse/eef/ide/ui/properties/api/EEFTabDescriptor.java b/plugins/org.eclipse.eef.ide.ui.properties/src/org/eclipse/eef/ide/ui/properties/api/EEFTabDescriptor.java
index 5c21eb430..b8e7dff3a 100644
--- a/plugins/org.eclipse.eef.ide.ui.properties/src/org/eclipse/eef/ide/ui/properties/api/EEFTabDescriptor.java
+++ b/plugins/org.eclipse.eef.ide.ui.properties/src/org/eclipse/eef/ide/ui/properties/api/EEFTabDescriptor.java
@@ -19,11 +19,11 @@ import org.eclipse.eef.core.api.EEFExpressionUtils;
import org.eclipse.eef.core.api.EEFGroup;
import org.eclipse.eef.core.api.EEFPage;
import org.eclipse.eef.core.api.utils.EvalFactory;
+import org.eclipse.eef.ide.ui.properties.internal.RefreshIdsHolder;
import org.eclipse.eef.properties.ui.api.AbstractEEFTabDescriptor;
import org.eclipse.eef.properties.ui.api.IEEFSectionDescriptor;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.util.EcoreUtil;
/**
* The implementation of the {@link AbstractEEFTabDescriptor} using the {@link EEFPage}.
@@ -73,7 +73,7 @@ public class EEFTabDescriptor extends AbstractEEFTabDescriptor {
Object groupSemanticElement = eefGroup.getVariableManager().getVariables().get(EEFExpressionUtils.SELF);
if (groupSemanticElement instanceof EObject) {
- identifier.append(EcoreUtil.getURI((EObject) groupSemanticElement));
+ identifier.append(this.getIdForEObject((EObject) groupSemanticElement));
}
identifier.append(groupSemanticElement.hashCode());
}
@@ -90,13 +90,25 @@ public class EEFTabDescriptor extends AbstractEEFTabDescriptor {
Object pageSemanticElement = this.eefPage.getVariableManager().getVariables().get(EEFExpressionUtils.SELF);
if (pageSemanticElement instanceof EObject) {
- identifier.append(EcoreUtil.getURI((EObject) pageSemanticElement));
+ identifier.append(this.getIdForEObject((EObject) pageSemanticElement));
}
identifier.append(System.identityHashCode(pageSemanticElement));
return identifier.toString();
}
/**
+ * Returns an unique identifier for the given EObject which will stay the same even after changes which would impact
+ * its URI (for example, changing the name of an EClass).
+ *
+ * @param eObject
+ * The EObject
+ * @return The unique identifier of the given EObject
+ */
+ private Integer getIdForEObject(EObject eObject) {
+ return RefreshIdsHolder.getOrCreateID(eObject);
+ }
+
+ /**
* {@inheritDoc}
*
* @see org.eclipse.eef.properties.ui.api.IEEFTabDescriptor#getLabel()
diff --git a/plugins/org.eclipse.eef.ide.ui.properties/src/org/eclipse/eef/ide/ui/properties/internal/RefreshIdsHolder.java b/plugins/org.eclipse.eef.ide.ui.properties/src/org/eclipse/eef/ide/ui/properties/internal/RefreshIdsHolder.java
new file mode 100644
index 000000000..d7251f760
--- /dev/null
+++ b/plugins/org.eclipse.eef.ide.ui.properties/src/org/eclipse/eef/ide/ui/properties/internal/RefreshIdsHolder.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2017 THALES GLOBAL SERVICES and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.eef.ide.ui.properties.internal;
+
+import org.eclipse.emf.common.notify.impl.AdapterImpl;
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * This class is responsible for providing an ID used during the refresh to match candidates and existing elements. We
+ * used to use EcoreUtil.getURI() but it was not performing well enough and could change when an attribute used as an
+ * eKeys was changed.
+ *
+ * The ID is associated with the element through the eAdapters mechanism and as such is stable as long as the element is
+ * there.
+ *
+ * This class is roughly based on RefreshIdsHolder in the Eclipse Sirius codebase.
+ *
+ * @author cbrun
+ * @since 2.0
+ *
+ */
+public final class RefreshIdsHolder extends AdapterImpl {
+
+ /**
+ * The previous identifier created for an EObject.
+ */
+ private static Integer lastID = Integer.valueOf(0);
+
+ /**
+ * The identifier of the EObject to which this adapter is attached.
+ */
+ private Integer id;
+
+ /**
+ * The constructor.
+ *
+ * @param id
+ * The identifier of the EObject
+ */
+ private RefreshIdsHolder(Integer id) {
+ this.id = id;
+ }
+
+ /**
+ * Return the element Id if there is one, create a new one if it's not already here.
+ *
+ * @param eObject
+ * any EObject.
+ * @return the existing Id or the new one.
+ */
+ public static Integer getOrCreateID(final EObject eObject) {
+ // @formatter:off
+ RefreshIdsHolder refreshIdsHolder = eObject.eAdapters().stream()
+ .filter(RefreshIdsHolder.class::isInstance)
+ .map(RefreshIdsHolder.class::cast)
+ .findFirst()
+ .orElseGet(() -> {
+ RefreshIdsHolder newRefreshIdsHolder = new RefreshIdsHolder(lastID);
+ eObject.eAdapters().add(newRefreshIdsHolder);
+ lastID = Integer.valueOf(lastID.intValue() + 1);
+ return newRefreshIdsHolder;
+ });
+ // @formatter:on
+
+ return refreshIdsHolder.getId();
+ }
+
+ /**
+ * return the ID which got assigned to this Object.
+ *
+ * @return the ID which got assigned to this Object
+ */
+ private Integer getId() {
+ return this.id;
+ }
+
+}

Back to the top