Home » Modeling » Compare » UnmatchElement List vs total(UnmatchElement List vs total)
|
Re: UnmatchElement List vs total [message #1058283 is a reply to message #1058054] |
Mon, 13 May 2013 13:04 |
|
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 08:40 |
|
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 15:05 |
Andrew Whelan Messages: 71 Registered: October 2012 Location: Syracuse NY |
Member |
|
|
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 #1061956 is a reply to message #1061721] |
Wed, 05 June 2013 07:03 |
|
Andrew,
Yours is one of the use cases EMF Compare has been designed for. If you get a lot of additions and deletions, chances are your EObjects aren't matched at all. Do you have identifiers for your EObjects? If so, are you sure these identifiers do not change between the EObject in memory (EObject-1) and the one you load from the database (EObject-2) ?
You can look at how EMF Compare retrieves an EObject's identifier in the code of IdentifierEObjectMatch.DefaultIDFunction. You could also prevent EMF Compare from using identifiers during matching.
If identifiers aren't the source of the issues, I won't be able to help much without more information about how your models look like and what we consider as being (wrong) differences in your case.
Laurent Goubet
Obeo
|
|
| |
Re: UnmatchElement List vs total [message #1063447 is a reply to message #1062075] |
Thu, 13 June 2013 08:19 |
Mikael Barbero Messages: 55 Registered: July 2009 |
Member |
|
|
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
Best regards,
Mikael Barbero
Obeo
|
|
|
Goto Forum:
Current Time: Tue Mar 19 06:36:12 GMT 2024
Powered by FUDForum. Page generated in 0.03784 seconds
|