Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: bf7c77fce65bb5f9e12a8732060d188cac86303e (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
/*******************************************************************************
 * Copyright (c) 2000, 2006 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.internal.ccvs.core.syncinfo;

import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer;
import org.eclipse.team.internal.core.BackgroundEventHandler;

/**
 * This class handles resources changes that are reported in deltas
 * in a deferred manner (i.e. in a background job)
 */
public class DeferredResourceChangeHandler extends BackgroundEventHandler {

	public DeferredResourceChangeHandler() {
		super(CVSMessages.DeferredResourceChangeHandler_0, CVSMessages.DeferredResourceChangeHandler_1);
	}

	private static final int IGNORE_FILE_CHANGED = 1;
	private static final int RECREATED_CVS_RESOURCE = 2;
	private static final int CONFLICTING_DELETION =3;
	
	private Set changedIgnoreFiles = new HashSet();
	private Set recreatedResources = new HashSet();
	private Set conflictingDeletion = new HashSet();

	@Override
	protected void processEvent(Event event, IProgressMonitor monitor) throws TeamException {
		int type = event.getType();
		switch (type) {
			case IGNORE_FILE_CHANGED :
				changedIgnoreFiles.add(event.getResource());
				break;
			case RECREATED_CVS_RESOURCE :
				recreatedResources.add(event.getResource());
				break;
			case CONFLICTING_DELETION :
				conflictingDeletion.add(event.getResource());
				break;
		}				
	}
	
	private IContainer[] getParents(Set files) {
		Set parents = new HashSet();
		for (Iterator iter = files.iterator(); iter.hasNext();) {
			IFile file = (IFile) iter.next();
			parents.add(file.getParent());
		}
		return (IContainer[]) parents.toArray(new IContainer[parents.size()]);
	}

	public void ignoreFileChanged(IFile file) {
		if (isSharedWithCVS(file))
			queueEvent(new ResourceEvent(file, IGNORE_FILE_CHANGED, IResource.DEPTH_ZERO), false);
	}
	
	/**
	 * The resource has been added and has sync info that has not been written to disk. 
	 * Queue an event to ensure that the CVS directory files
	 * are written to disk.
	 * @param resource the recently add resource
	 */
	public void recreated(IResource resource) {
		if (isSharedWithCVS(resource))
			queueEvent(new ResourceEvent(resource, RECREATED_CVS_RESOURCE, IResource.DEPTH_ZERO), false);
	}
	
	@Override
	protected boolean doDispatchEvents(IProgressMonitor monitor) {
		// Handle ignore file changes
		boolean workDone = !changedIgnoreFiles.isEmpty() || !recreatedResources.isEmpty();
		try {
			EclipseSynchronizer.getInstance().ignoreFilesChanged(getParents(changedIgnoreFiles));
		} catch (CVSException e) {
			// Log and continue
			CVSProviderPlugin.log(e);
		}
		changedIgnoreFiles.clear();
		// Handle recreations by project to reduce locking granularity
		Map recreations = getResourcesByProject((IResource[]) recreatedResources.toArray(new IResource[recreatedResources.size()]));
		recreatedResources.clear();
		for (Iterator iter = recreations.values().iterator(); iter.hasNext();) {
			List resources = (List) iter.next();
			try {
				EclipseSynchronizer.getInstance().resourcesRecreated((IResource[]) resources.toArray(new IResource[resources.size()]), monitor);
			} catch (CVSException e) {
				// Log and continue
				CVSProviderPlugin.log(e);
			}
		}
		IResource[] deletions = (IResource[]) conflictingDeletion.toArray(new IResource[conflictingDeletion.size()]);
		conflictingDeletion.clear();
		for (IResource resource : deletions) {
			ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
			try {
				if(!cvsResource.isFolder() && cvsResource.isManaged()) {
					cvsResource.unmanage(monitor);
				}
			} catch (CVSException e) {
				// Log and continue
				CVSProviderPlugin.log(e);
			}
		}
		return workDone;
	}
	
	private Map getResourcesByProject(IResource[] resources) {
		Map result = new HashMap();
		for (IResource resource : resources) {
			IProject project = resource.getProject();
			List projectResources = (List)result.get(project);
			if (projectResources == null) {
				projectResources = new ArrayList();
				result.put(project, projectResources);
			}
			projectResources.add(resource);
		}
		return result;
	}

	public void handleConflictingDeletion(IResource local) {
		if (isSharedWithCVS(local))
			queueEvent(new ResourceEvent(local, CONFLICTING_DELETION, IResource.DEPTH_ZERO), false);
	}
	
	private boolean isSharedWithCVS(IResource resource) {
		return CVSTeamProvider.isSharedWithCVS(resource.getProject());
	}

	protected Object getJobFamiliy() {
		return this;
	}

}

Back to the top