de.defmacro.dandelion.internal.preferences.LispServerPreferencePage.java Source code

Java tutorial

Introduction

Here is the source code for de.defmacro.dandelion.internal.preferences.LispServerPreferencePage.java

Source

/*
 Dandelion, a Lisp plugin for Eclipse.
 Copyright (C) 2007 Michael Bohn
    
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
    
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
    
 You should have received a copy of the GNU General Public License along
 with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

package de.defmacro.dandelion.internal.preferences;

import java.util.*;
import java.util.List;
import java.util.Map.Entry;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.IWorkbench;

import de.defmacro.dandelion.internal.LispPluginActivator;
import de.defmacro.dandelion.internal.core.LispCore;
import de.defmacro.dandelion.internal.core.connection.*;
import de.defmacro.dandelion.internal.ui.LispUI;
import de.defmacro.dandelion.internal.ui.dialogs.EnvironmentEditDialog;

/**
 * Die GUI-Komponente zur Anzeige der Eval-Server
 * in den Preferences.
 * @author Michael Bohn
 *
 */
public class LispServerPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
    /**
     * Eindeutige ID der PreferencePage aus Manifest.
     */
    public static final String ID = LispPluginActivator.NS + ".preferences.LispServerPreferences";

    private final EnvironmentManager fManager = LispCore.getEnvironmentManager();
    private TableViewer fTable;
    private Button fButtonAdd;
    private Button fButtonRemove;
    private Button fButtonDefault;
    private LispEvalServerLabelProvider fLabelProvider;

    private final Map<IEnvironment, IEnvironmentConfiguration> fAdded; //Map aller Server die neu hinzugefugt wurden
    private final List<IEnvironment> fRemoved; //Liste aller Server die aus dem Manager geloescht wurde
    private IEnvironment fNewDefault; //Der neue default server, null wenn nicht neu gesetzt

    /**
     * Erstellt eine neue PreferencePage fuer die Anzeige 
     * der Eval-Server.
     */
    public LispServerPreferencePage() {
        setDescription("Installed Environments:");
        fAdded = new Hashtable<IEnvironment, IEnvironmentConfiguration>();
        fRemoved = new ArrayList<IEnvironment>();
        fNewDefault = null;
    }

    @Override
    protected Control createContents(final Composite ancestor) {
        noDefaultAndApplyButton();
        {
            GridLayout layout = new GridLayout(1, false);
            layout.marginHeight = 0;
            layout.marginWidth = 0;
            ancestor.setLayout(layout);
        }

        Composite parent = new Composite(ancestor, SWT.NONE);
        parent.setLayoutData(new GridData(GridData.FILL_BOTH));
        {
            GridLayout layout = new GridLayout(2, false);
            layout.marginHeight = 0;
            layout.marginWidth = 0;
            parent.setLayout(layout);
        }

        fTable = new TableViewer(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
        {
            GridData data = new GridData(GridData.FILL_BOTH);
            fTable.getTable().setLayoutData(data);
        }
        fTable.getTable().setHeaderVisible(true);
        fTable.getTable().setLinesVisible(true);
        fTable.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(final SelectionChangedEvent event) {
                updateEnablement();
            }
        });
        addColumns(fTable.getTable());
        fLabelProvider = new LispEvalServerLabelProvider(fManager.getDefaultEnvironment());
        setTableProvider(fTable, fLabelProvider);

        Composite buttons = new Composite(parent, SWT.NONE);
        {
            GridLayout layout = new GridLayout(1, false);
            layout.marginHeight = 0;
            layout.marginWidth = 5;
            buttons.setLayout(layout);
        }
        buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));

        fButtonAdd = new Button(buttons, SWT.PUSH);
        fButtonAdd.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        fButtonAdd.setText("Add");
        fButtonAdd.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                addServer();
            }
        });

        fButtonRemove = new Button(buttons, SWT.PUSH);
        fButtonRemove.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        fButtonRemove.setText("Remove");
        fButtonRemove.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                removeServer();
            }
        });

        fButtonDefault = new Button(buttons, SWT.PUSH);
        {
            GridData data = new GridData(GridData.FILL_HORIZONTAL);
            data.verticalIndent = 25;
            fButtonDefault.setLayoutData(data);
        }
        fButtonDefault.setText("Default");
        fButtonDefault.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                setDefault();
            }
        });

        return parent;
    }

    private void setTableProvider(final TableViewer viewer, LispEvalServerLabelProvider labelProvider) {
        viewer.setContentProvider(new IStructuredContentProvider() {
            public Object[] getElements(final Object inputElement) {
                return getCurrentServerList().toArray();
            }

            public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {
                //no-op
            }

            public void dispose() {
                //no-op
            }
        });
        viewer.setInput(new Object());
        viewer.setLabelProvider(labelProvider);
    }

    private void addColumns(final Table table) {
        TableColumn name = makeColumn(table, "Name");
        name.setWidth(175);

        TableColumn host = makeColumn(table, "Host");
        host.setWidth(125);

        TableColumn port = makeColumn(table, "Port");
        port.setWidth(75);

        TableColumn version = makeColumn(table, "Version");
        version.setWidth(100);
    }

    private TableColumn makeColumn(final Table parent, final String name) {
        TableColumn column = new TableColumn(parent, SWT.LEFT);
        column.setText(name);
        return column;
    }

    /**
     * Unbenutzt.
     */
    public void init(final IWorkbench workbench) {
        //no-op
    }

    private IEnvironment getCurrentDefault() {
        if (fNewDefault == null) {
            return fManager.getDefaultEnvironment();
        }
        return fNewDefault;
    }

    /**
     * Gibt die aktuelle IEvalServer-Liste zurueck.
     * Die Liste ist != der Liste im EvalServerManager, da die akutell hinzugefuegten
     * Server hingzugenommen werden die noch nicht im Manager gespeichert wurden.
     * Die Liste der Server ist sortiert.
     * @return
     */
    protected List<IEnvironment> getCurrentServerList() {
        //zurueckgegebene Liste darf veraendert werden
        List<IEnvironment> serverInManager = fManager.getEnvironments();
        serverInManager.addAll(fAdded.keySet());
        serverInManager.removeAll(fRemoved);
        Collections.sort(serverInManager);
        return serverInManager;
    }

    protected void addServer() {
        EnvironmentEditDialog dialog = new EnvironmentEditDialog(getShell(), getCurrentServerList());
        dialog.setTitle("Add Environment");
        dialog.open();
        IEnvironment server = dialog.getEvalServer();
        IEnvironmentConfiguration config = dialog.getEvalServerConfiguration();

        if (server != null && config != null) {
            fAdded.put(server, config);
        }

        fTable.refresh();
    }

    protected void removeServer() {
        IEnvironment selected = getSelectedServer();
        if (selected != null) {
            if (LispCore.getProjectManager().isUsedInProject(selected)) {
                MessageDialog.openInformation(getShell(), "Removing server",
                        "Cannot remove this environment, the environment is used in a project");
            } else if (selected.equals(getCurrentDefault())) {
                MessageDialog.openInformation(getShell(), "Removing server", "Cannot remove default environment");
            } else {
                if (fAdded.containsKey(selected)) { //Server wurde hinzugefuegt und sofort wieder geloescht
                    fAdded.remove(selected); //aus add liste entfernen
                } else {
                    fRemoved.add(selected); //ein server aus Manager -> merken fuer loeschung
                }
            }
        }
        fTable.refresh();
    }

    protected void setDefault() {
        IEnvironment newDefault = getSelectedServer();
        if (newDefault == null || newDefault.equals(getCurrentDefault())) {
            return;
        }
        fNewDefault = newDefault;
        fLabelProvider.setNewDefault(newDefault);
        fTable.refresh();
    }

    /**
     * @see PreferencePage#performOk()
     */
    @Override
    public boolean performOk() {
        for (Entry<IEnvironment, IEnvironmentConfiguration> entry : fAdded.entrySet()) {
            fManager.addEnvironment(entry.getKey(), entry.getValue());
        }

        for (IEnvironment removed : fRemoved) {
            try {
                fManager.removeEnvironment(removed);
            } catch (ManagementException e) {
                LispPluginActivator.logBrokenInvariant("Error trying to remove a used environment", e);
            } catch (ConnectionException e) {
                LispUI.showErrorDialog(getShell(), "Error disconnecting environment", e);
            }
        }

        if (fNewDefault != null) {
            fManager.setDefaultEnvironment(fNewDefault);
            LispPreferences.storeDefaultServer(fNewDefault.hashCode());
        }

        //invariante: Manager enthaelt korrekten Zustand

        Map<IEnvironment, IEnvironmentConfiguration> serversToStore = new Hashtable<IEnvironment, IEnvironmentConfiguration>();
        for (IEnvironment server : fManager.getEnvironments()) {
            if (!fManager.isContributedViaPlugin(server)) {
                try {
                    serversToStore.put(server, fManager.getConfigurationFor(server));
                } catch (ManagementException e) {
                    //ignore
                }
            }
        }
        LispPreferences.storeEvalServer(serversToStore);

        return super.performOk();
    }

    protected void updateEnablement() {
        IEnvironment selected = getSelectedServer();
        if (selected != null) {
            fButtonRemove.setEnabled(!fManager.isContributedViaPlugin(selected));
        }
    }

    private IEnvironment getSelectedServer() {
        IStructuredSelection selection = (IStructuredSelection) fTable.getSelection();
        if (selection.isEmpty()) {
            return null;
        }
        return (IEnvironment) selection.getFirstElement();
    }
}