blob: df4b39a0974eac6da0f0b7d78ff19565a2a30a46 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 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.ui.operations;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.client.listeners.LogEntry;
import org.eclipse.team.internal.ccvs.core.client.listeners.LogListener;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFile;
import org.eclipse.team.internal.ccvs.core.resources.RemoteFolderTree;
import org.eclipse.team.internal.ccvs.ui.CVSUIMessages;
import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
import org.eclipse.team.internal.ccvs.ui.model.RemoteContentProvider;
import org.eclipse.team.internal.ccvs.ui.operations.RemoteLogOperation.LogEntryCache;
import org.eclipse.team.internal.ccvs.ui.repo.RepositoriesView;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.ui.IWorkbenchPart;
public class FetchAllMembersOperation extends RemoteOperation {
class RLogTreeBuilder {
private ICVSRepositoryLocation location;
private RemoteFolderTree tree;
private CVSTag tag;
public RLogTreeBuilder(ICVSRepositoryLocation location, CVSTag tag) {
this.tag = tag;
this.location = location;
reset();
}
public RemoteFolderTree getTree() {
return tree;
}
/**
* Reset the builder to prepare for a new build
*/
public void reset() {
tree = new RemoteFolderTree(null, location, ICVSRemoteFolder.REPOSITORY_ROOT_FOLDER_NAME, tag);
tree.setChildren(new ICVSRemoteResource[0]);
}
/*
* @see
* org.eclipse.team.internal.ccvs.core.client.listeners.RDiffSummaryListener.
* IFileDiffListener#newFile(java.lang.String, java.lang.String)
*/
public void newFile(IPath remoteFilePath, ICVSRemoteFile remoteFile) {
try {
addFile(tree,tag,remoteFile, remoteFilePath);
} catch (CVSException e) {
CVSUIPlugin.log(e);
}
}
private void addFile(RemoteFolderTree tree, CVSTag tag, ICVSRemoteFile file,IPath filePath) throws CVSException {
RemoteFolderTree parent = (RemoteFolderTree)getFolder(tree, tag, filePath.removeLastSegments(1), Path.EMPTY);
addChild(parent, file);
}
private void addChild(RemoteFolderTree tree, ICVSRemoteResource resource) {
ICVSRemoteResource[] children = tree.getChildren();
ICVSRemoteResource[] newChildren;
if (children == null) {
newChildren = new ICVSRemoteResource[] { resource };
} else {
newChildren = new ICVSRemoteResource[children.length + 1];
System.arraycopy(children, 0, newChildren, 0, children.length);
newChildren[children.length] = resource;
}
tree.setChildren(newChildren);
}
/*
* Get the folder at the given path in the given tree, creating any missing folders as needed.
*/
private ICVSRemoteFolder getFolder(RemoteFolderTree tree, CVSTag tag, IPath remoteFolderPath, IPath parentPath) throws CVSException {
if (remoteFolderPath.segmentCount() == 0) return tree;
String name = remoteFolderPath.segment(0);
ICVSResource child;
IPath childPath = parentPath.append(name);
if (tree.childExists(name)) {
child = tree.getChild(name);
} else {
child = new RemoteFolderTree(tree, tree.getRepository(), childPath.toString(), tag);
((RemoteFolderTree)child).setChildren(new ICVSRemoteResource[0]);
addChild(tree, (ICVSRemoteResource)child);
}
return getFolder((RemoteFolderTree)child, tag, remoteFolderPath.removeFirstSegments(1), childPath);
}
}
static final String DEAD_STATE = "dead"; //$NON-NLS-1$
ICVSRepositoryLocation repoLocation;
public FetchAllMembersOperation(IWorkbenchPart part, ICVSRemoteResource[] folders, ICVSRepositoryLocation repoLocation) {
super(part, folders);
this.repoLocation = repoLocation;
}
@Override
protected void execute(IProgressMonitor monitor) throws CVSException, InterruptedException {
//expand each folder selected in the tree
ICVSRemoteResource[] restest = getRemoteResources();
ICVSRemoteFolder testfolder = (ICVSRemoteFolder) restest[0];
CVSTag tag = testfolder.getTag();
if (tag == null)
tag = CVSTag.DEFAULT;
LogEntryCache cache = new LogEntryCache();
RemoteLogOperation operation = new RemoteLogOperation(getPart(), getRemoteResources(), tag, null, cache);
try {
operation.run(monitor);
ICVSRemoteResource[] remoteRes = getRemoteResources();
final ICVSRemoteFolder project = (ICVSRemoteFolder) remoteRes[0];
//Get the entry paths
String[] entry = cache.getCachedFilePaths();
//Strip repo + project info from entries
RLogTreeBuilder treeBuilder = new RLogTreeBuilder(project.getRepository(),tag);
for (int i = 0; i < entry.length; i++) {
ILogEntry[] logEntry = cache.getLogEntries(entry[i]);
//might not have state if this a branch entry
if (logEntry[0].getState() != null &&
logEntry[0].getState().equals(DEAD_STATE))
continue;
ICVSRemoteFile remoteFile = logEntry[0].getRemoteFile();
//if the current folder tag is a branch tag, we need to take the extra step
//of making sure that the file's revision number has been set appropriately
if (tag.getType() == CVSTag.BRANCH &&
remoteFile.getRevision().equals(LogListener.BRANCH_REVISION))
verifyRevision(tag, logEntry[0], remoteFile);
IPath logPath = new Path(null,remoteFile.getRepositoryRelativePath());
if (logPath.segmentCount()>0)
logPath = logPath.removeFirstSegments(1);
treeBuilder.newFile(logPath, remoteFile);
}
RemoteFolderTree remoteTree = treeBuilder.getTree();
IWorkbenchPart part = this.getPart();
if (part instanceof RepositoriesView ){
final RepositoriesView repView = (RepositoriesView) part;
RemoteContentProvider prov = repView.getContentProvider();
prov.addCachedTree(project, remoteTree);
final TreeViewer tree = repView.getViewer();
Utils.asyncExec((Runnable) () -> tree.expandToLevel(project, AbstractTreeViewer.ALL_LEVELS),
repView.getViewer());
}
} catch (InvocationTargetException e) {
throw CVSException.wrapException(e);
} catch (InterruptedException e) {
// Ignore;
} catch (TeamException e){
throw CVSException.wrapException(e);
}
}
private void verifyRevision(CVSTag tag, ILogEntry entry, ICVSRemoteFile remoteFile) throws CVSException {
if (entry instanceof LogEntry){
LogEntry logEntry = (LogEntry) entry;
String[] allBranchRevisions = logEntry.getBranchRevisions();
CVSTag[] allCVSTags = entry.getTags();
for (int i = 0; i < allCVSTags.length; i++) {
if (allCVSTags[i].equals(tag)){
//get the revision number stored for this tag
((RemoteFile) remoteFile).setRevision(allBranchRevisions[i]);
break;
}
}
}
}
@Override
protected String getTaskName() {
return CVSUIMessages.FetchAllMembersOperation_0;
}
}