blob: 58b40232e50dc24fcefae78d99f8e40e4e8ea7e4 [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.ui.mappings;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.diff.IDiff;
import org.eclipse.team.core.diff.IThreeWayDiff;
import org.eclipse.team.core.history.IFileRevision;
import org.eclipse.team.core.mapping.provider.ResourceDiffTree;
import org.eclipse.team.core.variants.IResourceVariant;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.mapping.CVSCheckedInChangeSet;
import org.eclipse.team.internal.ccvs.ui.CVSUIMessages;
import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
import org.eclipse.team.internal.ccvs.ui.operations.RemoteCompareOperation.CompareTreeBuilder;
import org.eclipse.team.internal.ccvs.ui.subscriber.CVSChangeSetCollector;
import org.eclipse.team.internal.core.mapping.SyncInfoToDiffConverter;
import org.eclipse.team.internal.core.subscribers.ChangeSet;
import org.eclipse.team.internal.core.subscribers.DiffChangeSet;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.internal.ui.mapping.ResourceModelParticipantAction;
import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
import org.eclipse.ui.PlatformUI;
import com.ibm.icu.text.DateFormat;
class OpenChangeSetAction extends ResourceModelParticipantAction {
protected OpenChangeSetAction(ISynchronizePageConfiguration configuration) {
super(CVSUIMessages.OpenCommitSetAction_20, configuration);
ISelection selection = configuration.getSite().getSelectionProvider().getSelection();
if (selection != null)
selectionChanged(selection);
}
private ChangeSet getChangeSet(IStructuredSelection selection) {
// First, check to see if a change set is selected directly
if (selection.size() == 1) {
Object o = selection.getFirstElement();
if (o instanceof IAdaptable) {
ChangeSet set = ((IAdaptable)o).getAdapter(ChangeSet.class);
if (set != null)
return set;
}
}
// Failing that, check to see if all the selected elements and their children are in the same change set
if (selection instanceof TreeSelection) {
TreeSelection ts = (TreeSelection) selection;
TreePath[] paths = ts.getPaths();
if (paths.length > 0) {
ChangeSet set = getChangeSet(paths[0]);
if (set != null) {
for (int i = 1; i < paths.length; i++) {
TreePath path = paths[i];
ChangeSet otherSet = getChangeSet(path);
if (set != otherSet)
return null;
}
}
return set;
}
}
return null;
}
private ChangeSet getChangeSet(TreePath treePath) {
Object test = treePath.getFirstSegment();
if (test instanceof ChangeSet) {
ChangeSet cs = (ChangeSet) test;
return cs;
}
return null;
}
@Override
protected boolean isEnabledForSelection(IStructuredSelection selection) {
// The selection only contains appropriate files so
// only enable if the selection is contained within a single change set
ChangeSet set = getChangeSet(selection);
return set != null;
}
public void openEditor(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
IDiff[] diffs = getSelectedDiffs(monitor);
if (diffs.length > 0) {
ICVSRepositoryLocation location = getLocation(diffs[0]);
if (location == null) {
throw new CVSException(CVSUIMessages.OpenCommitSetAction_21);
}
CompareTreeBuilder builder = new CompareTreeBuilder(location, null, null);
if (buildTrees(builder, diffs)) {
builder.cacheContents(monitor);
builder.openCompareEditor(getConfiguration().getSite().getPart().getSite().getPage(), getCompareTitle(), getCompareToolTip());
}
}
} catch (CoreException e) {
throw new InvocationTargetException(e);
}
}
private IDiff[] getSelectedDiffs(IProgressMonitor monitor) throws CoreException {
ResourceTraversal[] traversals = getResourceTraversals(getStructuredSelection(), monitor);
DiffChangeSet set = (DiffChangeSet)getChangeSet(getStructuredSelection());
return set.getDiffTree().getDiffs(traversals);
}
/*
* Build the trees that will be compared
*/
private boolean buildTrees(CompareTreeBuilder builder, IDiff[] diffs) {
for (int i = 0; i < diffs.length; i++) {
IDiff diff = diffs[i];
if (isFileChange(diff)) {
IFileRevision remoteRevision = Utils.getRemote(diff);
IResourceVariant remote = SyncInfoToDiffConverter.asResourceVariant(remoteRevision);
if (remote == null) {
IFileRevision predecessorRevision = Utils.getBase(diff);
IResourceVariant predecessor = SyncInfoToDiffConverter.asResourceVariant(predecessorRevision);
if (predecessor instanceof ICVSRemoteFile) {
builder.addToTrees((ICVSRemoteFile)predecessor, null);
}
} else if (remote instanceof ICVSRemoteFile) {
try {
ICVSRemoteFile predecessor = getImmediatePredecessor(remote);
builder.addToTrees(predecessor, (ICVSRemoteFile)remote);
} catch (TeamException e) {
Utils.handle(e);
return false;
}
}
}
}
return true;
}
private boolean isFileChange(IDiff diff) {
IResource resource = ResourceDiffTree.getResourceFor(diff);
if (resource.getType() == IResource.FILE) {
if (diff instanceof IThreeWayDiff) {
IThreeWayDiff twd = (IThreeWayDiff) diff;
return twd.getDirection() == IThreeWayDiff.INCOMING || twd.getDirection() == IThreeWayDiff.CONFLICTING;
}
return true;
}
return false;
}
private ICVSRepositoryLocation getLocation(IDiff diff) {
IResource resource = ResourceDiffTree.getResourceFor(diff);
RepositoryProvider provider = RepositoryProvider.getProvider(resource.getProject());
if (provider instanceof CVSTeamProvider) {
CVSTeamProvider ctp = (CVSTeamProvider) provider;
try {
return ctp.getCVSWorkspaceRoot().getRemoteLocation();
} catch (CVSException e) {
CVSUIPlugin.log(e);
}
}
return null;
}
private String getCompareTitle() {
ChangeSet set = getChangeSet(getStructuredSelection());
if (set instanceof CVSCheckedInChangeSet) {
CVSCheckedInChangeSet cics = (CVSCheckedInChangeSet)set;
String date = DateFormat.getDateTimeInstance().format(cics.getDate());
return NLS.bind(CVSUIMessages.OpenChangeSetAction_0, new String[] {cics.getAuthor(), date});
}
return CVSUIMessages.OpenChangeSetAction_1;
}
private String getCompareToolTip() {
ChangeSet set = getChangeSet(getStructuredSelection());
if (set != null)
return set.getName();
return null;
}
private ICVSRemoteFile getImmediatePredecessor(IResourceVariant remote) throws TeamException {
CheckedInChangeSetCollector changeSetCollector = getChangeSetCollector();
if (changeSetCollector != null) {
return changeSetCollector.getImmediatePredecessor((ICVSRemoteFile)remote);
}
return null;
}
private CheckedInChangeSetCollector getChangeSetCollector() {
return (CheckedInChangeSetCollector)getConfiguration().getProperty(CVSChangeSetCollector.CVS_CHECKED_IN_COLLECTOR);
}
@Override
public void run() {
try {
PlatformUI.getWorkbench().getProgressService().run(true, true, monitor -> openEditor(monitor));
} catch (InvocationTargetException e) {
Utils.handle(e);
} catch (InterruptedException e) {
// Ignore
}
}
}