From 2e16b8639ffc52b523976d99ba8dfe02b151035c Mon Sep 17 00:00:00 2001 From: David McKnight Date: Fri, 24 Apr 2009 19:00:27 +0000 Subject: [PATCH] [272708] [import/export] fix various bugs with the synchronization support -needed to externalize some strings -some prototype work with merge --- .../SystemImportExportResources.java | 9 ++ .../SystemImportExportResources.properties | 7 ++ .../subscriber/FileSystemMergeContext.java | 9 +- .../ui/FileSystemSynchronizeParticipant.java | 36 ++++-- .../filesystem/ui/MergeOperation.java | 116 ++++++++++++++++++ .../filesystem/ui/ModelMergeAction.java | 89 ++++++++++++++ 6 files changed, 254 insertions(+), 12 deletions(-) create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/ui/MergeOperation.java create mode 100644 rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/ui/ModelMergeAction.java diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/importexport/SystemImportExportResources.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/importexport/SystemImportExportResources.java index 58305d8ced6..fa5334b3557 100644 --- a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/importexport/SystemImportExportResources.java +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/importexport/SystemImportExportResources.java @@ -8,6 +8,7 @@ * Contributors: * David McKnight (IBM) - [223204] [cleanup] fix broken nls strings in files.ui and others * Martin Oberhuber (Wind River) - [185925] Support Platform/Team Synchronization + * David McKnight (IBM) - [272708] [import/export] fix various bugs with the synchronization support *******************************************************************************/ package org.eclipse.rse.internal.importexport; @@ -69,6 +70,14 @@ public class SystemImportExportResources extends NLS { public static String RESID_FILEIMPEXP_BUTTON_SELECTTYPES_LABEL; public static String RESID_FILEIMPEXP_BUTTON_SELECTTYPES_TOOLTIP; + // synchronize actions + public static String RESID_SYNCHRONIZE_ACTIONS_PUT_LABEL; + public static String RESID_SYNCHRONIZE_ACTIONS_PUT_ALL_LABEL; + public static String RESID_SYNCHRONIZE_ACTIONS_GET_LABEL; + public static String RESID_SYNCHRONIZE_ACTIONS_GET_ALL_LABEL; + public static String RESID_SYNCHRONIZE_ACTIONS_MERGE_LABEL; + public static String RESID_SYNCHRONIZE_ACTIONS_MERGE_ALL_LABEL; + static { // load message values from bundle file NLS.initializeMessages(BUNDLE_NAME, SystemImportExportResources.class); diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/importexport/SystemImportExportResources.properties b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/importexport/SystemImportExportResources.properties index 1b2d5287854..c0825dbca1b 100644 --- a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/importexport/SystemImportExportResources.properties +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/importexport/SystemImportExportResources.properties @@ -91,3 +91,10 @@ RESID_FILEIMPEXP_BUTTON_DESELECTALL_TOOLTIP=De-select all resources RESID_FILEIMPEXP_BUTTON_SELECTTYPES_LABEL=Select Types RESID_FILEIMPEXP_BUTTON_SELECTTYPES_TOOLTIP=Select resource types to subset the selection list by +# synchronize operations +RESID_SYNCHRONIZE_ACTIONS_PUT_LABEL=Put +RESID_SYNCHRONIZE_ACTIONS_PUT_ALL_LABEL=Put All +RESID_SYNCHRONIZE_ACTIONS_GET_LABEL=Get +RESID_SYNCHRONIZE_ACTIONS_GET_ALL_LABEL=Get All +RESID_SYNCHRONIZE_ACTIONS_MERGE_LABEL=Merge +RESID_SYNCHRONIZE_ACTIONS_MERGE_ALL_LABEL=Merge All diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/subscriber/FileSystemMergeContext.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/subscriber/FileSystemMergeContext.java index 14975a566d4..74ec4205581 100644 --- a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/subscriber/FileSystemMergeContext.java +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/subscriber/FileSystemMergeContext.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2008 IBM Corporation and others. + * Copyright (c) 2006, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,20 +8,17 @@ * Contributors: * IBM Corporation - initial API and implementation * Takuya Miyamoto - Adapted from org.eclipse.team.examples.filesystem / FileSystemMergeContext + * David McKnight (IBM) - [272708] [import/export] fix various bugs with the synchronization support *******************************************************************************/ package org.eclipse.rse.internal.synchronize.filesystem.subscriber; -import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.rse.internal.synchronize.RSESyncUtils; import org.eclipse.team.core.diff.IDiff; -import org.eclipse.team.core.diff.IThreeWayDiff; import org.eclipse.team.core.mapping.ISynchronizationScopeManager; -import org.eclipse.team.core.mapping.provider.MergeStatus; import org.eclipse.team.core.mapping.provider.ResourceDiffTree; import org.eclipse.team.core.subscribers.SubscriberMergeContext; @@ -105,6 +102,7 @@ public class FileSystemMergeContext extends SubscriberMergeContext { // is because the file system provider doesn't really have the proper // base // so merging conflicts doesn't work properly + /* if (!ignoreLocalChanges) { IResource resource = ResourceDiffTree.getResourceFor(diff); if (diff instanceof IThreeWayDiff && resource instanceof IFile) { @@ -117,6 +115,7 @@ public class FileSystemMergeContext extends SubscriberMergeContext { } } } + */ return super.merge(diff, ignoreLocalChanges, monitor); } diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/ui/FileSystemSynchronizeParticipant.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/ui/FileSystemSynchronizeParticipant.java index a3977ca0f31..e36ee2811ca 100644 --- a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/ui/FileSystemSynchronizeParticipant.java +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/ui/FileSystemSynchronizeParticipant.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Takuya Miyamoto - Adapted from org.eclipse.team.examples.filesystem / FileSystemSynchronizeParticipant + * David McKnight (IBM) - [272708] [import/export] fix various bugs with the synchronization support *******************************************************************************/ package org.eclipse.rse.internal.synchronize.filesystem.ui; @@ -22,6 +23,7 @@ import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.viewers.ILabelDecorator; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.rse.internal.importexport.SystemImportExportResources; import org.eclipse.rse.internal.synchronize.filesystem.FileSystemPlugin; import org.eclipse.rse.internal.synchronize.filesystem.subscriber.FileSystemMergeContext; import org.eclipse.rse.internal.synchronize.filesystem.subscriber.FileSystemSubscriber; @@ -63,6 +65,7 @@ public class FileSystemSynchronizeParticipant extends ModelSynchronizeParticipan /** * Custom menu groups included in the viewer definition in the plugin.xml. */ + public static final String CONTEXT_MENU_MERGE_GROUP_1 = "merge"; //$NON-NLS-1$ public static final String CONTEXT_MENU_PUT_GROUP_1 = "put"; //$NON-NLS-1$ public static final String CONTEXT_MENU_GET_GROUP_1 = "get"; //$NON-NLS-1$ public static final String CONTEXT_MENU_OVERWRITE_GROUP_1 = "overwrite"; //$NON-NLS-1$ @@ -117,6 +120,7 @@ public class FileSystemSynchronizeParticipant extends ModelSynchronizeParticipan public class FileSystemParticipantActionGroup extends ModelSynchronizeParticipantActionGroup { private ModelPutAction putAction; private ModelGetAction getAction; + private ModelMergeAction mergeAction; /* * (non-Javadoc) @@ -130,6 +134,7 @@ public class FileSystemSynchronizeParticipant extends ModelSynchronizeParticipan super.initialize(configuration); putAction = new ModelPutAction("", configuration); getAction = new ModelGetAction("", configuration); + mergeAction = new ModelMergeAction("", configuration); } @@ -144,6 +149,7 @@ public class FileSystemSynchronizeParticipant extends ModelSynchronizeParticipan TreeSelection selection = (TreeSelection)getConfiguration().getSite().getSelectionProvider().getSelection(); boolean hasOutgoingChange = false; boolean hasIncomingChange = false; + boolean hasConflictingChange = false; boolean hasSingleResource = selection.size() == 1?true:false; List resources = new ArrayList(); @@ -156,18 +162,33 @@ public class FileSystemSynchronizeParticipant extends ModelSynchronizeParticipan IResource resource = (IResource) iterator.next(); SyncInfo info = FileSystemSubscriber.getInstance().getSyncInfo(resource); - if(SyncInfo.getDirection(info.getKind()) == SyncInfo.OUTGOING){ + int kind = info.getKind(); + + if(SyncInfo.getDirection(kind) == SyncInfo.OUTGOING){ hasOutgoingChange = true; - } else if (SyncInfo.getDirection(info.getKind()) == SyncInfo.INCOMING){ + } else if (SyncInfo.getDirection(kind) == SyncInfo.INCOMING){ hasIncomingChange = true; } + else if (SyncInfo.getDirection(kind) == SyncInfo.CONFLICTING){ + hasConflictingChange = true; + } + } + + if (hasConflictingChange){ + if(hasSingleResource){ + mergeAction.setText(SystemImportExportResources.RESID_SYNCHRONIZE_ACTIONS_MERGE_LABEL); + }else{ + mergeAction.setText(SystemImportExportResources.RESID_SYNCHRONIZE_ACTIONS_MERGE_ALL_LABEL); + } + appendToGroup(ISynchronizePageConfiguration.P_CONTEXT_MENU, CONTEXT_MENU_MERGE_GROUP_1, putAction); + menu.appendToGroup(CONTEXT_MENU_MERGE_GROUP_1, mergeAction); } if(hasOutgoingChange){ if(hasSingleResource){ - putAction.setText("Put"); + putAction.setText(SystemImportExportResources.RESID_SYNCHRONIZE_ACTIONS_PUT_LABEL); }else{ - putAction.setText("Put All"); + putAction.setText(SystemImportExportResources.RESID_SYNCHRONIZE_ACTIONS_PUT_ALL_LABEL); } appendToGroup(ISynchronizePageConfiguration.P_CONTEXT_MENU, CONTEXT_MENU_PUT_GROUP_1, putAction); menu.appendToGroup(CONTEXT_MENU_PUT_GROUP_1, putAction); @@ -175,13 +196,14 @@ public class FileSystemSynchronizeParticipant extends ModelSynchronizeParticipan if(hasIncomingChange){ if(hasSingleResource){ - getAction.setText("Get"); + getAction.setText(SystemImportExportResources.RESID_SYNCHRONIZE_ACTIONS_GET_LABEL); }else{ - getAction.setText("Get All"); + getAction.setText(SystemImportExportResources.RESID_SYNCHRONIZE_ACTIONS_GET_ALL_LABEL); } appendToGroup(ISynchronizePageConfiguration.P_CONTEXT_MENU, CONTEXT_MENU_GET_GROUP_1, getAction); menu.appendToGroup(CONTEXT_MENU_GET_GROUP_1, getAction); } + } catch (Exception e) { // TODO Auto-generated catch block diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/ui/MergeOperation.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/ui/MergeOperation.java new file mode 100644 index 00000000000..1459393afa7 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/ui/MergeOperation.java @@ -0,0 +1,116 @@ +/******************************************************************************** + * Copyright (c) 2009 IBM Corporation. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Initial Contributors: + * The following IBM employees contributed to the Remote System Explorer + * component that contains this file: David McKnight. + * + * Contributors: + * {Name} (company) - description of contribution. + ********************************************************************************/ +package org.eclipse.rse.internal.synchronize.filesystem.ui; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.team.core.mapping.IMergeContext; +import org.eclipse.team.core.mapping.ISynchronizationContext; +import org.eclipse.team.core.mapping.provider.SynchronizationContext; +import org.eclipse.team.internal.ui.TeamUIMessages; +import org.eclipse.team.ui.mapping.SynchronizationOperation; +import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration; +import org.eclipse.team.ui.synchronize.ModelMergeOperation; + +public class MergeOperation extends SynchronizationOperation { + + private IMergeContext context; + + protected MergeOperation(ISynchronizePageConfiguration configuration, Object[] elements, IMergeContext context) { + super(configuration, elements); + + this.context= context; + } + + + /* (non-Javadoc) + * @see org.eclipse.team.ui.mapping.SynchronizationOperation#execute(org.eclipse.core.runtime.IProgressMonitor) + */ + public void execute(IProgressMonitor monitor) throws InvocationTargetException, + InterruptedException { + new ModelMergeOperation(getPart(), ((SynchronizationContext)context).getScopeManager()) { + public boolean isPreviewRequested() { + return false; + } + protected void initializeContext(IProgressMonitor monitor) throws CoreException { + monitor.beginTask(null, 10); + monitor.done(); + } + protected ISynchronizationContext getContext() { + return context; + } + protected void executeMerge(IProgressMonitor monitor) throws CoreException { + monitor.beginTask(null, 100); + if (!hasChangesOfInterest()) { + handleNoChanges(); + } else if (isPreviewRequested()) { + handlePreviewRequest(); + } else { + IStatus status = ModelMergeOperation.validateMerge(getMergeContext(), monitor); + if (!status.isOK()) { + if (!promptToContinue(status)) + return; + } + status = performMerge(monitor); + if (!status.isOK()) { + handleMergeFailure(status); + } + } + monitor.done(); + } + private IMergeContext getMergeContext() { + return (IMergeContext)getContext(); + } + private boolean promptToContinue(final IStatus status) { + final boolean[] result = new boolean[] { false }; + Runnable runnable = new Runnable() { + public void run() { + ErrorDialog dialog = new ErrorDialog(getShell(), TeamUIMessages.ModelMergeOperation_0, TeamUIMessages.ModelMergeOperation_1, status, IStatus.ERROR | IStatus.WARNING | IStatus.INFO) { + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.YES_ID, IDialogConstants.YES_LABEL, + false); + createButton(parent, IDialogConstants.NO_ID, IDialogConstants.NO_LABEL, + true); + createDetailsButton(parent); + } + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.ErrorDialog#buttonPressed(int) + */ + protected void buttonPressed(int id) { + if (id == IDialogConstants.YES_ID) + super.buttonPressed(IDialogConstants.OK_ID); + else if (id == IDialogConstants.NO_ID) + super.buttonPressed(IDialogConstants.CANCEL_ID); + super.buttonPressed(id); + } + }; + int code = dialog.open(); + result[0] = code == 0; + } + }; + getShell().getDisplay().syncExec(runnable); + return (result[0]); + } + }.run(monitor); + } + + + +} diff --git a/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/ui/ModelMergeAction.java b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/ui/ModelMergeAction.java new file mode 100644 index 00000000000..5369d98e645 --- /dev/null +++ b/rse/plugins/org.eclipse.rse.importexport/src/org/eclipse/rse/internal/synchronize/filesystem/ui/ModelMergeAction.java @@ -0,0 +1,89 @@ +/******************************************************************************** + * Copyright (c) 2009 IBM Corporation. All rights reserved. + * This program and the accompanying materials are made available under the terms + * of the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Initial Contributors: + * The following IBM employees contributed to the Remote System Explorer + * component that contains this file: David McKnight. + * + * Contributors: + * {Name} (company) - description of contribution. + ********************************************************************************/ +package org.eclipse.rse.internal.synchronize.filesystem.ui; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.resources.mapping.ResourceMapping; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.rse.internal.synchronize.RSESyncUtils; +import org.eclipse.team.core.mapping.IMergeContext; +import org.eclipse.team.core.subscribers.SubscriberScopeManager; +import org.eclipse.team.internal.ui.Utils; +import org.eclipse.team.ui.mapping.ITeamContentProviderManager; +import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration; +import org.eclipse.team.ui.synchronize.ModelParticipantAction; + +public class ModelMergeAction extends ModelParticipantAction { + + public ModelMergeAction(String text, + ISynchronizePageConfiguration configuration) { + super(text, configuration); + // TODO Auto-generated constructor stub + } + + @Override + protected boolean isEnabledForSelection(IStructuredSelection selection) { + // Only enable the put in outgoing or both modes + int mode = getConfiguration().getMode(); + if (mode == ISynchronizePageConfiguration.OUTGOING_MODE || mode == ISynchronizePageConfiguration.BOTH_MODE) { + return getResourceMappings(selection).length > 0; + } + return false; + } + + private ResourceMapping[] getResourceMappings(IStructuredSelection selection) { + List mappings = new ArrayList(); + for (Iterator iter = selection.iterator(); iter.hasNext();) { + Object element = iter.next(); + ResourceMapping mapping = Utils.getResourceMapping(element); + if (mapping != null) + mappings.add(mapping); + } + return (ResourceMapping[]) mappings.toArray(new ResourceMapping[mappings.size()]); + } + + private IMergeContext getContext(ResourceMapping[] mappings) { + //SubscriberScopeManager manager = FileSystemOperation.createScopeManager(FileSystemSubscriber.getInstance().getName(), mappings); + //return new FileSystemMergeContext(manager); + + return ((IMergeContext)getConfiguration().getProperty(ITeamContentProviderManager.P_SYNCHRONIZATION_CONTEXT)); + } + + public void run() { + ResourceMapping[] resourceMappings = getResourceMappings(getStructuredSelection()); + SubscriberScopeManager manager = FileSystemOperation.createScopeManager("Merge", resourceMappings); + try { + new MergeOperation(getConfiguration(), resourceMappings, getContext(resourceMappings)).run(); + } catch (InvocationTargetException e) { + IStatus status = getStatus(e); + ErrorDialog.openError(getConfiguration().getSite().getShell(), null, null, status); + } catch (InterruptedException e) { + // Ignore + } + } + + private IStatus getStatus(Throwable throwable) { + if (throwable instanceof InvocationTargetException) { + return getStatus(((InvocationTargetException) throwable).getCause()); + } + return new Status(IStatus.ERROR, RSESyncUtils.PLUGIN_ID, 0, "An error occurred during the put.", throwable); + } +}