blob: e133455e1c04dd7d6aa69f85f0cb35726710e9d7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.team.core.subscribers;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ProgressMonitorWrapper;
import org.eclipse.team.core.diff.DiffFilter;
import org.eclipse.team.core.mapping.ISynchronizationScopeManager;
import org.eclipse.team.core.mapping.provider.MergeContext;
import org.eclipse.team.core.mapping.provider.ResourceDiffTree;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.internal.core.mapping.GroupProgressMonitor;
import org.eclipse.team.internal.core.subscribers.SubscriberDiffTreeEventHandler;
/**
* A merge context that uses a subscriber to populate the diff tree
* used by the context. The population of the diff tree is performed
* by a handler that runs in a background job.
*
* @see Subscriber
* @see MergeContext
*
* @since 3.2
*/
public abstract class SubscriberMergeContext extends MergeContext {
private Subscriber subscriber;
private SubscriberDiffTreeEventHandler handler;
private final ISynchronizationScopeManager manager;
/**
* Create a merge context for the given subscriber
* @param subscriber the subscriber
* @param manager the scope manager
*/
protected SubscriberMergeContext(Subscriber subscriber, ISynchronizationScopeManager manager) {
super(manager, getType(subscriber), new ResourceDiffTree());
this.subscriber = subscriber;
this.manager = manager;
}
private static int getType(Subscriber subscriber) {
return subscriber.getResourceComparator().isThreeWay()
? THREE_WAY : TWO_WAY;
}
/**
* Initialize the diff tree of this context. This method must
* be called before the context is given to clients.
*/
protected void initialize() {
handler = new SubscriberDiffTreeEventHandler(subscriber, manager, (ResourceDiffTree)getDiffTree(), getDiffFilter());
handler.setJobFamily(this);
handler.start();
}
/**
* Return the diff filter used to filter the differences that the merge context will present to clients.
* @return the diff filter used to filter the differences that the merge context will present to clients
* @since 3.3
*/
protected DiffFilter getDiffFilter() {
return null;
}
@Override
public void refresh(ResourceTraversal[] traversals, int flags,
IProgressMonitor monitor) throws CoreException {
GroupProgressMonitor group = getGroup(monitor);
if (group != null)
handler.setProgressGroupHint(group.getGroup(), group.getTicks());
handler.initializeIfNeeded();
subscriber.refresh(traversals, monitor);
}
private GroupProgressMonitor getGroup(IProgressMonitor monitor) {
if (monitor instanceof GroupProgressMonitor) {
return (GroupProgressMonitor) monitor;
}
if (monitor instanceof ProgressMonitorWrapper) {
ProgressMonitorWrapper wrapper = (ProgressMonitorWrapper) monitor;
return getGroup(wrapper.getWrappedProgressMonitor());
}
return null;
}
@Override
public void dispose() {
handler.shutdown();
super.dispose();
}
/**
* Return the sync info for the given resource.
* @param resource the resource
* @return the sync info for the resource obtained from the subscriber
* @throws CoreException if an error occurs
*/
protected SyncInfo getSyncInfo(IResource resource) throws CoreException {
return handler.getSubscriber().getSyncInfo(resource);
}
/**
* Return the subscriber associated with this context.
* @return the subscriber associated with this context
*/
public Subscriber getSubscriber() {
return subscriber;
}
/**
* Run the given runnable when the background handler
* for this context is idle. The given runnable should not lock
* the workspace.
* @param runnable the runnable
*/
protected void runInBackground(IWorkspaceRunnable runnable) {
handler.run(runnable, false);
}
@Override
@SuppressWarnings("unchecked")
public <T> T getAdapter(Class<T> adapter) {
if (adapter == SubscriberDiffTreeEventHandler.class)
return (T) handler;
return super.getAdapter(adapter);
}
}