blob: a87356a78485b7b393e76f1cca56f8899e78e5db [file] [log] [blame]
/*******************************************************************************
* 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.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.variants.PersistantResourceVariantByteStore;
import org.eclipse.team.core.variants.ResourceVariantByteStore;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.core.subscribers.DescendantResourceVariantByteStore;
/**
* CVS sycnrhonization cache that ignores stale remote bytes
*/
public class CVSDescendantResourceVariantByteStore extends DescendantResourceVariantByteStore {
public CVSDescendantResourceVariantByteStore(ResourceVariantByteStore baseCache, PersistantResourceVariantByteStore remoteCache) {
super(baseCache, remoteCache);
}
@Override
protected boolean isDescendant(IResource resource, byte[] baseBytes, byte[] remoteBytes) throws TeamException {
if (resource.getType() != IResource.FILE) return true;
try {
return ResourceSyncInfo.isLaterRevisionOnSameBranch(remoteBytes, baseBytes);
} catch (CVSException e) {
throw TeamException.asTeamException(e);
}
}
@Override
public boolean setBytes(IResource resource, byte[] bytes) throws TeamException {
boolean changed = super.setBytes(resource, bytes);
if (resource.getType() == IResource.FILE && getBytes(resource) != null && !parentHasSyncBytes(resource)) {
// Log a warning if there is no sync bytes available for the resource's
// parent but there is valid sync bytes for the child
CVSProviderPlugin.log(new TeamException(NLS.bind(CVSMessages.ResourceSynchronizer_missingParentBytesOnSet, new String[] { ((PersistantResourceVariantByteStore)getRemoteStore()).getSyncName().toString(), resource.getFullPath().toString() })));
}
return changed;
}
/**
* Indicates whether the parent of the given local resource has sync bytes for its
* corresponding remote resource. The parent bytes of a remote resource are required
* (by CVS) to create a handle to the remote resource.
*/
protected boolean parentHasSyncBytes(IResource resource) throws TeamException {
if (resource.getType() == IResource.PROJECT) return true;
return (getBytes(resource.getParent()) != null);
}
@Override
public boolean isVariantKnown(IResource resource) throws TeamException {
return ((PersistantResourceVariantByteStore)getRemoteStore()).isVariantKnown(resource);
}
/*
* TODO: Could possibly be generalized and moved up
*/
public IStatus handleResourceChanges(IResource[] changedResources, boolean canModifyWorkspace) {
// IMPORTANT NOTE: This will throw exceptions if performed during the POST_CHANGE delta phase!!!
List errors = new ArrayList();
for (IResource resource : changedResources) {
try {
if (!isInCVSProject(resource)) continue;
if (resource.getType() == IResource.FILE
&& (resource.exists() || resource.isPhantom())) {
byte[] remoteBytes = getBytes(resource);
if (remoteBytes == null) {
if (isVariantKnown(resource)) {
// The remote is known not to exist. If the local resource is
// managed then this information is stale
if (getBaseStore().getBytes(resource) != null) {
if (canModifyWorkspace) {
flushBytes(resource, IResource.DEPTH_ZERO);
} else {
// The revision comparison will handle the stale sync bytes
// TODO: Unless the remote is known not to exist (see bug 52936)
}
}
}
} else {
byte[] localBytes = getBaseStore().getBytes(resource);
if (localBytes == null || !isDescendant(resource, localBytes, remoteBytes)) {
if (canModifyWorkspace) {
flushBytes(resource, IResource.DEPTH_ZERO);
} else {
// The remote byte store handles the stale sync bytes
}
}
}
} else if (resource.getType() == IResource.FOLDER) {
// If the base has sync info for the folder, purge the remote bytes
if (getBaseStore().getBytes(resource) != null && canModifyWorkspace) {
flushBytes(resource, IResource.DEPTH_ZERO);
}
}
} catch (TeamException e) {
errors.add(e);
}
}
for (Iterator iter = errors.iterator(); iter.hasNext();) {
TeamException e = (TeamException) iter.next();
CVSProviderPlugin.log(e);
}
return Status.OK_STATUS; // TODO
}
private boolean isInCVSProject(IResource resource) {
return RepositoryProvider.getProvider(resource.getProject(), CVSProviderPlugin.getTypeId()) != null;
}
}