ext.org.eclipse.jdt.internal.ui.preferences.ImportOrganizeConfigurationBlock.java Source code

Java tutorial

Introduction

Here is the source code for ext.org.eclipse.jdt.internal.ui.preferences.ImportOrganizeConfigurationBlock.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
 *******************************************************************************/
package ext.org.eclipse.jdt.internal.ui.preferences;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;

import org.eclipse.core.runtime.IStatus;

import org.eclipse.core.resources.IProject;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.window.Window;

import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;

import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.ui.JavaElementImageDescriptor;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.PreferenceConstants;

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

import ext.org.eclipse.jdt.internal.ui.JavaPluginImages;
import ext.org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
import ext.org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
import ext.org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
import ext.org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
import ext.org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
import ext.org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import ext.org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter;
import ext.org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
import ext.org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField;
import ext.org.eclipse.jdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
import ext.org.eclipse.jdt.internal.ui.wizards.dialogfields.StringDialogField;

/**
 * The page for setting the organize import settings.
 */
public class ImportOrganizeConfigurationBlock extends OptionsConfigurationBlock {

    private static final Key PREF_IMPORTORDER = getJDTUIKey(PreferenceConstants.ORGIMPORTS_IMPORTORDER);
    private static final Key PREF_ONDEMANDTHRESHOLD = getJDTUIKey(PreferenceConstants.ORGIMPORTS_ONDEMANDTHRESHOLD);
    private static final Key PREF_IGNORELOWERCASE = getJDTUIKey(PreferenceConstants.ORGIMPORTS_IGNORELOWERCASE);
    private static final Key PREF_STATICONDEMANDTHRESHOLD = getJDTUIKey(
            PreferenceConstants.ORGIMPORTS_STATIC_ONDEMANDTHRESHOLD);

    private static final String DIALOGSETTING_LASTLOADPATH = JavaUI.ID_PLUGIN + ".importorder.loadpath"; //$NON-NLS-1$
    private static final String DIALOGSETTING_LASTSAVEPATH = JavaUI.ID_PLUGIN + ".importorder.savepath"; //$NON-NLS-1$

    private static Key[] getAllKeys() {
        return new Key[] { PREF_IMPORTORDER, PREF_ONDEMANDTHRESHOLD, PREF_STATICONDEMANDTHRESHOLD,
                PREF_IGNORELOWERCASE };
    }

    public static class ImportOrderEntry {

        public final String name;
        public final boolean isStatic;

        public ImportOrderEntry(String name, boolean isStatic) {
            this.name = name;
            this.isStatic = isStatic;
        }

        public String serialize() {
            return isStatic ? '#' + name : name;
        }

        public static ImportOrderEntry fromSerialized(String str) {
            if (str.length() > 0 && str.charAt(0) == '#') {
                return new ImportOrderEntry(str.substring(1), true);
            }
            return new ImportOrderEntry(str, false);
        }

    }

    private static class ImportOrganizeLabelProvider extends LabelProvider {

        private final Image PCK_ICON;
        private final Image STATIC_CLASS_ICON;

        public ImportOrganizeLabelProvider() {
            PCK_ICON = JavaPluginImages.get(JavaPluginImages.IMG_OBJS_PACKAGE);
            STATIC_CLASS_ICON = JavaElementImageProvider.getDecoratedImage(JavaPluginImages.DESC_MISC_PUBLIC,
                    JavaElementImageDescriptor.STATIC, JavaElementImageProvider.SMALL_SIZE);
        }

        @Override
        public Image getImage(Object element) {
            return ((ImportOrderEntry) element).isStatic ? STATIC_CLASS_ICON : PCK_ICON;
        }

        @Override
        public String getText(Object element) {
            ImportOrderEntry entry = (ImportOrderEntry) element;
            String name = entry.name;
            if (name.length() > 0) {
                return BasicElementLabels.getJavaElementName(name);
            }
            if (entry.isStatic) {
                return PreferencesMessages.ImportOrganizeConfigurationBlock_other_static;
            }
            return PreferencesMessages.ImportOrganizeConfigurationBlock_other_normal;
        }
    }

    private class ImportOrganizeAdapter implements IListAdapter<ImportOrderEntry>, IDialogFieldListener {

        private boolean canEdit(ListDialogField<ImportOrderEntry> field) {
            List<ImportOrderEntry> selected = field.getSelectedElements();
            return selected.size() == 1;
        }

        public void customButtonPressed(ListDialogField<ImportOrderEntry> field, int index) {
            doButtonPressed(index);
        }

        public void selectionChanged(ListDialogField<ImportOrderEntry> field) {
            fOrderListField.enableButton(IDX_EDIT, canEdit(field));
        }

        public void dialogFieldChanged(DialogField field) {
            doDialogFieldChanged(field);
        }

        public void doubleClicked(ListDialogField<ImportOrderEntry> field) {
            if (canEdit(field)) {
                doButtonPressed(IDX_EDIT);
            }
        }
    }

    private static final int IDX_ADD = 0;
    private static final int IDX_ADD_STATIC = 1;
    private static final int IDX_EDIT = 2;
    private static final int IDX_REMOVE = 3;
    private static final int IDX_UP = 5;
    private static final int IDX_DOWN = 6;

    private ListDialogField<ImportOrderEntry> fOrderListField;
    private StringDialogField fThresholdField;
    private StringDialogField fStaticThresholdField;
    private SelectionButtonDialogField fIgnoreLowerCaseTypesField;
    private SelectionButtonDialogField fExportButton;
    private SelectionButtonDialogField fImportButton;

    private PixelConverter fPixelConverter;

    public ImportOrganizeConfigurationBlock(IStatusChangeListener context, IProject project,
            IWorkbenchPreferenceContainer container) {
        super(context, project, getAllKeys(), container);

        String[] buttonLabels = new String[] {
                PreferencesMessages.ImportOrganizeConfigurationBlock_order_add_button,
                PreferencesMessages.ImportOrganizeConfigurationBlock_order_add_static_button,
                PreferencesMessages.ImportOrganizeConfigurationBlock_order_edit_button,
                PreferencesMessages.ImportOrganizeConfigurationBlock_order_remove_button, /* 4 */ null,
                PreferencesMessages.ImportOrganizeConfigurationBlock_order_up_button,
                PreferencesMessages.ImportOrganizeConfigurationBlock_order_down_button, };

        ImportOrganizeAdapter adapter = new ImportOrganizeAdapter();

        fOrderListField = new ListDialogField<ImportOrderEntry>(adapter, buttonLabels,
                new ImportOrganizeLabelProvider());
        fOrderListField.setDialogFieldListener(adapter);
        fOrderListField.setLabelText(PreferencesMessages.ImportOrganizeConfigurationBlock_order_label);
        fOrderListField.setUpButtonIndex(IDX_UP);
        fOrderListField.setDownButtonIndex(IDX_DOWN);
        fOrderListField.setRemoveButtonIndex(IDX_REMOVE);

        fOrderListField.enableButton(IDX_EDIT, false);

        fImportButton = new SelectionButtonDialogField(SWT.PUSH);
        fImportButton.setDialogFieldListener(adapter);
        fImportButton.setLabelText(PreferencesMessages.ImportOrganizeConfigurationBlock_order_load_button);

        fExportButton = new SelectionButtonDialogField(SWT.PUSH);
        fExportButton.setDialogFieldListener(adapter);
        fExportButton.setLabelText(PreferencesMessages.ImportOrganizeConfigurationBlock_order_save_button);

        fThresholdField = new StringDialogField();
        fThresholdField.setDialogFieldListener(adapter);
        fThresholdField.setLabelText(PreferencesMessages.ImportOrganizeConfigurationBlock_threshold_label);

        fStaticThresholdField = new StringDialogField();
        fStaticThresholdField.setDialogFieldListener(adapter);
        fStaticThresholdField
                .setLabelText(PreferencesMessages.ImportOrganizeConfigurationBlock_staticthreshold_label);

        fIgnoreLowerCaseTypesField = new SelectionButtonDialogField(SWT.CHECK);
        fIgnoreLowerCaseTypesField.setDialogFieldListener(adapter);
        fIgnoreLowerCaseTypesField
                .setLabelText(PreferencesMessages.ImportOrganizeConfigurationBlock_ignoreLowerCase_label);

        updateControls();
    }

    @Override
    protected Control createContents(Composite parent) {
        setShell(parent.getShell());

        fPixelConverter = new PixelConverter(parent);

        Composite composite = new Composite(parent, SWT.NONE);
        composite.setFont(parent.getFont());

        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        layout.marginWidth = 0;
        layout.marginHeight = 0;

        composite.setLayout(layout);

        fOrderListField.doFillIntoGrid(composite, 3);
        LayoutUtil.setHorizontalSpan(fOrderListField.getLabelControl(null), 2);
        LayoutUtil.setWidthHint(fOrderListField.getLabelControl(null),
                fPixelConverter.convertWidthInCharsToPixels(60));
        LayoutUtil.setHorizontalGrabbing(fOrderListField.getListControl(null));

        Composite importExportComp = new Composite(composite, SWT.NONE);
        importExportComp.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, 2, 1));
        layout = new GridLayout();
        layout.numColumns = 2;
        layout.marginWidth = 0;
        layout.marginHeight = 0;

        importExportComp.setLayout(layout);

        fImportButton.doFillIntoGrid(importExportComp, 1);
        fExportButton.doFillIntoGrid(importExportComp, 1);

        fThresholdField.doFillIntoGrid(composite, 2);
        ((GridData) fThresholdField.getTextControl(null).getLayoutData()).grabExcessHorizontalSpace = false;
        fStaticThresholdField.doFillIntoGrid(composite, 2);
        fIgnoreLowerCaseTypesField.doFillIntoGrid(composite, 2);

        Dialog.applyDialogFont(composite);

        return composite;
    }

    private boolean doThresholdChanged(String thresholdString) {
        StatusInfo status = new StatusInfo();
        try {
            int threshold = Integer.parseInt(thresholdString);
            if (threshold < 0) {
                status.setError(PreferencesMessages.ImportOrganizeConfigurationBlock_error_invalidthreshold);
            }
        } catch (NumberFormatException e) {
            status.setError(PreferencesMessages.ImportOrganizeConfigurationBlock_error_invalidthreshold);
        }
        updateStatus(status);
        return status.isOK();
    }

    private void doButtonPressed(int index) {
        if (index == IDX_ADD || index == IDX_ADD_STATIC) { // add new
            List<ImportOrderEntry> existing = fOrderListField.getElements();
            ImportOrganizeInputDialog dialog = new ImportOrganizeInputDialog(getShell(), existing,
                    index == IDX_ADD_STATIC);
            if (dialog.open() == Window.OK) {
                List<ImportOrderEntry> selectedElements = fOrderListField.getSelectedElements();
                if (selectedElements.size() == 1) {
                    int insertionIndex = fOrderListField.getIndexOfElement(selectedElements.get(0)) + 1;
                    fOrderListField.addElement(dialog.getResult(), insertionIndex);
                } else {
                    fOrderListField.addElement(dialog.getResult());
                }
            }
        } else if (index == IDX_EDIT) { // edit
            List<ImportOrderEntry> selected = fOrderListField.getSelectedElements();
            if (selected.isEmpty()) {
                return;
            }
            ImportOrderEntry editedEntry = selected.get(0);

            List<ImportOrderEntry> existing = fOrderListField.getElements();
            existing.remove(editedEntry);

            ImportOrganizeInputDialog dialog = new ImportOrganizeInputDialog(getShell(), existing,
                    editedEntry.isStatic);
            dialog.setInitialSelection(editedEntry);
            if (dialog.open() == Window.OK) {
                fOrderListField.replaceElement(editedEntry, dialog.getResult());
            }
        }
    }

    /*
     * The import order file is a property file. The keys are
     * "0", "1" ... last entry. The values must be valid package names.
     */
    private List<ImportOrderEntry> loadFromProperties(Properties properties) {
        ArrayList<ImportOrderEntry> res = new ArrayList<ImportOrderEntry>();
        int nEntries = properties.size();
        for (int i = 0; i < nEntries; i++) {
            String curr = properties.getProperty(String.valueOf(i));
            if (curr != null) {
                ImportOrderEntry entry = ImportOrderEntry.fromSerialized(curr);
                if (entry.name.length() == 0 || !JavaConventions
                        .validatePackageName(entry.name, JavaCore.VERSION_1_3, JavaCore.VERSION_1_5)
                        .matches(IStatus.ERROR)) {
                    res.add(entry);
                } else {
                    return null;
                }
            } else {
                return res;
            }
        }
        return res;
    }

    private List<ImportOrderEntry> loadImportOrder() {
        IDialogSettings dialogSettings = JavaPlugin.getDefault().getDialogSettings();

        FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);
        dialog.setText(PreferencesMessages.ImportOrganizeConfigurationBlock_loadDialog_title);
        dialog.setFilterExtensions(new String[] { "*.importorder", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$
        String lastPath = dialogSettings.get(DIALOGSETTING_LASTLOADPATH);
        if (lastPath != null) {
            dialog.setFilterPath(lastPath);
        }
        String fileName = dialog.open();
        if (fileName != null) {
            dialogSettings.put(DIALOGSETTING_LASTLOADPATH, dialog.getFilterPath());

            Properties properties = new Properties();
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(fileName);
                properties.load(fis);
                List<ImportOrderEntry> res = loadFromProperties(properties);
                if (res != null) {
                    return res;
                }
            } catch (IOException e) {
                JavaPlugin.log(e);
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                    }
                }
            }
            String title = PreferencesMessages.ImportOrganizeConfigurationBlock_loadDialog_error_title;
            String message = PreferencesMessages.ImportOrganizeConfigurationBlock_loadDialog_error_message;
            MessageDialog.openError(getShell(), title, message);
        }
        return null;
    }

    private void saveImportOrder(List<ImportOrderEntry> elements) {
        IDialogSettings dialogSettings = JavaPlugin.getDefault().getDialogSettings();

        FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
        dialog.setText(PreferencesMessages.ImportOrganizeConfigurationBlock_saveDialog_title);
        dialog.setFilterExtensions(new String[] { "*.importorder", "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$
        dialog.setFileName("example"); //$NON-NLS-1$
        String lastPath = dialogSettings.get(DIALOGSETTING_LASTSAVEPATH);
        if (lastPath != null) {
            dialog.setFilterPath(lastPath);
        }
        String fileName = dialog.open();
        if (fileName != null) {
            dialogSettings.put(DIALOGSETTING_LASTSAVEPATH, dialog.getFilterPath());

            Properties properties = new Properties();
            for (int i = 0; i < elements.size(); i++) {
                ImportOrderEntry entry = elements.get(i);
                properties.setProperty(String.valueOf(i), entry.serialize());
            }
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(fileName);
                properties.store(fos, "Organize Import Order"); //$NON-NLS-1$
            } catch (IOException e) {
                JavaPlugin.log(e);
                String title = PreferencesMessages.ImportOrganizeConfigurationBlock_saveDialog_error_title;
                String message = PreferencesMessages.ImportOrganizeConfigurationBlock_saveDialog_error_message;
                MessageDialog.openError(getShell(), title, message);
            } finally {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                    }
                }
            }
        }
    }

    private void updateStatus(IStatus status) {
        fContext.statusChanged(status);
    }

    /* (non-Javadoc)
     * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#validateSettings(java.lang.String, java.lang.String)
     */
    @Override
    protected void validateSettings(Key changedKey, String oldValue, String newValue) {
        // no validation
    }

    /* (non-Javadoc)
     * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#updateControls()
     */
    @Override
    protected void updateControls() {
        ImportOrderEntry[] importOrder = getImportOrderPreference();
        int threshold = getImportNumberThreshold(PREF_ONDEMANDTHRESHOLD);
        int staticThreshold = getImportNumberThreshold(PREF_STATICONDEMANDTHRESHOLD);
        boolean ignoreLowerCase = Boolean.valueOf(getValue(PREF_IGNORELOWERCASE)).booleanValue();

        fOrderListField.removeAllElements();
        for (int i = 0; i < importOrder.length; i++) {
            fOrderListField.addElement(importOrder[i]);
        }
        fThresholdField.setText(String.valueOf(threshold));
        fStaticThresholdField.setText(String.valueOf(staticThreshold));
        fIgnoreLowerCaseTypesField.setSelection(ignoreLowerCase);
    }

    protected final void doDialogFieldChanged(DialogField field) {
        // set values in working copy
        if (field == fOrderListField) {
            setValue(PREF_IMPORTORDER, packOrderList(fOrderListField.getElements()));
        } else if (field == fThresholdField) {
            if (doThresholdChanged(fThresholdField.getText())) {
                setValue(PREF_ONDEMANDTHRESHOLD, fThresholdField.getText());
            }
        } else if (field == fStaticThresholdField) {
            if (doThresholdChanged(fStaticThresholdField.getText())) {
                setValue(PREF_STATICONDEMANDTHRESHOLD, fStaticThresholdField.getText());
            }
        } else if (field == fIgnoreLowerCaseTypesField) {
            setValue(PREF_IGNORELOWERCASE, fIgnoreLowerCaseTypesField.isSelected());
        } else if (field == fImportButton) {
            List<ImportOrderEntry> order = loadImportOrder();
            if (order != null) {
                fOrderListField.setElements(order);
            }
        } else if (field == fExportButton) {
            saveImportOrder(fOrderListField.getElements());
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#getFullBuildDialogStrings(boolean)
     */
    @Override
    protected String[] getFullBuildDialogStrings(boolean workspaceSettings) {
        return null; // no build required
    }

    private static ImportOrderEntry[] unpackOrderList(String str) {
        ArrayList<ImportOrderEntry> res = new ArrayList<ImportOrderEntry>();
        int start = 0;
        do {
            int end = str.indexOf(';', start);
            if (end == -1) {
                end = str.length();
            }
            res.add(ImportOrderEntry.fromSerialized(str.substring(start, end)));
            start = end + 1;
        } while (start < str.length());

        return res.toArray(new ImportOrderEntry[res.size()]);
    }

    private static String packOrderList(List<ImportOrderEntry> orderList) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < orderList.size(); i++) {
            ImportOrderEntry entry = orderList.get(i);
            buf.append(entry.serialize());
            buf.append(';');
        }
        return buf.toString();
    }

    private ImportOrderEntry[] getImportOrderPreference() {
        String str = getValue(PREF_IMPORTORDER);
        if (str != null) {
            return unpackOrderList(str);
        }
        return new ImportOrderEntry[0];
    }

    private int getImportNumberThreshold(Key key) {
        String thresholdStr = getValue(key);
        try {
            int threshold = Integer.parseInt(thresholdStr);
            if (threshold < 0) {
                threshold = Integer.MAX_VALUE;
            }
            return threshold;
        } catch (NumberFormatException e) {
            return Integer.MAX_VALUE;
        }
    }

}