blob: c001238dc74d5060cfb446a9d96440d759b32d76 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2022 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Martin Fleck - initial API and implementation
*******************************************************************************/
package org.eclipse.emf.compare.ide.ui.subscriber;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.eclipse.compare.ICompareContainer;
import org.eclipse.compare.ITypedElement;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.core.subscribers.SubscriberMergeContext;
import org.eclipse.team.internal.ui.mapping.ModelCompareEditorInput;
import org.eclipse.team.ui.synchronize.ModelSynchronizeParticipant;
@SuppressWarnings("restriction")
public class TeamSubscriberProvider implements ISubscriberProvider {
public Subscriber getSubscriber(ICompareContainer container, ITypedElement left, ITypedElement right,
ITypedElement origin, IProgressMonitor monitor) {
if (container instanceof ModelCompareEditorInput) {
return getSubscriber((ModelCompareEditorInput)container);
}
return null;
}
/**
* Team left us with absolutely no way to determine whether our supplied input is the result of a
* synchronization or not.
* <p>
* In order to properly resolve the logical model of the resource currently being compared we need to know
* what "other" resources were part of its logical model, and we need to know the revisions of these
* resources we are to load. All of this has already been computed by Team, but it would not let us know.
* This method uses discouraged means to get around this "black box" locking from Team.
* </p>
* <p>
* The basic need here is to retrieve the Subscriber from this point. We have a lot of accessible
* variables, the two most important being the CompareConfiguration and ICompareInput... I could find no
* way around the privileged access to the private ModelCompareEditorInput.participant field. There does
* not seem to be any adapter (or Platform.getAdapterManager().getAdapter(...)) that would allow for this,
* so I'm taking the long way 'round.
* </p>
*
* @return The subscriber used for this comparison if any could be found, <code>null</code> otherwise.
*/
private Subscriber getSubscriber(ModelCompareEditorInput input) {
ModelSynchronizeParticipant participant = getModelSynchronizeParticipant(input);
return participant != null && participant.getContext() instanceof SubscriberMergeContext
? ((SubscriberMergeContext)participant.getContext()).getSubscriber()
: null;
}
private ModelSynchronizeParticipant getModelSynchronizeParticipant(ModelCompareEditorInput modelInput) {
try {
final Field field = ModelCompareEditorInput.class.getDeclaredField("participant"); //$NON-NLS-1$
AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
field.setAccessible(true);
return null;
});
Object participant = field.get(modelInput);
return participant instanceof ModelSynchronizeParticipant
? (ModelSynchronizeParticipant)participant
: null;
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
// Swallow this, this private field was there at least from 3.5 to 4.3
}
return null;
}
}