Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 345415 - Compare action from synchronize view does not make use of ModelProviders
Summary: Compare action from synchronize view does not make use of ModelProviders
Status: CLOSED WONTFIX
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Team (show other bugs)
Version: 4.1   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Platform Team Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-11 09:04 EDT by Laurent Goubet CLA
Modified: 2020-08-06 01:46 EDT (History)
3 users (show)

See Also:


Attachments
Model provider lookup from synchronize view (1.71 KB, patch)
2012-10-31 06:41 EDT, Laurent Goubet CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Laurent Goubet CLA 2011-05-11 09:04:29 EDT
I don't really know if this is a CVS issue, or a more generic platform/Compare problem. Here is the gist of it :

I have two files "A" and "B" which are part of the same logical resource. Thus, "A" cannot be compared alone, and neither can "B". Comparing either one of them should open the synchronize perspective and show the synchronization state of both. That, I can do.

Basically, I have defined my own model provider through the org.eclipse.core.resources.modelProviders extension point. Its enablement value looks like this :
<enablement>
  <and>
    <adapt type="org.eclipse.core.resources.IFile"/>
    <test
           property="contentTypeId"
           value="my.content.type.id">
    </test>
  </and>
</enablement>

So it applies on elements that can be adapted to "IFile" and which have a set content type (both "A" and "B" have that content type). With this, calling the action "right click on "A" > Compare With > Latest From HEAD" forces me to open the synchronize view, and this view displays both of my files for comparison. So far, so good. (for the record, my model provider then is called from "org.eclipse.team.internal.ccvs.ui.actions.SyncAction#isOKToShowSingleFile()")

However, if I right-click either one of the files in the synchronize view, and use the action "Open In Compare Editor" (or if I simply double clic the files), my model provider is _not_ called ... and thus the compare editor that gets open is opened on a single file instead of being opened on my ResourceMapping.

Trying to track down why, it turns out that
  org.eclipse.team.internal.ui.synchronize.actions.OpenInCompareAction()
calls
  ModelSynchronizeParticipant msp = (ModelSynchronizeParticipant) participant;
  ICompareInput input = msp.asCompareInput(object);
this "asCompareInput" implementation correctly tries to find the compare adapter corresponding to the given object (the IFile "A" in this case) :
  Utils.getCompareAdapter(object)
Which in turn calls
  org.eclipse.team.internal.ui.Utils.getModelProvider(Object)
in order to determine the proper ModelProvider for that IFile.

However, this implementation of "getModelProvider" adapts the IFile into a ResourceMapping directly (o.getAdapter(ResourceMapping.class)) to retrieve the corresponding model provider (mapping.getModelProvider()). And there lies the problem : the platform already defines an adapter factory in order to adapt IFile into ResourceMapping. A third party plugin cannot override this adapter factory safely (there are simply too many things that rely on this adaptation, and an adapter factory cannot be provided with an "enablement" condition). As such, the "ModelProvider" that gets used for the "open in compare editor" action is _always_ the "Workspace model provider", and the corresponding implementation of "asCompareInput", "org.eclipse.team.internal.ui.mapping.ResourceModelPersistenceAdapter#asCompareInput".

This feels like a half-provided API : third party plugins are allowed to make files part of a logical model spanning more than one file ... but they cannot make it so that these files cannot be compared alone. As I see it, the implementation of "org.eclipse.team.internal.ui.Utils.getModelProvider(Object)" is too restrictive (adapting directly to ResourceMapping) and should instead make use of "ModelProvider#getMatchingResources()" if the "object" passed as parameter can be adapted to IResource.

I have used something like this successfuly without notable problems (though I haven't tested much, this is only meant to give you an idea of where the problem is. I can transform this into a patch if you'd rather) :

public static ModelProvider getModelProvider(Object o) {
  if (o instanceof ModelProvider) {
    return (ModelProvider)o;
  }

  // FORK Starts here
  // Can "o" be adapted to an IResource?
  IResource resource = getResource(o);
  if (resource != null) {
    IModelProviderDescriptor[] descriptors = ModelProvider.getModelProviderDescriptors();
    for (int i = 0; i < descriptors.length; i++) {
      IModelProviderDescriptor descriptor = descriptors[i];
      try {
        IResource[] resources = descriptor.getMatchingResources(new IResource[] {resource});
        if (resources.length > 0) {
          return descriptor.getModelProvider();
        }
      } catch (CoreException e) {
        TeamUIPlugin.log(e);
      }
    }
  }
  // FORK Ends here

  ResourceMapping mapping = getResourceMapping(o);
  if (mapping != null) {
    return mapping.getModelProvider();
  }
  return null;
}
Comment 1 Laurent Goubet CLA 2012-04-17 09:44:41 EDT
Hi,

This bug still holds true for 4.2M5 and the fork remains necessary. Any news on this?
Comment 2 Laurent Goubet CLA 2012-04-17 09:49:15 EDT
Adding team inbox in the cc list of this bug since it seems more like a bug on their side (org.eclipse.team.internal.ui.Utils is the class at fault).
Comment 3 Laurent Goubet CLA 2012-10-31 06:41:48 EDT
Created attachment 223032 [details]
Model provider lookup from synchronize view

This bug was initially created against CVS, but is also observed when using EGit as the backend repository. Reaffecting to Team.

The attached patch includes the necessary change to properly look up the model providers when comparing from the synchronize view.
Comment 4 Eclipse Genie CLA 2020-08-06 01:46:22 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.