Allow proxy resolution from the EMF Compare content merge viewers
Bug: 532484
Change-Id: Id92ebeb8f41dbd224cdae843ee4133880e0d394c
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ManyStructuralFeatureAccessorImpl.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ManyStructuralFeatureAccessorImpl.java
index 5e7bd76..8c9c342 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ManyStructuralFeatureAccessorImpl.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/ManyStructuralFeatureAccessorImpl.java
@@ -290,7 +290,7 @@
*/
protected List<?> getFeatureValues(MergeViewerSide side) {
final EObject eObject = getEObject(side);
- return ReferenceUtil.getAsList(eObject, getStructuralFeature());
+ return ReferenceUtil.getAsListResolving(eObject, getStructuralFeature());
}
/**
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/SingleStructuralFeatureAccessorImpl.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/SingleStructuralFeatureAccessorImpl.java
index 06ef29f..4c5a690 100644
--- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/SingleStructuralFeatureAccessorImpl.java
+++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/contentmergeviewer/accessor/impl/SingleStructuralFeatureAccessorImpl.java
@@ -77,7 +77,7 @@
Object value = null;
EObject eObject = getEObject(side);
if (eObject != null) {
- value = ReferenceUtil.safeEGet(eObject, getStructuralFeature());
+ value = ReferenceUtil.safeResolvingEGet(eObject, getStructuralFeature());
}
return value;
}
diff --git a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/ReferenceUtil.java b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/ReferenceUtil.java
index 488b724..52b26c8 100644
--- a/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/ReferenceUtil.java
+++ b/plugins/org.eclipse.emf.compare/src/org/eclipse/emf/compare/utils/ReferenceUtil.java
@@ -78,6 +78,43 @@
}
/**
+ * This utility simply allows us to retrieve the value of a given feature as a List.
+ * <p>
+ * <b>Note</b> that contrary to {@link #getAsList(EObject, EStructuralFeature)}, this will allow proxy
+ * resolution.
+ * </p>
+ *
+ * @param object
+ * The object for which feature we need a value.
+ * @param feature
+ * The actual feature of which we need the value.
+ * @return The value of the given <code>feature</code> for the given <code>object</code> as a list. An
+ * empty list if this object has no value for that feature or if the object is <code>null</code>.
+ */
+ @SuppressWarnings("unchecked")
+ public static List<Object> getAsListResolving(EObject object, EStructuralFeature feature) {
+ if (object != null && feature != null) {
+ Object value = safeResolvingEGet(object, feature);
+ final List<Object> asList;
+ if (feature == EcorePackage.Literals.ECLASS__ESUPER_TYPES
+ || feature == EcorePackage.Literals.EOPERATION__EEXCEPTIONS) {
+ // workaround 394286. Use the normal list, resolution is not much of a problem on these.
+ asList = (List<Object>)value;
+ } else if (value instanceof List) {
+ asList = (List<Object>)value;
+ } else if (value instanceof Iterable) {
+ asList = ImmutableList.copyOf((Iterable<Object>)value);
+ } else if (value != null) {
+ asList = ImmutableList.of(value);
+ } else {
+ asList = Collections.emptyList();
+ }
+ return asList;
+ }
+ return Collections.emptyList();
+ }
+
+ /**
* In case of dynamic EObjects, the EClasses of both sides might be different, making "eget" fail in
* "unknown feature". We assume that even if the EClasses are distinct instances, they are the same
* nonetheless, and thus we can use the feature name in order to retrieve the feature's value.
@@ -94,6 +131,26 @@
}
/**
+ * In case of dynamic EObjects, the EClasses of both sides might be different, making "eget" fail in
+ * "unknown feature". We assume that even if the EClasses are distinct instances, they are the same
+ * nonetheless, and thus we can use the feature name in order to retrieve the feature's value.
+ * <p>
+ * <b>Note</b> that contrary to {@link #safeEGet(EObject, EStructuralFeature)}, this will allow proxy
+ * resolution.
+ * </p>
+ *
+ * @param object
+ * The object for which feature we need a value, must not be <code>null</code>.
+ * @param feature
+ * The actual feature of which we need the value, must not be <code>null</code>.
+ * @return The value of the given {@code feature} for the given {@code object}.
+ */
+ public static Object safeResolvingEGet(EObject object, EStructuralFeature feature) {
+ final int featureID = getFeatureID(feature, object.eClass());
+ return ((InternalEObject)object).eGet(featureID, true, true);
+ }
+
+ /**
* In case of dynamic EObjects, the EClasses of both sides might be different, making "isset" fail in
* "unknown feature". We assume that even if the EClasses are distinct instances, they are the same
* nonetheless, and thus we can use the feature name in order to retrieve the feature's value.