ext.org.eclipse.jdt.internal.ui.refactoring.code.ExtractMethodInputPage.java Source code

Java tutorial

Introduction

Here is the source code for ext.org.eclipse.jdt.internal.ui.refactoring.code.ExtractMethodInputPage.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2011 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
 *     Benjamin Muskalla <bmuskalla@eclipsesource.com> - [extract method] remember selected access modifier - https://bugs.eclipse.org/bugs/show_bug.cgi?id=101233
 *******************************************************************************/
package ext.org.eclipse.jdt.internal.ui.refactoring.code;

import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;

import org.eclipse.jface.text.Document;

import org.eclipse.ui.PlatformUI;

import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.ui.PreferenceConstants;
import patch.org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration;

import patch.org.eclipse.jdt.internal.ui.JavaPlugin;

import ext.org.eclipse.jdt.internal.corext.dom.ASTNodes;
import ext.org.eclipse.jdt.internal.corext.refactoring.ParameterInfo;
import ext.org.eclipse.jdt.internal.corext.refactoring.code.ExtractMethodRefactoring;
import ext.org.eclipse.jdt.internal.corext.util.Messages;
import ext.org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import ext.org.eclipse.jdt.internal.ui.JavaPluginImages;
import ext.org.eclipse.jdt.internal.ui.dialogs.TextFieldNavigationHandler;
import ext.org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer;
import ext.org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
import ext.org.eclipse.jdt.internal.ui.refactoring.ChangeParametersControl;
import ext.org.eclipse.jdt.internal.ui.refactoring.IParameterListChangeListener;
import ext.org.eclipse.jdt.internal.ui.refactoring.RefactoringMessages;
import ext.org.eclipse.jdt.internal.ui.util.RowLayouter;
import ext.org.eclipse.jdt.internal.ui.util.SWTUtil;
import ext.org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;

public class ExtractMethodInputPage extends UserInputWizardPage {

    public static final String PAGE_NAME = "ExtractMethodInputPage";//$NON-NLS-1$

    private ExtractMethodRefactoring fRefactoring;
    private Text fTextField;
    private boolean fFirstTime;
    private JavaSourceViewer fSignaturePreview;
    private Document fSignaturePreviewDocument;
    private IDialogSettings fSettings;

    private static final String DESCRIPTION = RefactoringMessages.ExtractMethodInputPage_description;
    private static final String THROW_RUNTIME_EXCEPTIONS = "ThrowRuntimeExceptions"; //$NON-NLS-1$
    private static final String GENERATE_JAVADOC = "GenerateJavadoc"; //$NON-NLS-1$
    private static final String ACCESS_MODIFIER = "AccessModifier"; //$NON-NLS-1$

    public ExtractMethodInputPage() {
        super(PAGE_NAME);
        setImageDescriptor(JavaPluginImages.DESC_WIZBAN_REFACTOR_CU);
        setDescription(DESCRIPTION);
        fFirstTime = true;
        fSignaturePreviewDocument = new Document();
    }

    public void createControl(Composite parent) {
        fRefactoring = (ExtractMethodRefactoring) getRefactoring();
        loadSettings();

        Composite result = new Composite(parent, SWT.NONE);
        setControl(result);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        result.setLayout(layout);
        RowLayouter layouter = new RowLayouter(2);
        GridData gd = null;

        initializeDialogUnits(result);

        Label label = new Label(result, SWT.NONE);
        label.setText(getLabelText());

        fTextField = createTextInputField(result, SWT.BORDER);
        fTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        layouter.perform(label, fTextField, 1);

        ASTNode[] destinations = fRefactoring.getDestinations();
        if (destinations.length > 1) {
            label = new Label(result, SWT.NONE);
            label.setText(RefactoringMessages.ExtractMethodInputPage_destination_type);
            final Combo combo = new Combo(result, SWT.READ_ONLY | SWT.DROP_DOWN);
            SWTUtil.setDefaultVisibleItemCount(combo);
            for (int i = 0; i < destinations.length; i++) {
                ASTNode declaration = destinations[i];
                combo.add(getLabel(declaration));
            }
            combo.select(0);
            combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
            combo.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    fRefactoring.setDestination(combo.getSelectionIndex());
                    updatePreview(getText());
                }
            });
        }

        label = new Label(result, SWT.NONE);
        label.setText(RefactoringMessages.ExtractMethodInputPage_access_Modifiers);

        Composite group = new Composite(result, SWT.NONE);
        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        layout = new GridLayout();
        layout.numColumns = 4;
        layout.marginWidth = 0;
        group.setLayout(layout);

        String[] labels = new String[] { RefactoringMessages.ExtractMethodInputPage_public,
                RefactoringMessages.ExtractMethodInputPage_protected,
                RefactoringMessages.ExtractMethodInputPage_default,
                RefactoringMessages.ExtractMethodInputPage_private };
        Integer[] data = new Integer[] { new Integer(Modifier.PUBLIC), new Integer(Modifier.PROTECTED),
                new Integer(Modifier.NONE), new Integer(Modifier.PRIVATE) };
        Integer visibility = new Integer(fRefactoring.getVisibility());
        for (int i = 0; i < labels.length; i++) {
            Button radio = new Button(group, SWT.RADIO);
            radio.setText(labels[i]);
            radio.setData(data[i]);
            if (data[i].equals(visibility))
                radio.setSelection(true);
            radio.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent event) {
                    final Integer selectedModifier = (Integer) event.widget.getData();
                    fSettings.put(ACCESS_MODIFIER, selectedModifier.intValue());
                    setVisibility(selectedModifier);
                }
            });
        }
        layouter.perform(label, group, 1);

        if (!fRefactoring.getParameterInfos().isEmpty()) {
            ChangeParametersControl cp = new ChangeParametersControl(result, SWT.NONE,
                    RefactoringMessages.ExtractMethodInputPage_parameters, new IParameterListChangeListener() {
                        public void parameterChanged(ParameterInfo parameter) {
                            parameterModified();
                        }

                        public void parameterListChanged() {
                            parameterModified();
                        }

                        public void parameterAdded(ParameterInfo parameter) {
                            updatePreview(getText());
                        }
                    }, ChangeParametersControl.Mode.EXTRACT_METHOD);
            gd = new GridData(GridData.FILL_BOTH);
            gd.horizontalSpan = 2;
            cp.setLayoutData(gd);
            cp.setInput(fRefactoring.getParameterInfos());
        }

        Button checkBox = new Button(result, SWT.CHECK);
        checkBox.setText(RefactoringMessages.ExtractMethodInputPage_throwRuntimeExceptions);
        checkBox.setSelection(fSettings.getBoolean(THROW_RUNTIME_EXCEPTIONS));
        checkBox.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                setRethrowRuntimeException(((Button) e.widget).getSelection());
            }
        });
        layouter.perform(checkBox);

        checkBox = new Button(result, SWT.CHECK);
        checkBox.setText(RefactoringMessages.ExtractMethodInputPage_generateJavadocComment);
        boolean generate = computeGenerateJavadoc();
        setGenerateJavadoc(generate);
        checkBox.setSelection(generate);
        checkBox.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                setGenerateJavadoc(((Button) e.widget).getSelection());
            }
        });
        layouter.perform(checkBox);

        int duplicates = fRefactoring.getNumberOfDuplicates();
        checkBox = new Button(result, SWT.CHECK);
        if (duplicates == 0) {
            checkBox.setText(RefactoringMessages.ExtractMethodInputPage_duplicates_none);
        } else if (duplicates == 1) {
            checkBox.setText(RefactoringMessages.ExtractMethodInputPage_duplicates_single);
        } else {
            checkBox.setText(Messages.format(RefactoringMessages.ExtractMethodInputPage_duplicates_multi,
                    new Integer(duplicates)));
        }
        checkBox.setSelection(fRefactoring.getReplaceDuplicates());
        checkBox.setEnabled(duplicates > 0);
        checkBox.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                fRefactoring.setReplaceDuplicates(((Button) e.widget).getSelection());
            }
        });
        layouter.perform(checkBox);

        label = new Label(result, SWT.SEPARATOR | SWT.HORIZONTAL);
        label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        layouter.perform(label);

        createSignaturePreview(result, layouter);

        Dialog.applyDialogFont(result);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
                IJavaHelpContextIds.EXTRACT_METHOD_WIZARD_PAGE);
    }

    private String getLabel(ASTNode node) {
        if (node instanceof AbstractTypeDeclaration) {
            return ((AbstractTypeDeclaration) node).getName().getIdentifier();
        } else if (node instanceof AnonymousClassDeclaration) {
            if (node.getLocationInParent() == ClassInstanceCreation.ANONYMOUS_CLASS_DECLARATION_PROPERTY) {
                ClassInstanceCreation creation = (ClassInstanceCreation) node.getParent();
                return Messages.format(RefactoringMessages.ExtractMethodInputPage_anonymous_type_label,
                        BasicElementLabels.getJavaElementName(ASTNodes.asString(creation.getType())));
            } else if (node.getLocationInParent() == EnumConstantDeclaration.ANONYMOUS_CLASS_DECLARATION_PROPERTY) {
                EnumConstantDeclaration decl = (EnumConstantDeclaration) node.getParent();
                return decl.getName().getIdentifier();
            }
        }
        return "UNKNOWN"; //$NON-NLS-1$
    }

    private Text createTextInputField(Composite parent, int style) {
        Text result = new Text(parent, style);
        result.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                textModified(getText());
            }
        });
        TextFieldNavigationHandler.install(result);
        return result;
    }

    private String getText() {
        if (fTextField == null)
            return null;
        return fTextField.getText();
    }

    private String getLabelText() {
        return RefactoringMessages.ExtractMethodInputPage_label_text;
    }

    private void setVisibility(Integer visibility) {
        fRefactoring.setVisibility(visibility.intValue());
        updatePreview(getText());
    }

    private void setRethrowRuntimeException(boolean value) {
        fSettings.put(THROW_RUNTIME_EXCEPTIONS, value);
        fRefactoring.setThrowRuntimeExceptions(value);
        updatePreview(getText());
    }

    private boolean computeGenerateJavadoc() {
        boolean result = fRefactoring.getGenerateJavadoc();
        if (result)
            return result;
        return fSettings.getBoolean(GENERATE_JAVADOC);
    }

    private void setGenerateJavadoc(boolean value) {
        fSettings.put(GENERATE_JAVADOC, value);
        fRefactoring.setGenerateJavadoc(value);
    }

    private void createSignaturePreview(Composite composite, RowLayouter layouter) {
        Label previewLabel = new Label(composite, SWT.NONE);
        previewLabel.setText(RefactoringMessages.ExtractMethodInputPage_signature_preview);
        layouter.perform(previewLabel);

        IPreferenceStore store = JavaPlugin.getDefault().getCombinedPreferenceStore();
        fSignaturePreview = new JavaSourceViewer(composite, null, null, false,
                SWT.READ_ONLY | SWT.V_SCROLL | SWT.WRAP /*| SWT.BORDER*/, store);
        fSignaturePreview.configure(new JavaSourceViewerConfiguration(
                JavaPlugin.getDefault().getJavaTextTools().getColorManager(), store, null, null));
        fSignaturePreview.getTextWidget().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT));
        fSignaturePreview.adaptBackgroundColor(composite);
        fSignaturePreview.setDocument(fSignaturePreviewDocument);
        fSignaturePreview.setEditable(false);

        //Layouting problems with wrapped text: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=9866
        Control signaturePreviewControl = fSignaturePreview.getControl();
        PixelConverter pixelConverter = new PixelConverter(signaturePreviewControl);
        GridData gdata = new GridData(GridData.FILL_BOTH);
        gdata.widthHint = pixelConverter.convertWidthInCharsToPixels(50);
        gdata.heightHint = pixelConverter.convertHeightInCharsToPixels(2);
        signaturePreviewControl.setLayoutData(gdata);
        layouter.perform(signaturePreviewControl);
    }

    private void updatePreview(String text) {
        if (fSignaturePreview == null)
            return;

        if (text.length() == 0)
            text = "someMethodName"; //$NON-NLS-1$

        int top = fSignaturePreview.getTextWidget().getTopPixel();
        String signature;
        try {
            signature = fRefactoring.getSignature(text);
        } catch (IllegalArgumentException e) {
            signature = ""; //$NON-NLS-1$
        }
        fSignaturePreviewDocument.set(signature);
        fSignaturePreview.getTextWidget().setTopPixel(top);
    }

    private void loadSettings() {
        fSettings = getDialogSettings().getSection(ExtractMethodWizard.DIALOG_SETTING_SECTION);
        if (fSettings == null) {
            fSettings = getDialogSettings().addNewSection(ExtractMethodWizard.DIALOG_SETTING_SECTION);
            fSettings.put(THROW_RUNTIME_EXCEPTIONS, false);
            fSettings.put(GENERATE_JAVADOC, JavaPreferencesSettings
                    .getCodeGenerationSettings(fRefactoring.getCompilationUnit().getJavaProject()).createComments);
            fSettings.put(ACCESS_MODIFIER, Modifier.PRIVATE);
        }
        fRefactoring.setThrowRuntimeExceptions(fSettings.getBoolean(THROW_RUNTIME_EXCEPTIONS));
        final String accessModifier = fSettings.get(ACCESS_MODIFIER);
        if (accessModifier != null) {
            fRefactoring.setVisibility(Integer.parseInt(accessModifier));
        }
    }

    //---- Input validation ------------------------------------------------------

    @Override
    public void setVisible(boolean visible) {
        if (visible) {
            if (fFirstTime) {
                fFirstTime = false;
                setPageComplete(false);
                updatePreview(getText());
                fTextField.setFocus();
            } else {
                setPageComplete(validatePage(true));
            }
        }
        super.setVisible(visible);
    }

    private void textModified(String text) {
        fRefactoring.setMethodName(text);
        RefactoringStatus status = validatePage(true);
        if (!status.hasFatalError()) {
            updatePreview(text);
        } else {
            fSignaturePreviewDocument.set(""); //$NON-NLS-1$
        }
        setPageComplete(status);
    }

    private void parameterModified() {
        updatePreview(getText());
        setPageComplete(validatePage(false));
    }

    private RefactoringStatus validatePage(boolean text) {
        RefactoringStatus result = new RefactoringStatus();
        if (text) {
            result.merge(validateMethodName());
            result.merge(validateParameters());
        } else {
            result.merge(validateParameters());
            result.merge(validateMethodName());
        }
        return result;
    }

    private RefactoringStatus validateMethodName() {
        RefactoringStatus result = new RefactoringStatus();
        String text = getText();
        if ("".equals(text)) { //$NON-NLS-1$
            result.addFatalError(RefactoringMessages.ExtractMethodInputPage_validation_emptyMethodName);
            return result;
        }
        result.merge(fRefactoring.checkMethodName());
        return result;
    }

    private RefactoringStatus validateParameters() {
        RefactoringStatus result = new RefactoringStatus();
        List<ParameterInfo> parameters = fRefactoring.getParameterInfos();
        for (Iterator<ParameterInfo> iter = parameters.iterator(); iter.hasNext();) {
            ParameterInfo info = iter.next();
            if ("".equals(info.getNewName())) { //$NON-NLS-1$
                result.addFatalError(RefactoringMessages.ExtractMethodInputPage_validation_emptyParameterName);
                return result;
            }
        }
        result.merge(fRefactoring.checkParameterNames());
        result.merge(fRefactoring.checkVarargOrder());
        return result;
    }
}