diff options
Diffstat (limited to 'bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/UpdateSyncAction.java')
-rw-r--r-- | bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/UpdateSyncAction.java | 407 |
1 files changed, 0 insertions, 407 deletions
diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/UpdateSyncAction.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/UpdateSyncAction.java deleted file mode 100644 index 338bcc8a2..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/sync/UpdateSyncAction.java +++ /dev/null @@ -1,407 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2002 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v05.html - * - * Contributors: - * IBM - Initial API and implementation - ******************************************************************************/ -package org.eclipse.team.internal.ccvs.ui.sync; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.Vector; - -import org.eclipse.compare.structuremergeviewer.Differencer; -import org.eclipse.compare.structuremergeviewer.IDiffContainer; -import org.eclipse.compare.structuremergeviewer.IDiffElement; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.sync.IRemoteSyncElement; -import org.eclipse.team.internal.ccvs.core.client.Command; -import org.eclipse.team.internal.ccvs.core.client.Update; -import org.eclipse.team.internal.ccvs.core.resources.CVSRemoteSyncElement; -import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; -import org.eclipse.team.internal.ccvs.ui.IHelpContextIds; -import org.eclipse.team.internal.ccvs.ui.Policy; -import org.eclipse.team.internal.ccvs.ui.RepositoryManager; -import org.eclipse.team.internal.ui.sync.ChangedTeamContainer; -import org.eclipse.team.internal.ui.sync.ITeamNode; -import org.eclipse.team.internal.ui.sync.SyncSet; -import org.eclipse.team.internal.ui.sync.TeamFile; - -/** - * UpdateSyncAction is run on a set of sync nodes when the "Update" menu item is performed - * in the Synchronize view. - * - * This class is also used as the super class of the merge update actions for regular and forced - * update. - */ -public class UpdateSyncAction extends MergeAction { - public static class ConfirmDialog extends MessageDialog { - - private boolean autoMerge = true; - private Button radio1; - private Button radio2; - - public ConfirmDialog(Shell parentShell) { - super( - parentShell, - Policy.bind("UpdateSyncAction.Conflicting_changes_found_1"), //$NON-NLS-1$ - null, // accept the default window icon - Policy.bind("UpdateSyncAction.You_have_local_changes_you_are_about_to_overwrite_2"), //$NON-NLS-1$ - MessageDialog.QUESTION, - new String[] {IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, - 0); // yes is the default - } - - protected Control createCustomArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - composite.setLayout(new GridLayout()); - radio1 = new Button(composite, SWT.RADIO); - radio1.addSelectionListener(selectionListener); - - radio1.setText(Policy.bind("UpdateSyncAction.Only_update_resources_that_can_be_automatically_merged_3")); //$NON-NLS-1$ - - radio2 = new Button(composite, SWT.RADIO); - radio2.addSelectionListener(selectionListener); - - radio2.setText(Policy.bind("UpdateSyncAction.Update_all_resources,_overwriting_local_changes_with_remote_contents_4")); //$NON-NLS-1$ - - // set initial state - radio1.setSelection(autoMerge); - radio2.setSelection(!autoMerge); - - return composite; - } - - private SelectionListener selectionListener = new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - Button button = (Button)e.widget; - if (button.getSelection()) { - autoMerge = (button == radio1); - } - } - }; - - public boolean getAutomerge() { - return autoMerge; - } - } - - public UpdateSyncAction(CVSSyncCompareInput model, ISelectionProvider sp, String label, Shell shell) { - super(model, sp, label, shell); - } - - protected SyncSet run(final SyncSet syncSet, IProgressMonitor monitor) { - boolean result = saveIfNecessary(); - if (!result) return null; - - // If there are conflicts or outgoing changes in the syncSet, we need to warn the user. - boolean onlyUpdateAutomergeable = false; - if (syncSet.hasConflicts() || syncSet.hasOutgoingChanges()) { - if (syncSet.hasAutoMergeableConflicts()) { - switch (promptForMergeableConflicts()) { - case 0: // cancel - return null; - case 1: // only update auto-mergeable conflicts - onlyUpdateAutomergeable = true; - syncSet.removeNonMergeableNodes(); - break; - case 2: // update all conflicts - onlyUpdateAutomergeable = false; - break; - } - } else { - if (! promptForConflicts()) return null; - } - } - - ITeamNode[] changed = syncSet.getChangedNodes(); - if (changed.length == 0) { - return syncSet; - } - - List updateIgnoreLocalShallow = new ArrayList(); - List updateDeep = new ArrayList(); - List updateShallow = new ArrayList(); - - // A list of diff elements in the sync set which are incoming folder additions - Set parentCreationElements = new HashSet(); - // A list of diff elements in the sync set which are folder conflicts - Set parentConflictElements = new HashSet(); - // A list of diff elements in the sync set which are outgoing folder deletions - Set parentDeletionElements = new HashSet(); - // A list of the team nodes that we need to perform makeIncoming on - List makeIncoming = new ArrayList(); - // A list of diff elements that need to be unmanaged and locally deleted - List deletions = new ArrayList(); - - for (int i = 0; i < changed.length; i++) { - IDiffContainer parent = changed[i].getParent(); - if (parent != null) { - int parentKind = changed[i].getParent().getKind(); - if (((parentKind & Differencer.CHANGE_TYPE_MASK) == Differencer.ADDITION) && - ((parentKind & Differencer.DIRECTION_MASK) == ITeamNode.INCOMING)) { - parentCreationElements.add(parent); - } else if (isLocallyDeletedFolder(parent)) { - parentDeletionElements.add(parent); - } else if ((parentKind & Differencer.DIRECTION_MASK) == ITeamNode.CONFLICTING) { - parentConflictElements.add(parent); - } - } - ITeamNode changedNode = changed[i]; - IResource resource = changedNode.getResource(); - int kind = changedNode.getKind(); - switch (kind & Differencer.DIRECTION_MASK) { - case ITeamNode.INCOMING: - switch (kind & Differencer.CHANGE_TYPE_MASK) { - case Differencer.ADDITION: - updateIgnoreLocalShallow.add(changedNode); - break; - case Differencer.DELETION: - case Differencer.CHANGE: - updateDeep.add(changedNode); - break; - } - break; - case ITeamNode.OUTGOING: - switch (kind & Differencer.CHANGE_TYPE_MASK) { - case Differencer.ADDITION: - // Unmanage the file if necessary and delete it. - deletions.add(changedNode); - break; - case Differencer.DELETION: - if (resource.getType() == IResource.FILE) { - makeIncoming.add(changedNode); - updateDeep.add(changedNode); - } - break; - case Differencer.CHANGE: - updateIgnoreLocalShallow.add(changedNode); - break; - } - break; - case ITeamNode.CONFLICTING: - switch (kind & Differencer.CHANGE_TYPE_MASK) { - case Differencer.ADDITION: - if(changedNode instanceof IDiffContainer) { - parentConflictElements.add(changedNode); - } else { - makeIncoming.add(changedNode); - deletions.add(changedNode); - updateIgnoreLocalShallow.add(changedNode); - } - break; - case Differencer.DELETION: - // Doesn't happen, these nodes don't appear in the tree. - break; - case Differencer.CHANGE: - if (resource.getType() == IResource.FILE) { - // Depends on the flag. - if (onlyUpdateAutomergeable && (changedNode.getKind() & IRemoteSyncElement.AUTOMERGE_CONFLICT) != 0) { - updateShallow.add(changedNode); - } else { - // Check to see if there is a remote - if (((TeamFile)changedNode).getMergeResource().getSyncElement().getRemote() == null) { - // If a locally modified file has no remote, "update -C" will fail. - // We must unmanage and delete the file ourselves - deletions.add(changedNode); - } else { - updateIgnoreLocalShallow.add(changedNode); - // If the resource doesn't exist remotely, we must ensure the sync info will allow the above update. - if (!resource.exists()) { - makeIncoming.add(changedNode); - } - } - } - } else { - // Conflicting change on a folder only occurs if the folder has been deleted locally - // The folder should only be recreated if there were children in the changed set. - // Such folders would have been added to the parentDeletionElements set above - } - break; - } - break; - } - } - try { - // Calculate the total amount of work needed - int work = (makeIncoming.size() + (deletions.size() * 2) + updateShallow.size() + updateIgnoreLocalShallow.size() + updateDeep.size()) * 100; - monitor.beginTask(null, work); - - RepositoryManager manager = CVSUIPlugin.getPlugin().getRepositoryManager(); - if (parentDeletionElements.size() > 0) { - // If a node has a parent that is an outgoing folder deletion, we have to - // recreate that folder locally (it's sync info already exists locally). - // We must do this for all outgoing folder deletions (recursively) - // in the case where there are multiple levels of outgoing folder deletions. - Iterator it = parentDeletionElements.iterator(); - while (it.hasNext()) { - recreateLocallyDeletedFolder((IDiffElement)it.next()); - } - } - if (parentCreationElements.size() > 0) { - // If a node has a parent that is an incoming folder creation, we have to - // create that folder locally and set its sync info before we can get the - // node itself. We must do this for all incoming folder creations (recursively) - // in the case where there are multiple levels of incoming folder creations. - Iterator it = parentCreationElements.iterator(); - while (it.hasNext()) { - IDiffElement element = (IDiffElement)it.next(); - makeInSync(element); - // Remove the folder from the update shallow list since we have it locally now - updateIgnoreLocalShallow.remove(element); - } - } - if (parentConflictElements.size() > 0) { - // If a node has a parent that is a folder conflict, that means that the folder - // exists locally but has no sync info. In order to get the node, we have to - // create the sync info for the folder (and any applicable parents) before we - // get the node itself. - Iterator it = parentConflictElements.iterator(); - while (it.hasNext()) { - makeInSync((IDiffElement)it.next()); - } - } - // Make any outgoing changes or deletions into incoming changes before updating. - Iterator it = makeIncoming.iterator(); - while (it.hasNext()) { - ITeamNode node = (ITeamNode)it.next(); - CVSRemoteSyncElement element = CVSSyncCompareInput.getSyncElementFrom(node); - element.makeIncoming(Policy.subMonitorFor(monitor, 100)); - } - // Outgoing additions must be unmanaged (if necessary) and locally deleted. - it = deletions.iterator(); - while (it.hasNext()) { - ITeamNode node = (ITeamNode)it.next(); - CVSRemoteSyncElement element = CVSSyncCompareInput.getSyncElementFrom(node); - element.makeIncoming(Policy.subMonitorFor(monitor, 100)); - element.getLocal().delete(true, Policy.subMonitorFor(monitor, 100)); - } - - if (updateShallow.size() > 0) { - runUpdateShallow((ITeamNode[])updateShallow.toArray(new ITeamNode[updateShallow.size()]), manager, Policy.subMonitorFor(monitor, 100)); - } - if (updateIgnoreLocalShallow.size() > 0) { - runUpdateIgnoreLocalShallow((ITeamNode[])updateIgnoreLocalShallow.toArray(new ITeamNode[updateIgnoreLocalShallow.size()]), manager, Policy.subMonitorFor(monitor, 100)); - } - if (updateDeep.size() > 0) { - runUpdateDeep((ITeamNode[])updateDeep.toArray(new ITeamNode[updateDeep.size()]), manager, Policy.subMonitorFor(monitor, 100)); - } - } catch (final TeamException e) { - getShell().getDisplay().syncExec(new Runnable() { - public void run() { - ErrorDialog.openError(getShell(), null, null, e.getStatus()); - } - }); - return null; - } catch (final CoreException e) { - getShell().getDisplay().syncExec(new Runnable() { - public void run() { - ErrorDialog.openError(getShell(), Policy.bind("simpleInternal"), Policy.bind("internal"), e.getStatus()); //$NON-NLS-1$ //$NON-NLS-2$ - } - }); - CVSUIPlugin.log(e.getStatus()); - return null; - } finally { - monitor.done(); - } - return syncSet; - } - - protected void runUpdateDeep(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - manager.update(getIResourcesFrom(nodes), Command.NO_LOCAL_OPTIONS, false, monitor); - } - - protected void runUpdateIgnoreLocalShallow(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - manager.update(getIResourcesFrom(nodes), new Command.LocalOption[] { Update.IGNORE_LOCAL_CHANGES, Command.DO_NOT_RECURSE }, false, monitor); - } - - protected void runUpdateShallow(ITeamNode[] nodes, RepositoryManager manager, IProgressMonitor monitor) throws TeamException { - manager.update(getIResourcesFrom(nodes), new Command.LocalOption[] { Command.DO_NOT_RECURSE }, false, monitor); - } - - protected IResource[] getIResourcesFrom(ITeamNode[] nodes) { - List resources = new ArrayList(nodes.length); - for (int i = 0; i < nodes.length; i++) { - resources.add(nodes[i].getResource()); - } - return (IResource[]) resources.toArray(new IResource[resources.size()]); - } - - protected boolean isEnabled(ITeamNode node) { - // The update action is enabled only for non-conflicting incoming changes - return new SyncSet(new StructuredSelection(node)).hasIncomingChanges(); - } - - /** - * Prompt for mergeable conflicts. - * Note: This method is designed to be overridden by test cases. - * @return 0 to cancel, 1 to only update mergeable conflicts, 2 to overwrite if unmergeable - */ - protected int promptForMergeableConflicts() { - final boolean doAutomerge[] = new boolean[] {false}; - final int[] result = new int[] {Dialog.CANCEL}; - final Shell shell = getShell(); - shell.getDisplay().syncExec(new Runnable() { - public void run() { - ConfirmDialog dialog = new ConfirmDialog(shell); - result[0] = dialog.open(); - doAutomerge[0] = dialog.getAutomerge(); - } - }); - if (result[0] == Dialog.CANCEL) return 0; - return doAutomerge[0] ? 1 : 2; - } - - /** - * Prompt for non-automergeable conflicts. - * Note: This method is designed to be overridden by test cases. - * @return false to cancel, true to overwrite local changes - */ - protected boolean promptForConflicts() { - final boolean[] result = new boolean[] { false }; - final Shell shell = getShell(); - shell.getDisplay().syncExec(new Runnable() { - public void run() { - result[0] = MessageDialog.openQuestion(shell, Policy.bind("UpdateSyncAction.Overwrite_local_changes__5"), Policy.bind("UpdateSyncAction.You_have_local_changes_you_are_about_to_overwrite._Do_you_wish_to_continue__6")); //$NON-NLS-1$ //$NON-NLS-2$ - } - }); - return result[0]; - } - protected void removeNonApplicableNodes(SyncSet set, int syncMode) { - set.removeConflictingNodes(); - set.removeOutgoingNodes(); - } - /** - * @see MergeAction#getHelpContextID() - */ - protected String getHelpContextID() { - return IHelpContextIds.SYNC_UPDATE_ACTION; - } - -} |