/******************************************************************************* * 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]); } /* (non-Javadoc) * @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; } }