Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 7ff35bd3f87f75e5244ffde4bdc0e24c5781a81c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation 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:
 *     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.*;
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;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.core.mapping.ISynchronizationContext#refresh(org.eclipse.core.resources.mapping.ResourceTraversal[], int, org.eclipse.core.runtime.IProgressMonitor)
	 */
	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;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.core.mapping.provider.SynchronizationContext#dispose()
	 */
	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
	 */
	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);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class adapter) {
		if (adapter == SubscriberDiffTreeEventHandler.class)
			return handler;
		return super.getAdapter(adapter);
	}

}

Back to the top