blob: f412764ac795585b8329a55467994ed6a864eabb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.team.internal.ccvs.core.resources;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.ccvs.core.CVSException;
import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.CVSTag;
import org.eclipse.team.internal.ccvs.core.ICVSFile;
import org.eclipse.team.internal.ccvs.core.ICVSFolder;
import org.eclipse.team.internal.ccvs.core.ICVSResource;
import org.eclipse.team.internal.ccvs.core.Policy;
import org.eclipse.team.internal.ccvs.core.client.Command;
import org.eclipse.team.internal.ccvs.core.client.Session;
import org.eclipse.team.internal.ccvs.core.client.Update;
import org.eclipse.team.internal.ccvs.core.client.Command.LocalOption;
import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
/**
* This class can be used to fetch and cache file contents for remote files.
*/
public class FileContentCachingService {
String[] fileDiffs;
private CVSRepositoryLocation repository;
private ICVSFolder remoteRoot;
public static RemoteFolderTree buildRemoteTree(CVSRepositoryLocation repository, ICVSFolder root, CVSTag tag, IProgressMonitor monitor) throws CVSException {
monitor.beginTask(null, 100);
try {
RemoteFolderTreeBuilder builder = new RemoteFolderTreeBuilder(repository, root, tag);
RemoteFolderTree tree = builder.buildTree(new ICVSResource[] { root }, Policy.subMonitorFor(monitor, 50));
FileContentCachingService service = new FileContentCachingService(repository, tree, builder.getFileDiffs());
service.cacheFileContents(Policy.subMonitorFor(monitor, 50));
return tree;
} finally {
monitor.done();
}
}
/**
* Fetch and cache the file contents for the specified files.
* @param root the root folder for the files being fetched
* @param filePaths the root relative file paths
* @param monitor
* @throws CVSException
*/
public static void fetchFileContents(RemoteFolderTree root, String[] filePaths, IProgressMonitor monitor) throws CVSException {
FileContentCachingService service = new FileContentCachingService((CVSRepositoryLocation)root.getRepository(), root, filePaths);
service.cacheFileContents(monitor);
}
public static RemoteFile buildRemoteTree(CVSRepositoryLocation repository, ICVSFile file, CVSTag tag, IProgressMonitor monitor) throws CVSException {
monitor.beginTask(null, 100);
try {
RemoteFolderTreeBuilder builder = new RemoteFolderTreeBuilder(repository, file.getParent(), tag);
RemoteFile remote = builder.buildTree(file, monitor);
if (builder.getFileDiffs().length > 0) {
// Getting the storage of the file will cache the contents
remote.getStorage(Policy.subMonitorFor(monitor, 50));
}
return remote;
} catch (TeamException e) {
throw CVSException.wrapException(e);
} finally {
monitor.done();
}
}
public FileContentCachingService(CVSRepositoryLocation repository, RemoteFolderTree tree, String[] fileDiffs) {
this.repository = repository;
this.remoteRoot = tree;
this.fileDiffs = fileDiffs;
}
private void cacheFileContents(IProgressMonitor monitor) throws CVSException {
String[] files = getUncachedFiles();
if (files.length == 0) return;
// Fetch the file contents for all out-of-sync files by running an update
// on the remote tree passing the known changed files as arguments
monitor.beginTask(null, 10 + files.length * 100);
Policy.checkCanceled(monitor);
Session session = new Session(repository, remoteRoot, false);
session.open(Policy.subMonitorFor(monitor, 10), false /* read-only */);
try {
Policy.checkCanceled(monitor);
IStatus status = Command.UPDATE.execute(session,
Command.NO_GLOBAL_OPTIONS,
new LocalOption[] { Update.IGNORE_LOCAL_CHANGES },
files,
null,
Policy.subMonitorFor(monitor, files.length * 100));
if (!status.isOK()) {
// No big deal but log the problem anyway
CVSProviderPlugin.log (new CVSException(status));
}
} finally {
session.close();
monitor.done();
}
}
/*
* Only return those file in the diff list that exist remotely and whose contents are not already cached
*/
private String[] getUncachedFiles() {
if (fileDiffs.length == 0) return fileDiffs;
List existing = new ArrayList();
for (int i = 0; i < fileDiffs.length; i++) {
String filePath = fileDiffs[i];
try {
ICVSFile file = remoteRoot.getFile(filePath);
if (file instanceof RemoteFile) {
if (!((RemoteFile)file).isContentsCached()) {
existing.add(filePath);
}
}
} catch (CVSException e) {
// The child does not exists so exclude it
}
}
return (String[]) existing.toArray(new String[existing.size()]);
}
}