com.windowtester.eclipse.ui.target.NewTargetProvisionerPage.java Source code

Java tutorial

Introduction

Here is the source code for com.windowtester.eclipse.ui.target.NewTargetProvisionerPage.java

Source

/*******************************************************************************
 *  Copyright (c) 2012 Google, 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
 *  http://www.eclipse.org/legal/epl-v10.html
 *  
 *  Contributors:
 *  Google, Inc. - initial API and implementation
 *******************************************************************************/
package com.windowtester.eclipse.ui.target;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
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.DirectoryDialog;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

import com.windowtester.eclipse.ui.UiPlugin;
import com.windowtester.internal.debug.LogHandler;
import com.windowtester.runtime.swt.internal.display.DisplayExec;
import com.windowtester.runtime.swt.internal.display.RunnableWithResult;

@SuppressWarnings({ "deprecation", "unchecked" })
public class NewTargetProvisionerPage extends WizardPage implements Listener {

    private static final String DESCRIPTION = "Create a new WindowTester File System Target Provisioner.";
    private static final String TITLE = "WindowTester Target Provisioner";

    protected static final int COMBO_HISTORY_LENGTH = 5;

    private static final String SELECT_DESTINATION_MESSAGE = "Select a parent directory.";
    private static final String SELECT_DESTINATION_TITLE = "Provisioner Destination";

    private static final String STORE_DESTINATION_NAMES_ID = "destination.names";
    private static final String STORE_RECORDING_CONTENT = "recording.content";
    private static final String STORE_RUNTIME_CONTENT = "runtime.content";

    private static final String CREATION_ERROR_MSG = "Creation Error";
    private static final String HELP_CONTEXT_ID = "com.windowtester.eclipse.help.wt_ui_context";

    private Combo destination;
    private Button recordingButton;
    private Button runtimeButton;
    private Button browseButton;

    private final SettingsManager settings = new SettingsManager();
    private final ITargetProvisionerFileProvider fileProvider;

    private Button gefSupportButton;

    private class SettingsManager {

        protected void restoreWidgetValues() {
            IDialogSettings settings = getDialogSettings();
            if (settings == null)
                return;

            restoreDestinations(settings);
            restoreContents(settings);
        }

        private void restoreContents(IDialogSettings settings) {
            recordingButton.setSelection(settings.getBoolean(STORE_RECORDING_CONTENT));
            runtimeButton.setSelection(settings.getBoolean(STORE_RUNTIME_CONTENT));
        }

        private void restoreDestinations(IDialogSettings settings) {
            String[] directoryNames = settings.getArray(STORE_DESTINATION_NAMES_ID);
            if (directoryNames == null || directoryNames.length == 0) {
                return;
            }
            for (int i = 0; i < directoryNames.length; i++) {
                destination.add(directoryNames[i], i);
            }
            destination.select(0);
        }

        protected void saveWidgetValues() {

            IDialogSettings settings = getDialogSettings();
            if (settings == null)
                return;

            saveDestinationHistory(settings);
            saveContentTypes(settings);
        }

        private void saveContentTypes(IDialogSettings settings) {
            // options
            settings.put(STORE_RECORDING_CONTENT, recordingButton.getSelection());

            settings.put(STORE_RUNTIME_CONTENT, runtimeButton.getSelection());
        }

        private void saveDestinationHistory(IDialogSettings settings) {
            String[] directoryNames = settings.getArray(STORE_DESTINATION_NAMES_ID);
            if (directoryNames == null) {
                directoryNames = new String[0];
            }

            directoryNames = addToHistory(directoryNames, getDestinationValue());
            settings.put(STORE_DESTINATION_NAMES_ID, directoryNames);
        }

        /**
         * Adds an entry to a history, while taking care of duplicate history items
         * and excessively long histories.  The assumption is made that all histories
         * should be of length <code>WizardDataTransferPage.COMBO_HISTORY_LENGTH</code>.
         *
         * @param history the current history
         * @param newEntry the entry to add to the history
         */
        protected String[] addToHistory(String[] history, String newEntry) {
            java.util.ArrayList l = new java.util.ArrayList(Arrays.asList(history));
            addToHistory(l, newEntry);
            String[] r = new String[l.size()];
            l.toArray(r);
            return r;
        }

        /**
         * Adds an entry to a history, while taking care of duplicate history items
         * and excessively long histories.  The assumption is made that all histories
         * should be of length <code>WizardDataTransferPage.COMBO_HISTORY_LENGTH</code>.
         *
         * @param history the current history
         * @param newEntry the entry to add to the history
         */
        protected void addToHistory(List history, String newEntry) {
            history.remove(newEntry);
            history.add(0, newEntry);

            // since only one new item was added, we can be over the limit
            // by at most one item
            if (history.size() > COMBO_HISTORY_LENGTH) {
                history.remove(COMBO_HISTORY_LENGTH);
            }
        }
    }

    /**
     * Create the wizard
     * @param structuredSelection 
     * @param string 
     */
    public NewTargetProvisionerPage(String string, IStructuredSelection structuredSelection,
            ITargetProvisionerFileProvider fileProvider) {
        super("wizardPage");
        this.fileProvider = fileProvider;
        setTitle(TITLE);
        setDescription(DESCRIPTION);
        setImageDescriptor(getPageImageDescriptor());
    }

    private ImageDescriptor getPageImageDescriptor() {
        return UiPlugin.imageDescriptor("icons/full/wizban/newTargetProvisioner.png");
    }

    /**
     * Create contents of the wizard
     * @param parent
     */
    public void createControl(Composite parent) {
        doCreateComposite(parent);
        addListeners();
        setInitialWidgetValues();
        validatePage(); //does validation
    }

    /*
     * @see org.eclipse.jface.window.Window#configureShell(Shell)
     */
    protected void configureShell(Shell newShell) {
        PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, HELP_CONTEXT_ID);
    }

    private void doCreateComposite(Composite parent) {
        Composite container = new Composite(parent, SWT.NULL);
        container.setLayout(new GridLayout());
        //
        setControl(container);

        final Composite contentsComposite = new Composite(container, SWT.NONE);
        contentsComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
        contentsComposite.setLayout(new GridLayout());

        final Group targetContentGroup = new Group(contentsComposite, SWT.NONE);
        final GridData gd_targetContentGroup = new GridData(SWT.FILL, SWT.CENTER, true, false);
        targetContentGroup.setLayoutData(gd_targetContentGroup);
        targetContentGroup.setText("Target Content");
        final GridLayout gridLayout_1 = new GridLayout();
        gridLayout_1.numColumns = 2;
        targetContentGroup.setLayout(gridLayout_1);

        final Label targetContentDescriptionLabel = new Label(targetContentGroup, SWT.NONE);
        final GridData gd_targetContentDescriptionLabel = new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1);
        gd_targetContentDescriptionLabel.verticalIndent = 5;
        targetContentDescriptionLabel.setLayoutData(gd_targetContentDescriptionLabel);
        targetContentDescriptionLabel.setText("This target provisioner provides support for");

        final Label spacer = new Label(targetContentGroup, SWT.NONE);
        final GridData gd_spacer = new GridData(10, SWT.DEFAULT);
        spacer.setLayoutData(gd_spacer);

        recordingButton = new Button(targetContentGroup, SWT.RADIO);
        final GridData gd_recordingButton = new GridData();
        gd_recordingButton.verticalIndent = 5;
        recordingButton.setLayoutData(gd_recordingButton);
        recordingButton.setText("&Recording and Execution of WindowTester Tests");

        final Label spacer2 = new Label(targetContentGroup, SWT.NONE);
        final GridData gd_spacer2 = new GridData(10, SWT.DEFAULT);
        spacer2.setLayoutData(gd_spacer2);

        runtimeButton = new Button(targetContentGroup, SWT.RADIO);
        final GridData gd_runtimeButton = new GridData();
        runtimeButton.setLayoutData(gd_runtimeButton);
        runtimeButton.setText("E&xecution of WindowTester Tests");

        final Label optionalSupportLabel = new Label(targetContentGroup, SWT.NONE);
        final GridData gd_optionalSupportLabel = new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1);
        gd_optionalSupportLabel.verticalIndent = 5;
        optionalSupportLabel.setLayoutData(gd_optionalSupportLabel);
        optionalSupportLabel.setText("Include support for");

        final Label spacer3 = new Label(targetContentGroup, SWT.NONE);
        final GridData gd_spacer3 = new GridData(10, SWT.DEFAULT);
        spacer3.setLayoutData(gd_spacer3);

        gefSupportButton = new Button(targetContentGroup, SWT.CHECK);
        final GridData gd_gefButton = new GridData();
        gd_gefButton.verticalIndent = 5;
        gefSupportButton.setLayoutData(gd_gefButton);
        gefSupportButton.setText("Graphical Editing Framework (GEF) Components");

        final Composite desinationComposite = new Composite(container, SWT.NONE);
        final GridData gd_desinationComposite = new GridData(SWT.FILL, SWT.CENTER, true, false);
        gd_desinationComposite.widthHint = 461;
        desinationComposite.setLayoutData(gd_desinationComposite);
        final GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 3;
        desinationComposite.setLayout(gridLayout);

        final Label destinationLabel = new Label(desinationComposite, SWT.NONE);
        destinationLabel.setText("Provisioner &directory:");

        destination = new Combo(desinationComposite, SWT.NONE);
        final GridData gd_combo = new GridData(SWT.FILL, SWT.CENTER, true, false);
        gd_combo.widthHint = 156;
        destination.setLayoutData(gd_combo);

        browseButton = new Button(desinationComposite, SWT.NONE);
        browseButton.setText("B&rowse...");

        final Label label = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
        final GridData gd_label = new GridData(SWT.FILL, SWT.TOP, true, false);
        gd_label.verticalIndent = 8;
        label.setLayoutData(gd_label);

    }

    private void addListeners() {
        browseButton.addSelectionListener(new SelectionListener() {
            public void widgetDefaultSelected(SelectionEvent e) {
                browseForProvisionerDestination();
            }

            public void widgetSelected(SelectionEvent e) {
                browseForProvisionerDestination();
            }
        });
        recordingButton.addListener(SWT.Selection, this);
        runtimeButton.addListener(SWT.Selection, this);
        destination.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                //System.out.println("combo modified");
                validatePage();
            }
        });
    }

    private void setInitialWidgetValues() {
        settings.restoreWidgetValues();
        /*
         * In case this is the first time, ensure there is a default set
         */
        if (!isRecordingContentSelected() && !runtimeButton.getSelection())
            recordingButton.setSelection(true);
    }

    private void browseForProvisionerDestination() {

        DirectoryDialog dialog = new DirectoryDialog(getContainer().getShell(), SWT.SAVE);
        dialog.setMessage(SELECT_DESTINATION_MESSAGE);
        dialog.setText(SELECT_DESTINATION_TITLE);
        //dialog.setFilterPath(getDestinationValue());
        String selectedDirectoryName = dialog.open();

        if (selectedDirectoryName != null) {
            setErrorMessage(null);
            setDestination(selectedDirectoryName);
        }
    }

    public void handleEvent(Event event) {
        validatePage();
    }

    private void validatePage() {
        setPageComplete(isPageValid());
    }

    private boolean isPageValid() {
        //System.out.println("validating page");
        if (!isRecordingContentSelected() && !runtimeButton.getSelection()) {
            setError("Please select a content type.");
            return false;
        }

        String text = destination.getText();

        if (text == null || text.trim().length() == 0) {
            setError("Please enter a destination directory.");
            return false;
        }

        setError(null);
        return true;
    }

    private void setError(String msg) {
        setErrorMessage(msg);
        setMessage(msg);
    }

    private void setDestination(String browsedDestination) {
        destination.add(browsedDestination, 0);
        destination.select(0);
    }

    //there is no next page!
    /* (non-Javadoc)
     * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage()
     */
    public boolean canFlipToNextPage() {
        return false;
    }

    /**
     * Returns a boolean indicating whether the directory portion of the
     * passed pathname is valid and available for use.
     */
    protected boolean ensureTargetDirectoryIsValid(String fullPathname) {
        int separatorIndex = fullPathname.lastIndexOf(File.separator);

        if (separatorIndex == -1) {
            return true;
        }

        return ensureTargetIsValid(new File(fullPathname.substring(0, separatorIndex)));
    }

    protected boolean ensureTargetIsValid(File targetDirectory) {
        if (targetDirectory.exists() && !targetDirectory.isDirectory()) {
            displayErrorDialog("The destination directory must exist.");
            giveFocusToDestination();
            return false;
        }

        return ensureDirectoryExists(targetDirectory);
    }

    protected boolean ensureDirectoryExists(File directory) {
        if (!directory.exists()) {
            if (!queryYesNoQuestion("The destination directory does not exist.  Would you like to create it?")) {
                return false;
            }

            if (!directory.mkdirs()) {
                displayErrorDialog("An error was encountered creating the provisioner directory.");
                giveFocusToDestination();
                return false;
            }
        }

        return true;
    }

    protected boolean queryYesNoQuestion(String message) {
        MessageDialog dialog = new MessageDialog(getContainer().getShell(), "Question", (Image) null, message,
                MessageDialog.NONE, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 0);
        // ensure yes is the default

        return dialog.open() == 0;
    }

    protected void displayErrorDialog(String message) {
        MessageDialog.openError(getContainer().getShell(), "Provisioner Creation Error", message);
    }

    protected void giveFocusToDestination() {
        destination.setFocus();
    }

    public boolean finish() {
        if (!ensureTargetIsValid(getTargetDestination()))
            return false;
        boolean created = createProvisioner();
        if (!created)
            return false;

        settings.saveWidgetValues();
        return true;
    }

    public static IAdaptable getUIInfoAdapter(final Shell shell) {
        return new IAdaptable() {
            public Object getAdapter(Class clazz) {
                if (clazz == Shell.class) {
                    return shell;
                }
                return null;
            }
        };
    }

    private boolean createProvisioner() {

        IRunnableWithProgress op = new IRunnableWithProgress() {
            public void run(IProgressMonitor monitor) {
                try {
                    CreateTargetProvisionerOperation op = new CreateTargetProvisionerOperation(getTargetFiles(),
                            getTargetDestination());
                    PlatformUI.getWorkbench().getOperationSupport().getOperationHistory().execute(op, monitor,
                            getUIInfoAdapter(getShell()));
                } catch (final Exception e) {
                    getContainer().getShell().getDisplay().syncExec(new Runnable() {
                        public void run() {
                            if (e.getCause() instanceof CoreException) {
                                ErrorDialog.openError(getContainer().getShell(), CREATION_ERROR_MSG, null,
                                        ((CoreException) e.getCause()).getStatus());
                            } else {
                                LogHandler.log(e);
                                MessageDialog.openError(getContainer().getShell(), CREATION_ERROR_MSG,
                                        e.getCause().getMessage());
                            }
                        }
                    });
                }
            }
        };
        try {
            getContainer().run(true, true, op);
            return true;
        } catch (InterruptedException e) {
            //do nothing
        } catch (InvocationTargetException e) {
            LogHandler.log(e);
            MessageDialog.openError(getContainer().getShell(), CREATION_ERROR_MSG, e.getCause().getMessage());

        }
        return false;
    }

    protected File getTargetDestination() {
        String dest = (String) DisplayExec.sync(new RunnableWithResult() {
            public Object runWithResult() {
                return getDestinationValue();
            }

        });
        return new File(dest);
    }

    protected File[] getTargetFiles() throws IOException {
        return fileProvider.getTargetFiles(getTargetSpecification());
    }

    private TargetSpecification getTargetSpecification() {
        TargetSpecification spec = getBaseSpec();
        if (isGEFSupportSelected())
            return spec.withBundles(RequiredPlugins.GEF_SUPPORT);
        return spec;
    }

    /**
     * @since 3.8.1
     */
    private boolean isGEFSupportSelected() {
        return ((Boolean) DisplayExec.sync(new RunnableWithResult() {
            public Object runWithResult() {
                return Boolean.valueOf(gefSupportButton.getSelection());
            }
        })).booleanValue();
    }

    private TargetSpecification getBaseSpec() {
        if (isRecordingContentSelected())
            return TargetSpecification.RECORDING.withBundles(RequiredPlugins.RUNTIME); //notice this includes both
        return TargetSpecification.EXECUTION;
    }

    private boolean isRecordingContentSelected() {
        return ((Boolean) DisplayExec.sync(new RunnableWithResult() {
            public Object runWithResult() {
                return Boolean.valueOf(recordingButton.getSelection());
            }
        })).booleanValue();
    }

    private String getDestinationValue() {
        return destination.getText().trim();
    }

}