blob: a008d59ab2951b3329b1942f47e4895054acd943 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.compare.internal.patch;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import org.eclipse.compare.internal.CompareUIPlugin;
import org.eclipse.compare.internal.ExceptionHandler;
import org.eclipse.compare.internal.Utilities;
import org.eclipse.compare.internal.patch.CompareWithPatchAction.PatchWizardDialog;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
/* package */class PatchWizard extends Wizard {
// dialog store id constants
private final static String DIALOG_SETTINGS_KEY= "PatchWizard"; //$NON-NLS-1$
private boolean fHasNewDialogSettings;
private InputPatchPage fPatchWizardPage;
private WorkspacePatcher fPatcher;
private PatchWizardDialog fDialog;
private HashSet modDiffs;
private HashMap modFiles;
/*
* Creates a wizard for applying a patch file to the workspace.
*/
/* package */PatchWizard(ISelection selection) {
setDefaultPageImageDescriptor(CompareUIPlugin.getImageDescriptor("wizban/applypatch_wizban.png")); //$NON-NLS-1$
setWindowTitle(PatchMessages.PatchWizard_title);
fPatcher= new WorkspacePatcher();
setTarget(Utilities.getFirstResource(selection));
IDialogSettings workbenchSettings= CompareUIPlugin.getDefault().getDialogSettings();
IDialogSettings section= workbenchSettings.getSection(DIALOG_SETTINGS_KEY);
if (section == null) {
fHasNewDialogSettings= true;
} else {
fHasNewDialogSettings= false;
setDialogSettings(section);
}
}
WorkspacePatcher getPatcher() {
return fPatcher;
}
IResource getTarget() {
return fPatcher.getTarget();
}
void setTarget(IResource target) {
fPatcher.setTarget(target);
}
/* (non-Javadoc)
* Method declared on IWizard.
*/
public void addPages() {
super.addPages();
addPage(fPatchWizardPage= new InputPatchPage(this));
addPage(new PatchTargetPage(this));
if (System.getProperty("oldPatch") != null) //$NON-NLS-1$
addPage(new PreviewPatchPage(this));
else{
addPage(new PreviewPatchPage2(this));
addPage(new HunkMergePage(this));
}
}
/* (non-Javadoc)
* Method declared on IWizard.
*/
public boolean needsProgressMonitor() {
return true;
}
/* (non-Javadoc)
* Method declared on IWizard.
*/
public boolean performFinish() {
//Before applying all of the enabled diffs you have to go through and disable the diffs
//that have been merged by hand - this only applies if the current page is the hunk merge page
IWizardPage currentPage = fDialog.getCurrentPage();
if (currentPage.getName().equals(HunkMergePage.HUNKMERGEPAGE_NAME)){
Diff[] diffs = fPatcher.getDiffs();
HunkMergePage hunkMergePage = (HunkMergePage) currentPage;
hunkMergePage.ensureContentsSaved();
modDiffs = hunkMergePage.getModifiedDiffs();
modFiles = hunkMergePage.getMergedFileContents();
for (int i = 0; i < diffs.length; i++) {
//if this diff has been modified by hand, mark it as disabled to prevent
//the patcher from modifying it later
if (modDiffs.contains(diffs[i])){
diffs[i].setEnabled(false);
}
}
}
fPatcher.setName(fPatchWizardPage.getPatchName());
// make sure that the patch has been read
if (!fPatchWizardPage.isPatchRead())
fPatchWizardPage.readInPatch();
try {
// create scheduling rule based on the type of patch - single or workspace
ISchedulingRule scheduleRule = null;
if (fPatcher.isWorkspacePatch()) {
// workspace patch
scheduleRule = new MultiRule(fPatcher.getTargetProjects());
} else {
// single patch
IResource resource = getTarget();
scheduleRule = ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(resource);
}
WorkspaceModifyOperation op = new WorkspaceModifyOperation(scheduleRule) {
protected void execute(IProgressMonitor monitor) throws InvocationTargetException {
try {
fPatcher.applyAll(monitor, getShell(), PatchMessages.PatchWizard_title);
writePatchedFiles(monitor);
} catch (CoreException e) {
throw new InvocationTargetException(e);
}
}
};
getContainer().run(true, false, op);
} catch (InvocationTargetException e) {
ExceptionHandler.handle(e, PatchMessages.PatchWizard_title, PatchMessages.PatchWizard_unexpectedException_message);
} catch (InterruptedException e) {
// cannot happen
// NeedWork: use assert!
}
// Save the dialog settings
if (fHasNewDialogSettings) {
IDialogSettings workbenchSettings = CompareUIPlugin.getDefault().getDialogSettings();
IDialogSettings section = workbenchSettings.getSection(DIALOG_SETTINGS_KEY);
section = workbenchSettings.addNewSection(DIALOG_SETTINGS_KEY);
setDialogSettings(section);
}
fPatchWizardPage.saveWidgetValues();
//fPreviewPatchPage.saveWidgetValues();
return true;
}
private void writePatchedFiles(IProgressMonitor monitor) throws CoreException{
if (modDiffs != null){
Iterator iter = modDiffs.iterator();
while (iter.hasNext()){
Diff diff = (Diff) iter.next();
PatchedFileNode patchedFile = (PatchedFileNode) modFiles.get(diff);
fPatcher.store(patchedFile.getBytes(), diff.getTargetFile(), monitor);
}
}
}
public void setDialog(PatchWizardDialog dialog) {
fDialog= dialog;
}
public void showPage(IWizardPage page) {
fDialog.showPage(page);
}
}