org.grails.ide.eclipse.ui.internal.properties.InstalledGrailsInstallBlock.java Source code

Java tutorial

Introduction

Here is the source code for org.grails.ide.eclipse.ui.internal.properties.InstalledGrailsInstallBlock.java

Source

/*******************************************************************************
 * Copyright (c) 2012 VMWare, Inc.
 * 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
 * https://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     VMWare, Inc. - initial API and implementation
 *******************************************************************************/
package org.grails.ide.eclipse.ui.internal.properties;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.ListenerList;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.ui.ISharedImages;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
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.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.grails.ide.eclipse.core.GrailsCoreActivator;
import org.grails.ide.eclipse.core.internal.model.DefaultGrailsInstall;
import org.grails.ide.eclipse.core.model.IGrailsInstall;

import org.grails.ide.eclipse.ui.GrailsUiActivator;

/**
 * @author Christian Dupuis
 * @author Steffen Pingel
 * @author Kris De Volder
 */
@SuppressWarnings("restriction")
public class InstalledGrailsInstallBlock implements ISelectionProvider {

    private static final int[] defaultColumnWidth = { 140, 280 };

    /**
     * This block's control
     */
    private Composite fControl;

    /**
     * VMs being displayed
     */
    private List<IGrailsInstall> fVMs = new ArrayList<IGrailsInstall>();

    /**
     * The main list control
     */
    private CheckboxTableViewer fVMList;

    // Action buttons
    private Button fAddButton;

    private Button fRemoveButton;

    private Button fEditButton;

    // index of column used for sorting
    private int fSortColumn = 0;

    /**
     * Selection listeners (checked JRE changes)
     */
    private ListenerList fSelectionListeners = new ListenerList();

    /**
     * Previous selection
     */
    private ISelection fPrevSelection = new StructuredSelection();

    private Table fTable;

    /**
     * Content provider to show a list of JREs
     */
    class JREsContentProvider implements IStructuredContentProvider {
        public Object[] getElements(Object input) {
            return fVMs.toArray();
        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }

        public void dispose() {
        }
    }

    /**
     * Label provider for installed JREs table.
     */
    class VMLabelProvider extends LabelProvider implements ITableLabelProvider {

        private Image errorImg;

        /**
         * @see ITableLabelProvider#getColumnText(Object, int)
         */
        public String getColumnText(Object element, int columnIndex) {
            if (element instanceof IGrailsInstall) {
                IGrailsInstall vm = (IGrailsInstall) element;
                switch (columnIndex) {
                case 0:
                    return vm.getName();
                case 1:
                    return vm.getHome();
                }
            }
            return element.toString();
        }

        /**
         * @see ITableLabelProvider#getColumnImage(Object, int)
         */
        public Image getColumnImage(Object element, int columnIndex) {
            if (columnIndex == 0) {
                IGrailsInstall install = (IGrailsInstall) element;
                if (install.verify().isOK()) {
                    return JavaUI.getSharedImages().getImage(ISharedImages.IMG_OBJS_LIBRARY);
                } else {
                    return getErrorImage();
                }
            }
            return null;
        }

        private Image getErrorImage() {
            if (errorImg == null) {
                errorImg = GrailsUiActivator.getImageDescriptor("icons/full/obj16/error.gif").createImage(true);
            }
            return errorImg;
        }

        @Override
        public void dispose() {
            super.dispose();
            if (errorImg != null) {
                errorImg.dispose();
            }
        }

    }

    public void addSelectionChangedListener(ISelectionChangedListener listener) {
        fSelectionListeners.add(listener);
    }

    public ISelection getSelection() {
        return new StructuredSelection(fVMList.getCheckedElements());
    }

    public void removeSelectionChangedListener(ISelectionChangedListener listener) {
        fSelectionListeners.remove(listener);
    }

    public void setSelection(ISelection selection) {
        if (selection instanceof IStructuredSelection) {
            if (!selection.equals(fPrevSelection)) {
                fPrevSelection = selection;
                Object jre = ((IStructuredSelection) selection).getFirstElement();
                if (jre == null) {
                    fVMList.setCheckedElements(new Object[0]);
                } else {
                    fVMList.setCheckedElements(new Object[] { jre });
                    fVMList.reveal(jre);
                }
                fireSelectionChanged();
            }
        }
    }

    public void createControl(Composite ancestor) {
        Font font = ancestor.getFont();
        Composite parent = SWTFactory.createComposite(ancestor, font, 2, 1, GridData.FILL_BOTH);
        GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);
        fControl = parent;

        SWTFactory.createLabel(parent, "Grails Installations:", 2);

        fTable = new Table(parent, SWT.CHECK | SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
        fTable.setFont(font);
        fTable.setHeaderVisible(true);
        fTable.setLinesVisible(true);

        //      GridData gd = new GridData(GridData.FILL_BOTH);
        //      gd.heightHint = 250;
        //      gd.widthHint = 350;
        GridDataFactory.fillDefaults().hint(350, 250).grab(true, true).applyTo(fTable);

        TableColumn column = new TableColumn(fTable, SWT.LEFT);
        column.setText("Name");
        column.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                sortByName();
            }
        });

        column = new TableColumn(fTable, SWT.LEFT);
        column.setText("Location");
        column.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                sortByLocation();
            }
        });

        fVMList = new CheckboxTableViewer(fTable);
        fVMList.setLabelProvider(new VMLabelProvider());
        fVMList.setContentProvider(new JREsContentProvider());
        // by default, sort by name
        sortByName();

        fVMList.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent evt) {
                enableButtons();
            }
        });

        fVMList.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                if (event.getChecked()) {
                    setCheckedJRE((IGrailsInstall) event.getElement());
                } else {
                    setCheckedJRE(null);
                }
            }
        });

        fVMList.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent e) {
                if (!fVMList.getSelection().isEmpty()) {
                    editVM();
                }
            }
        });
        fTable.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent event) {
                if (event.character == SWT.DEL && event.stateMask == 0) {
                    if (fRemoveButton.isEnabled()) {
                        removeVMs();
                    }
                }
            }
        });

        Composite buttons = SWTFactory.createComposite(parent, font, 1, 1, GridData.VERTICAL_ALIGN_BEGINNING, 0, 0);

        fAddButton = SWTFactory.createPushButton(buttons, "Add...", null);
        fAddButton.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event evt) {
                addVM();
            }
        });

        fEditButton = SWTFactory.createPushButton(buttons, "Edit...", null);
        fEditButton.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event evt) {
                editVM();
            }
        });

        fRemoveButton = SWTFactory.createPushButton(buttons, "Remove...", null);
        fRemoveButton.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event evt) {
                removeVMs();
            }
        });

        SWTFactory.createVerticalSpacer(parent, 1);

        fillWithWorkspaceJREs();
        enableButtons();
        fAddButton.setEnabled(JavaRuntime.getVMInstallTypes().length > 0);
    }

    /**
     * Compares the given name against current names and adds the appropriate numerical suffix to ensure that it is
     * unique.
     * @param name the name with which to ensure uniqueness
     * @return the unique version of the given name
     * @since 3.2
     */
    public String generateName(String name, IGrailsInstall install) {
        if (!isDuplicateName(name, install)) {
            return name;
        }

        if (name.matches(".*\\(\\d*\\)")) { //$NON-NLS-1$
            int start = name.lastIndexOf('(');
            int end = name.lastIndexOf(')');
            String stringInt = name.substring(start + 1, end);
            int numericValue = Integer.parseInt(stringInt);
            String newName = name.substring(0, start + 1) + (numericValue + 1) + ")"; //$NON-NLS-1$
            return generateName(newName, install);
        } else {
            return generateName(name + " (1)", install); //$NON-NLS-1$
        }
    }

    /**
     * Fire current selection
     */
    private void fireSelectionChanged() {
        SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());
        Object[] listeners = fSelectionListeners.getListeners();
        for (int i = 0; i < listeners.length; i++) {
            ISelectionChangedListener listener = (ISelectionChangedListener) listeners[i];
            listener.selectionChanged(event);
        }
    }

    /**
     * Sorts by VM name.
     */
    private void sortByName() {
        fVMList.setComparator(new ViewerComparator() {
            public int compare(Viewer viewer, Object e1, Object e2) {
                if ((e1 instanceof IGrailsInstall) && (e2 instanceof IGrailsInstall)) {
                    IGrailsInstall left = (IGrailsInstall) e1;
                    IGrailsInstall right = (IGrailsInstall) e2;
                    return left.getName().compareToIgnoreCase(right.getName());
                }
                return super.compare(viewer, e1, e2);
            }

            public boolean isSorterProperty(Object element, String property) {
                return true;
            }
        });
        fSortColumn = 1;
    }

    /**
     * Sorts by VM location.
     */
    private void sortByLocation() {
        fVMList.setComparator(new ViewerComparator() {
            public int compare(Viewer viewer, Object e1, Object e2) {
                if ((e1 instanceof IGrailsInstall) && (e2 instanceof IGrailsInstall)) {
                    IGrailsInstall left = (IGrailsInstall) e1;
                    IGrailsInstall right = (IGrailsInstall) e2;
                    return left.getHome().compareToIgnoreCase(right.getHome());
                }
                return super.compare(viewer, e1, e2);
            }

            public boolean isSorterProperty(Object element, String property) {
                return true;
            }
        });
        fSortColumn = 2;
    }

    /**
     * Enables the buttons based on selected items counts in the viewer
     */
    private void enableButtons() {
        IStructuredSelection selection = (IStructuredSelection) fVMList.getSelection();
        int selectionCount = selection.size();
        fEditButton.setEnabled(selectionCount == 1);
        if (selectionCount > 0 && selectionCount < fVMList.getTable().getItemCount()) {
            fRemoveButton.setEnabled(true);
        } else {
            fRemoveButton.setEnabled(false);
        }
    }

    /**
     * Returns this block's control
     * 
     * @return control
     */
    public Control getControl() {
        return fControl;
    }

    /**
     * Sets the JREs to be displayed in this block
     * 
     * @param vms JREs to be displayed
     */
    protected void setJREs(IGrailsInstall[] vms) {
        fVMs.clear();
        for (int i = 0; i < vms.length; i++) {
            fVMs.add(vms[i]);
        }
        fVMList.setInput(fVMs);
        fVMList.refresh();

        for (IGrailsInstall install : vms) {
            if (install.isDefault()) {
                setCheckedJRE(install);
            }
        }
    }

    /**
     * Returns the JREs currently being displayed in this block
     * 
     * @return JREs currently being displayed in this block
     */
    public IGrailsInstall[] getJREs() {
        return fVMs.toArray(new IGrailsInstall[fVMs.size()]);
    }

    /**
     * Bring up a wizard that lets the user create a new VM definition.
     */
    private void addVM() {
        GrailsInstallDialog wizard = new GrailsInstallDialog(getShell(),
                new DefaultGrailsInstall(null, null, false), this);
        if (wizard.open() == Window.OK) {
            IGrailsInstall result = wizard.getResult();
            if (result != null) {
                fVMs.add(result);
                fVMList.refresh();
                Object[] checkedElements = fVMList.getCheckedElements();
                if (checkedElements == null || checkedElements.length == 0) {
                    fVMList.setSelection(new StructuredSelection(result));
                    setSelection(new StructuredSelection(result));
                }
            }
        }
    }

    public void vmAdded(IGrailsInstall vm) {
        fVMs.add(vm);
        fVMList.refresh();
    }

    public boolean isDuplicateName(String name, IGrailsInstall install) {
        if (install != null) {
            if (install.getName() != null && install.getName().equals(name)) {
                return false;
            }
        }
        for (int i = 0; i < fVMs.size(); i++) {
            IGrailsInstall vm = fVMs.get(i);
            if (vm.getName().equals(name)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Performs the edit VM action when the Edit... button is pressed
     */
    private void editVM() {
        IStructuredSelection selection = (IStructuredSelection) fVMList.getSelection();
        IGrailsInstall vm = (IGrailsInstall) selection.getFirstElement();
        if (vm == null) {
            return;
        }
        GrailsInstallDialog wizard = new GrailsInstallDialog(getShell(), vm, this);
        if (wizard.open() == Window.OK) {
            IGrailsInstall result = wizard.getResult();
            if (result != null) {
                // replace with the edited VM
                int index = fVMs.indexOf(vm);
                fVMs.remove(index);
                fVMs.add(index, result);
                fVMList.refresh();
                fVMList.setSelection(new StructuredSelection(result));
                fireSelectionChanged();
            }
        }
    }

    /**
     * Performs the remove VM(s) action when the Remove... button is pressed
     */
    @SuppressWarnings("unchecked")
    private void removeVMs() {
        IStructuredSelection selection = (IStructuredSelection) fVMList.getSelection();
        IGrailsInstall[] vms = new IGrailsInstall[selection.size()];
        Iterator<IGrailsInstall> iter = selection.iterator();
        int i = 0;
        while (iter.hasNext()) {
            vms[i] = iter.next();
            i++;
        }
        removeJREs(vms);
    }

    /**
     * Removes the given VMs from the table.
     * 
     * @param vms
     */
    public void removeJREs(IGrailsInstall[] vms) {
        IStructuredSelection prev = (IStructuredSelection) getSelection();
        for (int i = 0; i < vms.length; i++) {
            fVMs.remove(vms[i]);
        }
        fVMList.refresh();
        IStructuredSelection curr = (IStructuredSelection) getSelection();
        if (!curr.equals(prev)) {
            IGrailsInstall[] installs = getJREs();
            if (curr.size() == 0 && installs.length == 1) {
                // pick a default VM automatically
                setSelection(new StructuredSelection(installs[0]));
            }
        }
        fireSelectionChanged();
    }

    protected Shell getShell() {
        return getControl().getShell();
    }

    /**
     * Sets the checked JRE, possible <code>null</code>
     * 
     * @param vm JRE or <code>null</code>
     */
    public void setCheckedJRE(IGrailsInstall vm) {
        if (vm == null) {
            setSelection(new StructuredSelection());
        } else {
            setSelection(new StructuredSelection(vm));
        }
    }

    /**
     * Returns the checked JRE or <code>null</code> if none.
     * 
     * @return the checked JRE or <code>null</code> if none
     */
    public IGrailsInstall getCheckedJRE() {
        Object[] objects = fVMList.getCheckedElements();
        if (objects.length == 0) {
            return null;
        }
        return (IGrailsInstall) objects[0];
    }

    /**
     * Persist table settings into the give dialog store, prefixed with the given key.
     * 
     * @param settings dialog store
     * @param qualifier key qualifier
     */
    public void saveColumnSettings(IDialogSettings settings, String qualifier) {
        int columnCount = fTable.getColumnCount();
        for (int i = 0; i < columnCount; i++) {
            settings.put(qualifier + ".columnWidth" + i, fTable.getColumn(i).getWidth()); //$NON-NLS-1$
        }
        settings.put(qualifier + ".sortColumn", fSortColumn); //$NON-NLS-1$
    }

    /**
     * Restore table settings from the given dialog store using the given key.
     * 
     * @param settings dialog settings store
     * @param qualifier key to restore settings from
     */
    public void restoreColumnSettings(IDialogSettings settings, String qualifier) {
        fVMList.getTable().layout(true);
        restoreColumnWidths(settings, qualifier);
        try {
            fSortColumn = settings.getInt(qualifier + ".sortColumn"); //$NON-NLS-1$
        } catch (NumberFormatException e) {
            fSortColumn = 1;
        }
        switch (fSortColumn) {
        case 1:
            sortByName();
            break;
        case 2:
            sortByLocation();
            break;
        }
    }

    /**
     * Restores the column widths from dialog settings
     * @param settings
     * @param qualifier
     */
    private void restoreColumnWidths(IDialogSettings settings, String qualifier) {
        int columnCount = fTable.getColumnCount();
        for (int i = 0; i < columnCount; i++) {
            int width = -1;
            try {
                width = settings.getInt(qualifier + ".columnWidth" + i); //$NON-NLS-1$
            } catch (NumberFormatException e) {
            }

            if (width > 0) {
                fTable.getColumn(i).setWidth(width);
            } else {
                fTable.getColumn(i).setWidth(defaultColumnWidth[i]);
            }
        }
    }

    /**
     * Populates the JRE table with existing JREs defined in the workspace.
     */
    protected void fillWithWorkspaceJREs() {
        Collection<IGrailsInstall> installs = GrailsCoreActivator.getDefault().getInstallManager().getAllInstalls();
        setJREs(installs.toArray(new IGrailsInstall[installs.size()]));
    }

}