Home » Modeling » Compare » UnmatchElement List vs total(UnmatchElement List vs total)
UnmatchElement List vs total [message #1058054] |
Fri, 10 May 2013 12:22  |
Eclipse User |
|
|
|
When I do the following using EMFCompare
MatchModel match = MatchService.doMatch(eObject1,
eObject2, Collections.<String, Object> emptyMap());
The MatchModel returned has a method that will show me all of the elements of eObject2 that don't exist in eObject1 and elements of eObject1 that don't exist in eObject2. In this scenario eObject1 and eObject2 are of the same class or model.
EList<UnmatchElement> uList = match.getUnmachedElements();
Each UnmatchElement of uList has, among its contents, the EObject for the subelement of eObject1 or eObject2 that didn't appear in one. It also has a value Side for LEFT <eObject1> or RIGHT <eObject2>.
I want to get the total number of matchable elements from eObject1 so that I can calculate (total UnmatchElement from eObject2)/(total matchable elements of eObject1, which is the total number of subelements in eObject1). This way I could claim eObject2 has a certain percentage of matching elements from eObject1.
Can anyone tell me how to get the total number of matchable elements from eObject1 using the EMFCompare APIs so that I can make the above computation? (or if there is a way to get this outside of the EMFCompare APIs, I am interested in that too).
Thanks
-Andrew
|
|
|
Re: UnmatchElement List vs total [message #1058283 is a reply to message #1058054] |
Mon, 13 May 2013 09:04   |
Eclipse User |
|
|
|
Andrew,
This value would not be interesting with EMF Compare 1.*, which you are using, let's see "how to do it" first, I'll expand the "why won't it work" later.
"match.getUnmatchedElement()" will return all elements that we could not match, as you found out. In your case, you would use "eObject1.eAllContents().size()" to get the total number of elements that could have been matched (i.e. all elements that are contained by "eObject1". So a naive approach would be to say that "unmatchedElements / eAllContent().size()" is some kind of similarity percentage, However...
EMF Compare 1 did not look "under" unmatched elements to check for other matches (elements that have been moved from one container to the other for example). That is to say that with such models:
Model
|-Package1
|-Class1
|-Class2
and
Model
|-Package1
| |-Class1
|-Package2
|-Class2
(For a textual description : we created a new package, "package2" and moved the class "Class2" to that new container.)
You will have a MatchModel that contains two unmatched elements : "Package2" in right, and "Class2" in left. Whereas "Class2" really is not "unmatched", it has just moved "into" an unmatched element.
You would not have such a limitation with EMF Compare 2 : there is exactly one "Match" element for all elements of the input models, unmatched ones being represented by a "Match" which has only one of its sides filled in. If that is more clear, your Comparison model would look like so :
Comparison
|-Match "Package1 <-> Package1"
| |-Match "Class1 <-> Class1"
| |-Match "Class2 <-> Class2"
|-Match " <-> Package2"
Notice how there is only one match with only one side : "package2" really is the only unmatched element here. The match for "Class2" is located under the Match for Package1, but that hierarchy is only there to help visualize the comparison model in the UI, the "Class2" EObject it references for the "right" side really is the one that's located under Package2.
I'd advise using EMF Compare 2 instead of EMF Compare 1, this problem was the main limitation we created a second version in the first place .
Laurent Goubet
Obeo
|
|
| | |
Re: UnmatchElement List vs total [message #1059688 is a reply to message #1059609] |
Tue, 21 May 2013 04:40   |
Eclipse User |
|
|
|
Andrew,
You probably tried to clone at a moment git.eclipse.org was down... but I do not recall any down time for this server lately. Are you still seeing these issues now? Are you behind a proxy that would prevent you from accessing the server (you can try with the web UI at http://git.eclipse.org/c/emfcompare/org.eclipse.emf.compare.git/ )?
We use this repository daily, and I just cloned it with the exact same URL you did, successfuly :
$ git clone git://git.eclipse.org/gitroot/emfcompare/org.eclipse.emf.compare.git test.compare.clone
Cloning into test.compare.clone...
remote: Counting objects: 64600, done.
remote: Compressing objects: 100% (11172/11172), done.
remote: Total 64600 (delta 37662), reused 63388 (delta 36494)
Receiving objects: 100% (64600/64600), 14.42 MiB | 704 KiB/s, done.
Resolving deltas: 100% (37662/37662), done.
The documentation of EMF Compare 2 may still be incomplete, but the developer guide already describes some of the core concepts.
The "UnmatchElement" concept has disappeared from the metamodel since one of our goals was to simplify it and make for a more robust merge. An "unmatch" is an element for which only one side (or two, in the case of three-way comparisons) has been filled. There isn't an easy way to retrieve all unmatched elements... since this value evolves with the merge operations that are taken.
In the example above, I gave an example with one unmatched element :
Comparison
|-Match "Package1 <-> Package1"
| |-Match "Class1 <-> Class1"
| |-Match "Class2 <-> Class2"
|-Match " <-> Package2"
"Package2" is unmatched. If a user merges this change, the Comparison model evolves to look like this :
Comparison
|-Match "Package1 <-> Package1"
| |-Match "Class1 <-> Class1"
| |-Match "Class2 <-> Class2"
|-Match "Package2 <-> Package2"
i.e. there is no more "unmatched" elements here, and subsequent merge operations (moving "Class2" into "Package2") can use this information to move the element in the proper container.
You could emulate the behavior of EMF Compare 1 to get a "snapshot" of all unmatched elements at a given moment though something like this :
public List<Match> getUnmatched(Comparison comparison) {
final List<Match> unmatched = new ArrayList<Match>();
for (Match root : comparison.getMatches()) {
if (isUnmatched(root)) {
unmatched.add(root);
}
unmatched.addAll(getUnmatched(root));
}
return unmatched;
}
private List<Match> getUnmatched(Match match) {
final List<Match> unmatched = new ArrayList<Match>();
for (Match subMatch : match.getSubmatches()) {
if (isUnmatched(subMatch)) {
unmatched.add(subMatch);
}
unmatched.addAll(getUnmatched(subMatch));
}
return unmatched;
}
private boolean isUnmatched(Match match) {
if (match.getLeft() == null || match.getRight() == null) {
return true;
}
return match.getComparison().isThreeWay() && match.getOrigin() == null;
}
As you can see for yourself, this is kind of a "brute force" lookup : we never need this information, be it for the UI or for the merge, so it remains buried in the model. Do note that this is only the state at a given moment : merging any difference can make that information evolve. Once you have a "Match" corresponding to an unmatched element, finding out which side contains it is a matter of looking at the side which is not "null". (You might have more luck looking at the "Diff" elements themselves...)
Laurent Goubet
Obeo
|
|
|
Re: UnmatchElement List vs total [message #1061721 is a reply to message #1059688] |
Mon, 03 June 2013 11:05   |
Eclipse User |
|
|
|
Hi Laurent,
Thanks for the info. I'd like to ask your opinion of what I am finding. We have a, sort of, weird database that we use to store large EMF object data in. There is also, as you know, a default XMI file persistence mechanism that comes out of the box with EMF.
What I'm finding is this. We have data that we create in an editor, and we can write EMF object contents to a file.
We want to read data from a file into a EObject-1 , write it to our database, and then retrieve it from our database (into a new EObject-2). So these are essentially two different EMFObjects with the same data.
Should I be able to use EMFCompare in the above method to detect differences in EObject-1 and EObject-2? I really shouldn't have that many differneces based on my scenario, but I am coming up with tons of adds and deletes (Match.getDifferences().getKind()) that just make no sense. Is EMFCompare only meant to track changes of an object within a certain memory instance as changes are made to it in memory? Or should I be able to use it in my above scenario(will the object graph mechanisms support that)? If I should, then can you provide any clues as to why I might be seeing all of these adds, and deletes?
Thanks
-Andrew
|
|
| | |
Re: UnmatchElement List vs total [message #1063447 is a reply to message #1062075] |
Thu, 13 June 2013 04:19  |
Eclipse User |
|
|
|
Hi Andrew,
Sorry for the late answer. My comments below.
Quote:I am not creating a MatchEngine specifically in the code above. I had thought that some kind of default was being created within the creation of the Scope or builder. Do I need to be doing more than this?
Default behavior is to use identifier when it is available and fall back to "content-based match" when objects do not.
Quote:The Builder.setMatchEngine method has been replaced with setMatchEngineFactoryRegistry which takes a factory now instead of a MatchEngine, and I'm having trouble determining how to fix the above example. Is there a way to add the matchEngine created above to a factory and then use the factory?
Could you shed some light on that?
I updated the wiki page to reflect the new API http://wiki.eclipse.org/EMF_Compare/Developer_Guide#Overriding_the_Match_engine
|
|
|
Goto Forum:
Current Time: Sun Jul 06 23:20:29 EDT 2025
Powered by FUDForum. Page generated in 0.08610 seconds
|