1 11 package org.eclipse.team.ui.synchronize; 12 13 import java.lang.reflect.InvocationTargetException ; 14 import java.util.ArrayList ; 15 import java.util.List ; 16 17 import org.eclipse.core.resources.*; 18 import org.eclipse.core.resources.mapping.ModelProvider; 19 import org.eclipse.core.runtime.*; 20 import org.eclipse.core.runtime.jobs.Job; 21 import org.eclipse.jface.dialogs.*; 22 import org.eclipse.swt.widgets.Composite; 23 import org.eclipse.swt.widgets.Display; 24 import org.eclipse.team.core.TeamException; 25 import org.eclipse.team.core.diff.*; 26 import org.eclipse.team.core.mapping.*; 27 import org.eclipse.team.internal.ui.*; 28 import org.eclipse.team.internal.ui.dialogs.NoChangesDialog; 29 import org.eclipse.ui.IWorkbenchPart; 30 31 38 public abstract class ModelMergeOperation extends ModelOperation { 39 40 53 public static IStatus validateMerge(IMergeContext context, IProgressMonitor monitor) { 54 try { 55 ModelProvider[] providers = context.getScope().getModelProviders(); 56 monitor.beginTask(null, 100 * providers.length); 57 List notOK = new ArrayList (); 58 for (int i = 0; i < providers.length; i++) { 59 ModelProvider provider = providers[i]; 60 IStatus status = validateMerge(provider, context, Policy.subMonitorFor(monitor, 100)); 61 if (!status.isOK()) 62 notOK.add(status); 63 } 64 if (notOK.isEmpty()) 65 return Status.OK_STATUS; 66 if (notOK.size() == 1) 67 return (IStatus)notOK.get(0); 68 return new MultiStatus(TeamUIPlugin.ID, 0, (IStatus[]) notOK.toArray(new IStatus[notOK.size()]), TeamUIMessages.ResourceMappingMergeOperation_3, null); 69 } finally { 70 monitor.done(); 71 } 72 } 73 74 82 private static IStatus validateMerge(ModelProvider provider, IMergeContext context, IProgressMonitor monitor) { 83 IResourceMappingMerger merger = getMerger(provider); 84 if (merger == null) 85 return Status.OK_STATUS; 86 return merger.validateMerge(context, monitor); 87 } 88 89 100 private static IResourceMappingMerger getMerger(ModelProvider provider) { 101 Assert.isNotNull(provider); 102 return (IResourceMappingMerger)Utils.getAdapter(provider, IResourceMappingMerger.class); 103 } 104 105 110 protected ModelMergeOperation(IWorkbenchPart part, ISynchronizationScopeManager manager) { 111 super(part, manager); 112 } 113 114 121 protected void execute(IProgressMonitor monitor) 122 throws InvocationTargetException , InterruptedException { 123 try { 124 monitor.beginTask(null, 100); 125 initializeContext(Policy.subMonitorFor(monitor, 50)); 126 executeMerge(Policy.subMonitorFor(monitor, 50)); 127 } catch (CoreException e) { 128 throw new InvocationTargetException (e); 129 } finally { 130 monitor.done(); 131 } 132 } 133 134 145 protected void executeMerge(IProgressMonitor monitor) throws CoreException { 146 monitor.beginTask(null, 100); 147 if (!hasChangesOfInterest()) { 148 handleNoChanges(); 149 } else if (isPreviewRequested()) { 150 handlePreviewRequest(); 151 } else { 152 IStatus status = ModelMergeOperation.validateMerge(getMergeContext(), Policy.subMonitorFor(monitor, 10)); 153 if (!status.isOK()) { 154 handleValidationFailure(status); 155 } else { 156 status = performMerge(Policy.subMonitorFor(monitor, 90)); 157 if (!status.isOK()) { 158 handleMergeFailure(status); 159 } 160 } 161 } 162 monitor.done(); 163 } 164 165 171 protected void handlePreviewRequest() { 172 } 174 175 183 protected abstract void initializeContext(IProgressMonitor monitor) throws CoreException; 184 185 193 protected void handleValidationFailure(final IStatus status) { 194 final boolean[] result = new boolean[] { false }; 195 Runnable runnable = new Runnable () { 196 public void run() { 197 ErrorDialog dialog = new ErrorDialog(getShell(), TeamUIMessages.ModelMergeOperation_0, TeamUIMessages.ModelMergeOperation_1, status, IStatus.ERROR | IStatus.WARNING | IStatus.INFO) { 198 protected void createButtonsForButtonBar(Composite parent) { 199 createButton(parent, IDialogConstants.YES_ID, IDialogConstants.YES_LABEL, 200 false); 201 createButton(parent, IDialogConstants.NO_ID, IDialogConstants.NO_LABEL, 202 true); 203 createDetailsButton(parent); 204 } 205 208 protected void buttonPressed(int id) { 209 if (id == IDialogConstants.YES_ID) 210 super.buttonPressed(IDialogConstants.OK_ID); 211 else if (id == IDialogConstants.NO_ID) 212 super.buttonPressed(IDialogConstants.CANCEL_ID); 213 super.buttonPressed(id); 214 } 215 }; 216 int code = dialog.open(); 217 result[0] = code == 0; 218 } 219 }; 220 getShell().getDisplay().syncExec(runnable); 221 if (result[0]) 222 handlePreviewRequest(); 223 } 224 225 231 protected void handleMergeFailure(final IStatus status) { 232 Display.getDefault().syncExec(new Runnable () { 233 public void run() { 234 MessageDialog.openInformation(getShell(), TeamUIMessages.MergeIncomingChangesAction_0, status.getMessage()); 235 }; 236 }); 237 handlePreviewRequest(); 238 } 239 240 245 protected void handleNoChanges() { 246 Display.getDefault().syncExec(new Runnable () { 247 public void run() { 248 NoChangesDialog.open(getShell(), TeamUIMessages.ResourceMappingMergeOperation_0, TeamUIMessages.ResourceMappingMergeOperation_1, TeamUIMessages.ModelMergeOperation_3, getScope().asInputScope()); 249 }; 250 }); 251 } 252 253 269 protected IStatus performMerge(IProgressMonitor monitor) throws CoreException { 270 ISynchronizationContext sc = getContext(); 271 if (sc instanceof IMergeContext) { 272 IMergeContext context = (IMergeContext) sc; 273 final ModelProvider[] providers = sortByExtension(context.getScope().getModelProviders()); 274 final IStatus[] result = new IStatus[] { Status.OK_STATUS }; 275 context.run(new IWorkspaceRunnable() { 276 public void run(IProgressMonitor monitor) throws CoreException { 277 try { 278 int ticks = 100; 279 monitor.beginTask(null, ticks + ((providers.length - 1) * 10)); 280 for (int i = 0; i < providers.length; i++) { 281 ModelProvider provider = providers[i]; 282 IStatus status = performMerge(provider, Policy.subMonitorFor(monitor, ticks)); 283 ticks = 10; 284 if (!status.isOK()) { 285 result[0] = status; 287 return; 288 } 289 try { 290 Job.getJobManager().join(getContext(), monitor); 291 } catch (InterruptedException e) { 292 } 294 } 295 } finally { 296 monitor.done(); 297 } 298 } 299 }, null , IResource.NONE, monitor); 300 return result[0]; 301 } 302 return noMergeContextAvailable(); 303 } 304 305 325 protected IStatus performMerge(ModelProvider provider, IProgressMonitor monitor) throws CoreException { 326 ISynchronizationContext sc = getContext(); 327 if (sc instanceof IMergeContext) { 328 IMergeContext context = (IMergeContext) sc; 329 IResourceMappingMerger merger = getMerger(provider); 330 if (merger != null) { 331 IStatus status = merger.merge(context, monitor); 332 if (status.isOK() || status.getCode() == IMergeStatus.CONFLICTS) { 333 return status; 334 } 335 throw new TeamException(status); 336 } 337 return Status.OK_STATUS; 338 } 339 return noMergeContextAvailable(); 340 } 341 342 private IStatus noMergeContextAvailable() { 343 throw new IllegalStateException (TeamUIMessages.ModelMergeOperation_2); 344 } 345 346 352 protected boolean hasChangesOfInterest() { 353 return !getContext().getDiffTree().isEmpty() && hasIncomingChanges(getContext().getDiffTree()); 354 } 355 356 private boolean hasIncomingChanges(IDiffTree tree) { 357 return tree.hasMatchingDiffs(ResourcesPlugin.getWorkspace().getRoot().getFullPath(), new FastDiffFilter() { 358 public boolean select(IDiff node) { 359 if (node instanceof IThreeWayDiff) { 360 IThreeWayDiff twd = (IThreeWayDiff) node; 361 int direction = twd.getDirection(); 362 if (direction == IThreeWayDiff.INCOMING || direction == IThreeWayDiff.CONFLICTING) { 363 return true; 364 } 365 } else { 366 return true; 368 } 369 return false; 370 } 371 }); 372 } 373 374 private IMergeContext getMergeContext() { 375 return (IMergeContext)getContext(); 376 } 377 } 378 | Popular Tags |