org.eclipse.ltk.internal.ui.refactoring.ChangeExceptionHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.ltk.internal.ui.refactoring.ChangeExceptionHandler.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2012 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.ltk.internal.ui.refactoring;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;

import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.Refactoring;

public class ChangeExceptionHandler {

    private Shell fParent;
    private String fName;

    private static class RefactorErrorDialog extends ErrorDialog {
        public RefactorErrorDialog(Shell parentShell, String dialogTitle, String dialogMessage, IStatus status,
                int displayMask) {
            super(parentShell, dialogTitle, dialogMessage, status, displayMask);
        }

        protected void createButtonsForButtonBar(Composite parent) {
            super.createButtonsForButtonBar(parent);
            Button ok = getButton(IDialogConstants.OK_ID);
            ok.setText(RefactoringUIMessages.ChangeExceptionHandler_undo);
            Button abort = createButton(parent, IDialogConstants.CANCEL_ID,
                    RefactoringUIMessages.ChangeExceptionHandler_abort, true);
            abort.moveBelow(ok);
            abort.setFocus();
        }

        protected Control createMessageArea(Composite parent) {
            Control result = super.createMessageArea(parent);

            // Panic code: use 'parent' instead of 'result' in case super implementation changes in the future
            new Label(parent, SWT.NONE); // filler as parent has 2 columns (icon and label)
            Label label = new Label(parent, SWT.NONE);
            label.setText(RefactoringUIMessages.ChangeExceptionHandler_button_explanation);
            label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

            applyDialogFont(result);
            return result;
        }
    }

    public ChangeExceptionHandler(Shell parent, Refactoring refactoring) {
        fParent = parent;
        fName = refactoring.getName();
    }

    public void handle(Change change, RuntimeException exception) {
        RefactoringUIPlugin.log(exception);
        IStatus status = null;
        if (exception.getMessage() == null) {
            status = new Status(IStatus.ERROR, RefactoringUIPlugin.getPluginId(), IStatus.ERROR,
                    RefactoringUIMessages.ChangeExceptionHandler_no_details, exception);
        } else {
            status = new Status(IStatus.ERROR, RefactoringUIPlugin.getPluginId(), IStatus.ERROR,
                    exception.getMessage(), exception);
        }
        handle(change, status);
    }

    public void handle(Change change, CoreException exception) {
        RefactoringUIPlugin.log(exception);
        handle(change, exception.getStatus());
    }

    private void handle(Change change, IStatus status) {
        if (change instanceof CompositeChange) {
            Change undo = ((CompositeChange) change).getUndoUntilException();
            if (undo != null) {
                RefactoringUIPlugin.log(status);
                final ErrorDialog dialog = new RefactorErrorDialog(fParent, change.getName(),
                        Messages.format(RefactoringUIMessages.ChangeExceptionHandler_unexpected_exception, fName),
                        status, IStatus.OK | IStatus.INFO | IStatus.WARNING | IStatus.ERROR);
                int result = dialog.open();
                if (result == IDialogConstants.OK_ID) {
                    performUndo(undo);
                }
                return;
            }
        }
        ErrorDialog dialog = new ErrorDialog(fParent, change.getName(),
                Messages.format(RefactoringUIMessages.ChangeExceptionHandler_unexpected_exception, fName), status,
                IStatus.OK | IStatus.INFO | IStatus.WARNING | IStatus.ERROR);
        dialog.open();
    }

    private void performUndo(final Change undo) {
        IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
            public void run(IProgressMonitor monitor) throws CoreException {
                monitor.beginTask("", 11); //$NON-NLS-1$
                try {
                    undo.initializeValidationData(
                            new NotCancelableProgressMonitor(new SubProgressMonitor(monitor, 1)));
                    if (undo.isValid(new SubProgressMonitor(monitor, 1)).hasFatalError()) {
                        monitor.done();
                        return;
                    }
                    undo.perform(new SubProgressMonitor(monitor, 9));
                } finally {
                    undo.dispose();
                }
            }
        };
        WorkbenchRunnableAdapter adapter = new WorkbenchRunnableAdapter(runnable,
                ResourcesPlugin.getWorkspace().getRoot());
        ProgressMonitorDialog dialog = new ProgressMonitorDialog(fParent);
        try {
            dialog.run(false, false, adapter);
        } catch (InvocationTargetException e) {
            ExceptionHandler.handle(e, fParent, RefactoringUIMessages.ChangeExceptionHandler_rollback_title,
                    RefactoringUIMessages.ChangeExceptionHandler_rollback_message + fName);
        } catch (InterruptedException e) {
            // can't happen
        }
    }
}