[Compare] How to resolve proxies [message #1837934] |
Wed, 10 February 2021 22:51  |
Eclipse User |
|
|
|
Hi
I'm trying to compare two diagrams (located in aird-files). The logic is as follows. Two visual elements (diagrams, nodes, edges) are equal if their target (semantic) EObjects are equal. Target EObjects are equal if their names (or ids) are equal.
The problem is that semantic EObjects are located in a separate xmi-files. EMF Compare doesn't resolve proxies to these objects. So I can't get their names.
How could I fix it?
Also what is a right way to implement such a comparision? For now I defined a custom MatchEngineFactoryImpl. It creates a DefaultMatchEngine with IdentifierEObjectMatcher with custom id-getter:
import org.eclipse.emf.compare.match.DefaultComparisonFactory;
import org.eclipse.emf.compare.match.DefaultEqualityHelperFactory;
import org.eclipse.emf.compare.match.DefaultMatchEngine;
import org.eclipse.emf.compare.match.IComparisonFactory;
import org.eclipse.emf.compare.match.IMatchEngine;
import org.eclipse.emf.compare.match.eobject.IEObjectMatcher;
import org.eclipse.emf.compare.match.eobject.IdentifierEObjectMatcher;
import org.eclipse.emf.compare.match.impl.MatchEngineFactoryImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.gmf.runtime.notation.Anchor;
import org.eclipse.gmf.runtime.notation.Bendpoints;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.LayoutConstraint;
import org.eclipse.gmf.runtime.notation.Style;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.sirius.diagram.DSemanticDiagram;
import org.eclipse.sirius.viewpoint.DAnalysis;
import org.eclipse.sirius.viewpoint.DRepresentationDescriptor;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
import org.eclipse.sirius.viewpoint.DView;
import org.eclipse.sirius.viewpoint.IdentifiedElement;
import org.eclipse.sirius.viewpoint.UIState;
import com.google.common.base.Function;
public class MatchEngineFactory extends MatchEngineFactoryImpl {
public MatchEngineFactory() {
}
@Override
public IMatchEngine getMatchEngine() {
Function<EObject, String> idFunction = new Function<EObject, String>() {
public String apply(EObject obj) {
String id = getId(obj);
if (id == null) {
return null;
}
System.out.println(id + " " + obj);
return obj.eClass().getName() + id;
}
};
IEObjectMatcher matcher = new IdentifierEObjectMatcher(
new IdentifierEObjectMatcher(), idFunction);
IComparisonFactory comparisonFactory = new DefaultComparisonFactory(
new DefaultEqualityHelperFactory());
return new DefaultMatchEngine(matcher, comparisonFactory);
}
private static String getId(EObject obj) {
// GMF objects
if (obj instanceof Edge) {
return getId(((View) obj).getElement());
}
if (obj instanceof View) {
return getId(((View) obj).getElement());
}
if (obj instanceof LayoutConstraint) {
return null;
}
if (obj instanceof Style) {
return null;
}
if (obj instanceof Bendpoints) {
return null;
}
if (obj instanceof Anchor) {
return null;
}
// Sirius objects
if (obj instanceof DAnalysis) {
return "5387ba35-1f2d-4614-b29f-874ef97b27f6-DAnalysis";
}
if (obj instanceof DView) {
return "5387ba35-1f2d-4614-b29f-874ef97b27f6-DView";
}
if (obj instanceof DRepresentationDescriptor) {
EObject target = ((DRepresentationDescriptor) obj).getTarget();
EcoreUtil.resolve(target, (EObject) null);
return getId(target);
}
if (obj instanceof DSemanticDiagram) {
System.out.println(((DSemanticDiagram) obj).getTarget());
System.out.println(getId(((DSemanticDiagram) obj).getTarget()));
return getId(((DSemanticDiagram) obj).getTarget());
}
if (obj instanceof DSemanticDecorator) {
return getId(((DSemanticDecorator) obj).getTarget());
}
if (obj instanceof IdentifiedElement) {
return ((IdentifiedElement) obj).getUid();
}
if (obj instanceof UIState) {
return null;
}
// Other Ecore objects
EStructuralFeature idFeature = obj.eClass().getEStructuralFeature("id"); //$NON-NLS-1$
if (idFeature == null) {
return null;
}
Object id = obj.eGet(idFeature);
if (!(id instanceof String)) {
return null;
}
String result = (String) id;
if (result.isEmpty()) {
return null;
}
return result;
}
}
The following code returns null, because the target object is unresolved proxy and it's attributes aren't loaded:
if (obj instanceof DSemanticDecorator) {
return getId(((DSemanticDecorator) obj).getTarget());
}
Actually there are a lot of ugly hacks. The method returns the same id for any DAnalysis or DView. So they are always equal.
Maybe it's better to implement a custom IEqualityHelper?
|
|
|
|
Re: [Compare] How to resolve proxies [message #1837973 is a reply to message #1837957] |
Thu, 11 February 2021 09:42  |
Eclipse User |
|
|
|
There is a one more scenario. I'm trying to compare two EObjects in a model. Some of the contents of the EObjects is moved into separate files using (Sirius Control or EMF Control Command):
<entities name="some object">
<details xsi:type="some:type" href="link to external entity"/>
</entities>
The problem is that EObjects contained in the separate files are ignored during comparision.
Using debug I've found the following method in the FilterComparisonScope class:
public Iterator<? extends EObject> getChildren(EObject eObject) {
if (eObject == null) {
return emptyIterator();
}
final Iterator<EObject> properContent = EcoreUtil.getAllProperContents(eObject, false);
final Iterator<EObject> filter = Iterators.filter(properContent, eObjectContentFilter);
final Iterator<EObject> uriInitializingIt = new URIInitializingIterator<EObject>(eObject, filter);
return Iterators.unmodifiableIterator(uriInitializingIt);
}
The 2nd parameter for EcoreUtil.getAllProperContents() is false. So it never resolve proxies.
I can't find any way to define custom IComparisonScope or to force EMF Compare to resolve proxies.
|
|
|
Powered by
FUDForum. Page generated in 0.28151 seconds