blob: 3249352de876a965496906f41d0a841327d029f7 [file] [log] [blame]
/*******************************************************************************
* 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.internal.ccvs.core.util;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.ICVSRunnable;
import org.eclipse.team.internal.ccvs.core.Policy;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.resources.EclipseSynchronizer;
/**
* Cleanup any CVS folders that were copied by a builder. This will also clean up
* CVS folders that were copied by the user since the last auto-build.
*/
public class BuildCleanupListener implements IResourceDeltaVisitor, IResourceChangeListener {
public static IResource getResourceFor(IProject container, IResource destination, IPath originating) {
switch(destination.getType()) {
case IResource.FILE : return container.getFile(originating);
case IResource.FOLDER: return container.getFolder(originating);
case IResource.PROJECT: return ResourcesPlugin.getWorkspace().getRoot().getProject(originating.toString());
}
return destination;
}
/**
* @see IResourceDeltaVisitor#visit(IResourceDelta)
*/
public boolean visit(IResourceDelta delta) throws CoreException {
IResource resource = delta.getResource();
boolean movedFrom = (delta.getFlags() & IResourceDelta.MOVED_FROM) > 0;
switch (delta.getKind()) {
case IResourceDelta.ADDED :
// make sure the added resource isn't a phantom
if (resource.exists()) {
if (EclipseSynchronizer.getInstance().wasPhantom(resource)) {
EclipseSynchronizer.getInstance().resourcesRecreated(new IResource[] { resource }, null);
}
if (resource.getType() == IResource.FOLDER) {
if (resource.getName().equals(SyncFileWriter.CVS_DIRNAME)) {
handleOrphanedSubtree(resource.getParent());
} else {
handleOrphanedSubtree((IContainer)resource);
}
}
}
break;
case IResourceDelta.CHANGED :
// This state means there is a resource before and after but changes were made by deleting and moving.
// For files, we shouldn'd do anything.
// For folders, we should purge the CVS info
if (movedFrom && resource.getType() == IResource.FOLDER && resource.exists()) {
// When folders are moved, purge the CVS folders
return ! handleOrphanedSubtree((IContainer)resource);
}
break;
}
return true;
}
/*
* Determine if the container is an orphaned subtree.
* If it is, handle it and return true.
* Otherwise, return false
*/
private boolean handleOrphanedSubtree(IContainer container) {
try {
if (CVSWorkspaceRoot.isOrphanedSubtree(container)) {
ICVSFolder mFolder = CVSWorkspaceRoot.getCVSFolderFor(container);
mFolder.unmanage(null);
return true;
}
} catch (CVSException e) {
CVSProviderPlugin.log(e);
}
return false;
}
public void resourceChanged(IResourceChangeEvent event) {
try {
IResourceDelta root = event.getDelta();
IResourceDelta[] projectDeltas = root.getAffectedChildren();
for (int i = 0; i < projectDeltas.length; i++) {
final IResourceDelta delta = projectDeltas[i];
IResource resource = delta.getResource();
if (resource.getType() == IResource.PROJECT) {
// If the project is not accessible, don't process it
if (!resource.isAccessible()) continue;
}
RepositoryProvider provider = RepositoryProvider.getProvider(resource.getProject(), CVSProviderPlugin.getTypeId());
// Make sure that the project is a CVS folder.
ICVSFolder folder = CVSWorkspaceRoot.getCVSFolderFor(resource.getProject());
if (provider != null) {
try {
if (! folder.isCVSFolder()) {
RepositoryProvider.unmap(resource.getProject());
provider = null;
}
} catch (TeamException e) {
CVSProviderPlugin.log(e);
}
}
// if a project is moved the originating project will not be associated with the CVS provider
// however listeners will probably still be interested in the move delta.
if ((delta.getFlags() & IResourceDelta.MOVED_TO) > 0) {
IResource destination = getResourceFor(resource.getProject(), resource, delta.getMovedToPath());
provider = RepositoryProvider.getProvider(destination.getProject());
}
if(provider!=null) {
// Traverse the delta is a runnable so that files are only written at the end
folder.run(new ICVSRunnable() {
public void run(IProgressMonitor monitor) throws CVSException {
try {
delta.accept(BuildCleanupListener.this);
} catch (CoreException e) {
Util.logError(CVSMessages.ResourceDeltaVisitor_visitError, e);
}
}
}, Policy.monitorFor(null));
}
}
} catch (CVSException e) {
Util.logError(CVSMessages.ResourceDeltaVisitor_visitError, e);
}
}
}