Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Compare » UnmatchElement List vs total(UnmatchElement List vs total)
UnmatchElement List vs total [message #1058054] Fri, 10 May 2013 12:22 Go to next message
Andrew Whelan is currently offline Andrew Whelan
Messages: 69
Registered: October 2012
Location: Syracuse NY
Member
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 Go to previous messageGo to next message
Laurent Goubet is currently offline Laurent Goubet
Messages: 1625
Registered: July 2009
Senior Member
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 Smile.

Laurent Goubet
Obeo
Re: UnmatchElement List vs total [message #1059577 is a reply to message #1058283] Mon, 20 May 2013 10:49 Go to previous messageGo to next message
Andrew Whelan is currently offline Andrew Whelan
Messages: 69
Registered: October 2012
Location: Syracuse NY
Member
The trouble with EMF Compare 2 is the lack of documentation. I am also having major heartburn trying to check out the source code for the JUnit tests (the next best thing to documentation!).

git clone git://git.eclipse.org/gitroot/emfcompare/org.eclipse.emf.compare.git using the GIT Bash tool results in the following:

The line below was taken from http://wiki.eclipse.org/EMF_Compare/Contributor_Guide#Checking_out_the_code.

$ git clone git://git.eclipse.org/gitroot/emfcompare/org.eclipse.emf.compare.git

Cloning into 'org.eclipse.emf.compare'...
fatal: unable to connect to git.eclipse.org:
git.eclipse.org[0: 198.41.30.196]: errno=No error

I've also tried the GIT GUI and Importing using the Eclipse GIT interface, all having similar problems. Is there a way to get the source code (with unit tests) in a zip? The source JARs available when using the P2 update site to import into eclipse do not contain the source code Sad Or is there another URL you would with GIT?

Do you have any suggestions? Is there documentation (EMF Compare 2 specific)?

Thanks
-Andrew
Re: UnmatchElement List vs total [message #1059609 is a reply to message #1058283] Mon, 20 May 2013 15:28 Go to previous messageGo to next message
Andrew Whelan is currently offline Andrew Whelan
Messages: 69
Registered: October 2012
Location: Syracuse NY
Member
Actually, ignore my last response. I figured out a way to get at the JUnit tests. Unfortunately I'm having difficulty getting the information I want out of them.

I used to be able to do the following in 1.x:

final MatchModel match = MatchService.doMatch(original,
					fromDatabase, Collections.<String, Object> emptyMap());
EList<UnmatchElement> ueList = match.getUnmatchedElements();


The UnmatchElement had everything I needed including the EObject being reported and whether it was on the LEFT or RIGHT side (source or reference). I need this functionality. How would I do this in EMF Compare 2?

Thanks
Re: UnmatchElement List vs total [message #1059688 is a reply to message #1059609] Tue, 21 May 2013 04:40 Go to previous messageGo to next message
Laurent Goubet is currently offline Laurent Goubet
Messages: 1625
Registered: July 2009
Senior Member
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 Go to previous messageGo to next message
Andrew Whelan is currently offline Andrew Whelan
Messages: 69
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 03:03 Go to previous messageGo to next message
Laurent Goubet is currently offline Laurent Goubet
Messages: 1625
Registered: July 2009
Senior Member
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 #1062075 is a reply to message #1061956] Wed, 05 June 2013 13:32 Go to previous messageGo to next message
Andrew Whelan is currently offline Andrew Whelan
Messages: 69
Registered: October 2012
Location: Syracuse NY
Member
Hi Laurent,

I have a couple of follow up questions. We are using IDs but not every single object has an ID. The higher level objects all do. Will this at least differentiate those that do have IDs?
I am creating my Comparison as follows.

IComparisonScope scope = EMFCompare.createDefaultScope(original,
					fromDatabase);
Comparison comparison = EMFCompare.builder().build().compare(scope);

Then I just start processing matches.

for (Match match : comparison.getMatches()) {
    if(match.getLeft()==null)
      //do something


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?

Also in the example for preventing the use of identifiers


IEObjectMatcher matcher =    DefaultMatchEngine.createDefaultEObjectMatcher(UseIdentifiers.NEVER);

IComparisonFactory comparisonFactory = new DefaultComparisonFactory(new DefaultEqualityHelperFactory());
			
IMatchEngine matchEngine = new DefaultMatchEngine(matcher , comparisonFactory);
			
Comparison comparison = EMFCompare.builder().setMatchEngine(matchEngine).build().compare(scope);


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?

Thanks for all of your help!
Re: UnmatchElement List vs total [message #1063447 is a reply to message #1062075] Thu, 13 June 2013 04:19 Go to previous message
Mikael Barbero is currently offline Mikael Barbero
Messages: 53
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
Previous Topic:[EMF Compare] Exchange ScopeProvider in UI plugin
Next Topic:Customized EMF Comare UI
Goto Forum:
  


Current Time: Fri Aug 22 15:48:20 EDT 2014

Powered by FUDForum. Page generated in 0.10573 seconds