Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Compare » Left and Right panels disposed during conflict resolution
Left and Right panels disposed during conflict resolution [message #1751745] Fri, 13 January 2017 12:03 Go to next message
Vlad Acretoaie is currently offline Vlad AcretoaieFriend
Messages: 93
Registered: April 2014
Member
Hi,

I am using EMF Compare for conflict resolution in an EMF-based modeling tool I am developing.

Occasionally, when I accept a change (either local or remote), the two panels (widgets) containing the Left and Right sides of the next conflict are disposed.

Because of this, I get an IllegalStateException when resolving the next conflict. The detailed error message is "Need an underlying widget to be able to set the input.(Has the widget been disposed?)"

The conflicts I am resolving do not involve any unusual model elements, they are just conflicting changes on String and Float attributes.

Can anyone suggest a possible cause for this behavior?

Thank you in advance!

Vlad

Re: Left and Right panels disposed during conflict resolution [message #1751767 is a reply to message #1751745] Fri, 13 January 2017 15:48 Go to previous messageGo to next message
Laurent Goubet is currently offline Laurent GoubetFriend
Messages: 1857
Registered: July 2009
Senior Member
Hi Vlad,

We have never experienced such a behavior as far as I know. Is there any chance you could provide us (preferrably through bugzilla) with ways to reproduce this?

Laurent Goubet
Obeo
Re: Left and Right panels disposed during conflict resolution [message #1751894 is a reply to message #1751767] Mon, 16 January 2017 15:19 Go to previous messageGo to next message
Vlad Acretoaie is currently offline Vlad AcretoaieFriend
Messages: 93
Registered: April 2014
Member
Hi Laurent,

Thank you for your answer.

The fact that you never experienced this before made me look into some UI customizations I made to the Compare Editor.
I was able to trace the exception to a customization I made in order to change the labels of the left and tight panels (I don't want these panels to display the model file path, as they do by default).

My solution for changing these labels is to override the getViewer() method of the CompareContentViewerSwitchingPane class. Here is the code for my getViewer() method:

  @Override
  protected Viewer getViewer(Viewer oldViewer, Object input) {
    if (fSelectedViewerDescriptor != null) {
      ViewerDescriptor[] array = CompareUIPlugin.getDefault().findContentViewerDescriptor(oldViewer, input, getCompareConfiguration());
      List<?> list = array != null ? Arrays.asList(array) : Collections.EMPTY_LIST;
      if (list.contains(fSelectedViewerDescriptor)) {
        // use selected viewer only when appropriate for the new input
        fCompareEditorInput.setContentViewerDescriptor(fSelectedViewerDescriptor);
        Viewer viewer = fCompareEditorInput.findContentViewer(oldViewer, (ICompareInput) input, this);
        return viewer;
      }
      // fallback to default otherwise
      fSelectedViewerDescriptor = null;
    }
    if (input instanceof ICompareInput) {
      // We use our own label provider for the TreeNodeCompareInput
      if (input instanceof TreeNodeCompareInput) {
        EMFCompareConfiguration emfConfig = new EMFCompareConfiguration(getCompareConfiguration());
        emfConfig.setLabelProvider(TreeNodeCompareInput.class, new TreeNodeCompareInputLabelProvider() {
          @Override
          public String getLeftLabel(@SuppressWarnings("hiding") Object input) {
            return CollaborationHelper.LEFT_LABEL;
          }

          @Override
          public String getRightLabel(@SuppressWarnings("hiding") Object input) {
            return CollaborationHelper.RIGHT_LABEL;
          }

          @Override
          public String getAncestorLabel(@SuppressWarnings("hiding") Object input) {
            return CollaborationHelper.ANCESTOR_LABEL;
          }
        });

        fCompareEditorInput.setContentViewerDescriptor(null);
        Viewer viewer = fCompareEditorInput.findContentViewer(oldViewer, (ICompareInput) input, this);

        if (viewer instanceof EMFCompareTextMergeViewer) {
          EMFCompareTextMergeViewer textMergeViewer = (EMFCompareTextMergeViewer) viewer;
          textMergeViewer.setContentProvider(new EMFCompareTextMergeViewerContentProvider(emfConfig));
          fCompareEditorInput.setContentViewerDescriptor(fSelectedViewerDescriptor);
          return textMergeViewer;
        } else if (viewer instanceof TreeContentMergeViewer) {
          TreeContentMergeViewer treeMergeViewer = (TreeContentMergeViewer) viewer;
          treeMergeViewer.setContentProvider(new TreeContentMergeViewerContentProvider(emfConfig));
          fCompareEditorInput.setContentViewerDescriptor(fSelectedViewerDescriptor);
          return treeMergeViewer;
        } else if (viewer instanceof TableContentMergeViewer) {
          TableContentMergeViewer tableMergeViewer = (TableContentMergeViewer) viewer;
          tableMergeViewer.setContentProvider(new TableContentMergeViewerContentProvider(emfConfig));
          fCompareEditorInput.setContentViewerDescriptor(fSelectedViewerDescriptor);
          return tableMergeViewer;
        } else { // if the viewer type is unknown, just use the default configuration
          fCompareEditorInput.setContentViewerDescriptor(fSelectedViewerDescriptor);
          return viewer;
        }

      }

      // For other types of inputs, we do not define our own label provider
      fCompareEditorInput.setContentViewerDescriptor(null);
      Viewer viewer = fCompareEditorInput.findContentViewer(oldViewer, (ICompareInput) input, this);
      fCompareEditorInput.setContentViewerDescriptor(fSelectedViewerDescriptor);
      return viewer;
    }
    return null;
  }


This is a rather cumbersome way to customize those labels, but it is the only solution that works in my case (I also asked about this in another thread https://www.eclipse.org/forums/index.php/m/1746586/#msg_1746586).

The getViewer() method seems to be executed as expected, but the widget is disposed somewhere later in the call stack in case my getViewer() method returns a TableContentMergeViewer.

I guess I should go back to looking for other methods to customize those labels, which apparently is more difficult than I was hoping.

Cheers,
Vlad
Re: Left and Right panels disposed during conflict resolution [message #1751959 is a reply to message #1751894] Tue, 17 January 2017 08:51 Go to previous messageGo to next message
Laurent Goubet is currently offline Laurent GoubetFriend
Messages: 1857
Registered: July 2009
Senior Member
Hi Vlad,

Another approach might be for you to look on how to patch EMF Compare to make this customizable instead of what we're doing today (something like making sure the configuration's labels are preserved instead of ditched?) and raise a bugzilla with the explanation and patch (preferrably submitted through gerrit). We'll gladly look at such contributions and it might end faster for you to ask for the proper APIs instead of working around the limitations. For this one I don't really foresee a problem in opening such an API as long as the "default" behavior is respected when no one modifies the labels.

Laurent Goubet
Obeo
Re: Left and Right panels disposed during conflict resolution [message #1752049 is a reply to message #1751959] Wed, 18 January 2017 10:17 Go to previous messageGo to next message
Vlad Acretoaie is currently offline Vlad AcretoaieFriend
Messages: 93
Registered: April 2014
Member
Hi Laurent,

Thank you for your answer. I eventually solved the problem by using a different method to customize the labels. I followed Philip Langer's suggestion (https://www.eclipse.org/forums/index.php?t=msg&th=1082189&goto=1746632&#msg_1746632) to add a storage path adapter to the left/right/origin resources of the comparison scope.

My revised code for the getViewer() method looks like this, in case anyone else finds it useful:

  @Override
  protected Viewer getViewer(Viewer oldViewer, Object input) {
    if (fSelectedViewerDescriptor != null) {
      ViewerDescriptor[] array = CompareUIPlugin.getDefault().findContentViewerDescriptor(oldViewer, input, getCompareConfiguration());
      List<?> list = array != null ? Arrays.asList(array) : Collections.EMPTY_LIST;
      if (list.contains(fSelectedViewerDescriptor)) {
        // use selected viewer only when appropriate for the new input
        fCompareEditorInput.setContentViewerDescriptor(fSelectedViewerDescriptor);
        Viewer viewer = fCompareEditorInput.findContentViewer(oldViewer, (ICompareInput) input, this);
        return viewer;
      }
      // fallback to default otherwise
      fSelectedViewerDescriptor = null;
    }
    if (input instanceof ICompareInput) {
      // Customize left and right panel labels
      Match match = getMatch(getTreeNode(input));
      if (match != null) {
        setResourceStoragePath(match.getLeft().eResource(), CollaborationHelper.LEFT_LABEL, true);
        setResourceStoragePath(match.getRight().eResource(), CollaborationHelper.RIGHT_LABEL, false);
      }

      fCompareEditorInput.setContentViewerDescriptor(null);
      Viewer viewer = fCompareEditorInput.findContentViewer(oldViewer, (ICompareInput) input, this);
      fCompareEditorInput.setContentViewerDescriptor(fSelectedViewerDescriptor);
      return viewer;
    }
    return null;
  }

  /**
   * Set the storage path adapter of a resource.
   * The storage path adapter is part of the label used for the resource in the Compare Editor left/right/ancestor panes.
   * 
   * @param resource an EMF resource
   * @param storagePath the storage path to be assigned to the new storage path adapter
   * @param isLocal true if the storage path is local, false otherwise
   */
  private void setResourceStoragePath(Resource resource, String storagePath, boolean isLocal) {
    EList<Adapter> eAdapters = resource.eAdapters();
    ArrayList<Adapter> adaptersToRemove = new ArrayList<>();
    for (Adapter adapter : eAdapters) {
      if (adapter instanceof StoragePathAdapter) {
        adaptersToRemove.add(adapter);
      }
    }
    eAdapters.removeAll(adaptersToRemove);
    eAdapters.add(new StoragePathAdapter(storagePath, isLocal));
  }


However, this doesn't look like a really generic fix to the problem, so I don't think submitting a patch would be appropriate here. I also don't really know what a generic fix could be (my understanding of EMF Compare is still rather superficial).

Cheers,
Vlad
Re: Left and Right panels disposed during conflict resolution [message #1752258 is a reply to message #1752049] Fri, 20 January 2017 11:03 Go to previous message
Laurent Goubet is currently offline Laurent GoubetFriend
Messages: 1857
Registered: July 2009
Senior Member
Thanks for the follow-up vlad, hopefully this will be useful for others.
Previous Topic:New UUIDs for non-conflicting Addition changes after merge
Next Topic:Merging file deletions in multi-file model
Goto Forum:
  


Current Time: Sun Jul 15 19:12:07 GMT 2018

Powered by FUDForum. Page generated in 0.01892 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top