Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 3aa46e75d3f8a5256598f13f936bd6f01591d256 (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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*******************************************************************************
 * Copyright (c) 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 java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.resources.mapping.*;
import org.eclipse.core.runtime.*;
import org.eclipse.team.core.mapping.IResourceMappingScopeManager;
import org.eclipse.team.core.mapping.IResourceMappingScopeParticipantFactory;
import org.eclipse.team.core.mapping.provider.IResourceMappingScopeParticipant;
import org.eclipse.team.core.mapping.provider.ResourceMappingScopeManager;

/**
 * A {@link IResourceMappingScopeManager} that uses a {@link Subscriber} to provide 
 * a {@link RemoteResourceMappingContext} and to notify participants when the
 * remote state of resources change.
 * <p>
 * <strong>EXPERIMENTAL</strong>. This class or interface has been added as
 * part of a work in progress. There is a guarantee neither that this API will
 * work nor that it will remain the same. Please do not use this API without
 * consulting with the Platform/Team team.
 * </p>
 * @since 3.2
 */
public class SubscriberScopeManager extends ResourceMappingScopeManager implements ISubscriberChangeListener {

	private final Subscriber subscriber;
	private Map participants = new HashMap();

	/**
	 * Create a manager for the given subscriber and input.
	 * @param inputMappings the input mappings
	 * @param subscriber the subscriber
	 * @param consultModels whether models should be consulted when calculating the scope
	 */
	public SubscriberScopeManager(ResourceMapping[] inputMappings, Subscriber subscriber, boolean consultModels) {
		this(inputMappings, subscriber, SubscriberResourceMappingContext.createContext(subscriber), consultModels);
	}

	/**
	 * Create a manager for the given subscriber and input.
	 * @param inputMappings the input mappings
	 * @param subscriber the subscriber
	 * @param context a remote resource mapping conext for the subscriber
	 * @param consultModels whether models should be consulted when calculating the scope
	 */
	public SubscriberScopeManager(ResourceMapping[] inputMappings, Subscriber subscriber, RemoteResourceMappingContext context, boolean consultModels) {
		super(inputMappings, context, consultModels);
		this.subscriber = subscriber;
	}

	/**
	 * Return the subscriber for this manager.
	 * @return the subscriber for this manager
	 */
	protected Subscriber getSubscriber() {
		return subscriber;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.core.mapping.IResourceMappingScopeManager#dispose()
	 */
	public void dispose() {
		for (Iterator iter = participants.values().iterator(); iter.hasNext();) {
			IResourceMappingScopeParticipant p = (IResourceMappingScopeParticipant) iter.next();
			p.dispose();
		}
		super.dispose();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.core.mapping.provider.ResourceMappingScopeManager#initialize(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void initialize(IProgressMonitor monitor) throws CoreException {
		ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				SubscriberScopeManager.super.initialize(monitor);
				hookupParticipants();
				getSubscriber().addListener(SubscriberScopeManager.this);
			}
		}, getSchedulingRule(), IResource.NONE, monitor);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.team.core.mapping.provider.ResourceMappingScopeManager#refresh(org.eclipse.core.resources.mapping.ResourceMapping[], org.eclipse.core.runtime.IProgressMonitor)
	 */
	public ResourceTraversal[] refresh(final ResourceMapping[] mappings, IProgressMonitor monitor) throws CoreException {
		final List result = new ArrayList(1);
		ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				result.add(SubscriberScopeManager.super.refresh(mappings, monitor));
				hookupParticipants();
			}
		}, getSchedulingRule(), IResource.NONE, monitor);
		if (result.isEmpty())
			return new ResourceTraversal[0];
		return (ResourceTraversal[])result.get(0);
	}
	
	/*
	 * Hookup the participants for the participating models.
	 * This is done to ensure that future local and remote changes to 
	 * resources will update the resources contained in the scope 
	 * appropriately
	 */
	/* private */ void hookupParticipants() {
		ModelProvider[] providers = getScope().getModelProviders();
		for (int i = 0; i < providers.length; i++) {
			ModelProvider provider = providers[i];
			if (!participants.containsKey(provider)) {
				IResourceMappingScopeParticipant p = createParticipant(provider);
				if (p != null) {
					participants.put(provider, p);
				}
			}
		}
	}
	
	/*
	 * Obtain a participant through the factory which is obtained using IAdaptable
	 */
	private IResourceMappingScopeParticipant createParticipant(ModelProvider provider) {
		Object factoryObject = provider.getAdapter(IResourceMappingScopeParticipantFactory.class);
		if (factoryObject instanceof IResourceMappingScopeParticipantFactory) {
			IResourceMappingScopeParticipantFactory factory = (IResourceMappingScopeParticipantFactory) factoryObject;
			return factory.createParticipant(provider, this);
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.team.core.subscribers.ISubscriberChangeListener#subscriberResourceChanged(org.eclipse.team.core.subscribers.ISubscriberChangeEvent[])
	 */
	public void subscriberResourceChanged(ISubscriberChangeEvent[] deltas) {
		List changedResources = new ArrayList();
		List changedProjects = new ArrayList();
		for (int i = 0; i < deltas.length; i++) {
			ISubscriberChangeEvent event = deltas[i];
			if ((event.getFlags() & (ISubscriberChangeEvent.ROOT_ADDED | ISubscriberChangeEvent.ROOT_REMOVED)) != 0) {
				changedProjects.add(event.getResource().getProject());
			}
			if ((event.getFlags() & ISubscriberChangeEvent.SYNC_CHANGED) != 0) {
				changedResources.add(event.getResource());
			}
		}
		fireChange((IResource[]) changedResources.toArray(new IResource[changedResources.size()]), (IProject[]) changedProjects.toArray(new IProject[changedProjects.size()]));
	}

	private void fireChange(final IResource[] resources, final IProject[] projects) {
		IResourceMappingScopeParticipant[] handlers = (IResourceMappingScopeParticipant[]) participants.values().toArray(new IResourceMappingScopeParticipant[participants.size()]);
		for (int i = 0; i < handlers.length; i++) {
			final IResourceMappingScopeParticipant participant = handlers[i];
			Platform.run(new ISafeRunnable() {
				public void run() throws Exception {
					participant.handleContextChange(SubscriberScopeManager.this, resources, projects);
				}
				public void handleException(Throwable exception) {
					// Handled by platform
				}
			});
		}
	}

}

Back to the top