org.eclipse.php.internal.debug.ui.launching.AbstractPHPLaunchConfigurationDebuggerTab.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.php.internal.debug.ui.launching.AbstractPHPLaunchConfigurationDebuggerTab.java

Source

/*******************************************************************************
 * Copyright (c) 2015 Zend Technologies 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:
 *     Zend Technologies - initial API and implementation
 *******************************************************************************/
package org.eclipse.php.internal.debug.ui.launching;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.php.debug.core.debugger.parameters.IDebugParametersKeys;
import org.eclipse.php.debug.ui.IDebugServerConnectionTest;
import org.eclipse.php.internal.core.Logger;
import org.eclipse.php.internal.debug.core.PHPDebugPlugin;
import org.eclipse.php.internal.debug.core.preferences.PHPDebugCorePreferenceNames;
import org.eclipse.php.internal.debug.core.preferences.PHPDebuggersRegistry;
import org.eclipse.php.internal.debug.ui.PHPDebugUIImages;
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.graphics.Font;
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.Composite;
import org.eclipse.swt.widgets.Label;

/**
 * Abstract implementation of "Debugger" launch configuration tab. It handles
 * switching between dedicated settings sections and updates the corresponding
 * debugger type related data if it has been changed.
 * 
 * @author Bartlomiej Laczkowski
 */
@SuppressWarnings("restriction")
public abstract class AbstractPHPLaunchConfigurationDebuggerTab extends AbstractPHPLaunchConfigurationTab {

    /**
     * Widget listener that should be added to all controls that affects the
     * state of corresponding launch configuration.
     */
    public final class WidgetListener extends SelectionAdapter implements ModifyListener {
        public void modifyText(ModifyEvent e) {
            setDirty(true);
            updateLaunchConfigurationDialog();
        }

        public void widgetSelected(SelectionEvent e) {
            setDirty(true);
            updateLaunchConfigurationDialog();
        }
    }

    /**
     * Status message that provides information about validation result in given
     * settings section.
     */
    public final static class StatusMessage implements IMessageProvider {

        private int type;
        private String message;

        public StatusMessage(int type, String message) {
            this.type = type;
            this.message = message;
        }

        @Override
        public String getMessage() {
            return message;
        }

        @Override
        public int getMessageType() {
            return type;
        }

    }

    private final class NoneDebuggerSection extends DebuggerLaunchSettingsSectionAdapter {

        @Override
        public StatusMessage isValid(ILaunchConfiguration configuration) {
            return new StatusMessage(IMessageProvider.ERROR, getNoDebuggerMessage());
        }

    }

    private final class UnsupportedDebuggerSection extends DebuggerLaunchSettingsSectionAdapter {

        @Override
        public void createSection(Composite parent, WidgetListener widgetListener) {
            Label info = new Label(parent, SWT.NONE);
            info.setText(Messages.AbstractPHPLaunchConfigurationDebuggerTab_Unsupported_debugger_type);
        }

        @Override
        public StatusMessage isValid(ILaunchConfiguration configuration) {
            return new StatusMessage(IMessageProvider.ERROR,
                    Messages.AbstractPHPLaunchConfigurationDebuggerTab_Unsupported_debugger_type);
        }

    }

    protected Button validateDebuggerBtn;
    protected IDebugServerConnectionTest[] debugTesters;
    private Label debuggerName;
    private Button configureDebugger;
    private Composite mainComposite;
    private Composite settingsComposite;
    private Map<String, IDebuggerLaunchSettingsSection> currentSection = new HashMap<String, IDebuggerLaunchSettingsSection>();

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
     */
    public String getName() {
        return Messages.AbstractPHPLaunchConfigurationDebuggerTab_Debugger_tab_name;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getImage()
     */
    @Override
    public Image getImage() {
        return PHPDebugUIImages.get(PHPDebugUIImages.IMG_OBJ_DEBUG_CONF);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse
     * .swt.widgets.Composite)
     */
    public void createControl(Composite parent) {
        // Create main composite
        mainComposite = new Composite(parent, SWT.NONE);
        GridLayout mainLayout = new GridLayout();
        mainLayout.marginHeight = 0;
        mainLayout.marginWidth = 0;
        mainComposite.setLayout(mainLayout);
        createDebuggerSelectionControl(mainComposite);
        // Create composite for debugger dedicated settings
        settingsComposite = new Composite(mainComposite, SWT.NONE);
        Dialog.applyDialogFont(mainComposite);
        setControl(mainComposite);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.php.internal.debug.ui.launching.
     * AbstractPHPLaunchConfigurationTab#setDefaults(org.eclipse.debug.core.
     * ILaunchConfigurationWorkingCopy)
     */
    @Override
    public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
        super.setDefaults(configuration);
        try {
            if (!configuration.hasAttribute(IDebugParametersKeys.FIRST_LINE_BREAKPOINT)) {
                configuration.setAttribute(IDebugParametersKeys.FIRST_LINE_BREAKPOINT,
                        PHPDebugPlugin.getStopAtFirstLine());
            }
        } catch (CoreException e) {
            Logger.logException(e);
        }
        getSection().setDefaults(configuration);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.
     * debug.core.ILaunchConfigurationWorkingCopy)
     */
    @Override
    public void performApply(ILaunchConfigurationWorkingCopy configuration) {
        configuration.setAttribute(PHPDebugCorePreferenceNames.PHP_DEBUGGER_ID, getCurrentDebuggerId());
        getSection().performApply(configuration);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.debug.ui.AbstractLaunchConfigurationTab#isValid(org.eclipse.
     * debug.core.ILaunchConfiguration)
     */
    @Override
    public boolean isValid(ILaunchConfiguration launchConfig) {
        setMessage(null);
        setWarningMessage(null);
        setErrorMessage(null);
        StatusMessage status = getSection().isValid(launchConfig);
        switch (status.getMessageType()) {
        case IMessageProvider.ERROR: {
            setErrorMessage(status.getMessage());
            return false;
        }
        case IMessageProvider.WARNING: {
            setWarningMessage(status.getMessage());
            return true;
        }
        default:
            return true;
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.php.internal.debug.ui.launching.
     * AbstractPHPLaunchConfigurationTab#initialize(org.eclipse.debug.core.
     * ILaunchConfiguration)
     */
    @Override
    protected void initialize(ILaunchConfiguration configuration) {
        getSection().initialize(configuration);
    }

    /**
     * Implementors should provide an action that handles triggering of
     * "Configure..." debugger settings button.
     */
    protected abstract void handleConfigureDebugger();

    /**
     * Implementors should provide the current debugger ID that corresponds to
     * debugger settings owner in related launch configuration.
     * 
     * @return current debugger ID
     */
    protected abstract String getCurrentDebuggerId();

    /**
     * Implementors should provide the appropriate message in case when there is
     * no debugger attached to potential debugger settings owner.
     * 
     * @return "No" debugger attached message.
     */
    protected abstract String getNoDebuggerMessage();

    /**
     * Implementors should update state of a "Test" button.
     */
    protected abstract void updateDebugTest();

    /**
     * Implementors should provide an action that handles triggering of "Test"
     * debugger connection button.
     */
    protected abstract void performDebugTest();

    private void createDebuggerSelectionControl(Composite parent) {
        Composite mainComposite = new Composite(parent, SWT.NONE);
        GridLayout mcLayout = new GridLayout(1, false);
        mcLayout.marginHeight = 0;
        mcLayout.marginWidth = 0;
        mainComposite.setLayout(mcLayout);
        mainComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        Composite debuggerChoiceComposite = new Composite(mainComposite, SWT.NONE);
        GridLayout layout = new GridLayout(5, false);
        debuggerChoiceComposite.setLayout(layout);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        debuggerChoiceComposite.setLayoutData(data);
        Font font = parent.getFont();
        debuggerChoiceComposite.setFont(font);
        Label label = new Label(debuggerChoiceComposite, SWT.WRAP);
        data = new GridData(SWT.BEGINNING);
        label.setLayoutData(data);
        label.setFont(font);
        label.setText(Messages.AbstractPHPLaunchConfigurationDebuggerTab_Debugger_type);
        debuggerName = new Label(debuggerChoiceComposite, SWT.NONE);
        Label separator = new Label(debuggerChoiceComposite, SWT.NONE);
        data = new GridData(SWT.BEGINNING);
        data.widthHint = 20;
        separator.setLayoutData(data);
        configureDebugger = createPushButton(debuggerChoiceComposite,
                Messages.AbstractPHPLaunchConfigurationDebuggerTab_Configure, null);
        configureDebugger.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                handleConfigureDebugger();
            }
        });
        configureDebugger.addSelectionListener(new WidgetListener());
        validateDebuggerBtn = createPushButton(debuggerChoiceComposite,
                Messages.AbstractPHPLaunchConfigurationDebuggerTab_Test, null);
        validateDebuggerBtn.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                performDebugTest();
            }
        });
        Label lineSeparator = new Label(mainComposite, SWT.SEPARATOR | SWT.HORIZONTAL);
        lineSeparator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
    }

    private IDebuggerLaunchSettingsSection getSection() {
        try {
            String launchTypeId = getConfiguration().getType().getIdentifier();
            String debuggerId = getCurrentDebuggerId();
            IDebuggerLaunchSettingsSection section = currentSection.get(debuggerId);
            if (section == null) {
                // Debugger type has been changed, rebuild section
                if (PHPDebuggersRegistry.NONE_DEBUGGER_ID.equals(debuggerId)) {
                    section = new NoneDebuggerSection();
                } else {
                    section = DebuggerLaunchSettingsSectionRegistry.getSection(debuggerId, launchTypeId);
                    if (section == null) {
                        section = new UnsupportedDebuggerSection();
                    }
                }
                if (settingsComposite != null) {
                    buildSection(debuggerId, section);
                }
            }
            return section;
        } catch (CoreException e) {
            Logger.logException(e);
        }
        // Should never return null
        return null;
    }

    private void buildSection(String debuggerId, IDebuggerLaunchSettingsSection section) {
        // Update debugger type data first
        updateDebugger(debuggerId);
        // Store as singular key map (most recent section by debugger ID)
        currentSection.clear();
        currentSection.put(debuggerId, section);
        settingsComposite.dispose();
        settingsComposite = new Composite(mainComposite, SWT.NONE);
        settingsComposite.setLayout(new GridLayout());
        GridData dscData = new GridData(SWT.FILL, SWT.FILL, true, true);
        settingsComposite.setLayoutData(dscData);
        section.createSection(settingsComposite, new WidgetListener());
        // Rebuild main composite
        mainComposite.layout();
        section.initialize(getConfiguration());
    }

    private void updateDebugger(String debuggerId) {
        debuggerName.setText(PHPDebuggersRegistry.getDebuggerName(debuggerId));
        try {
            // Update debugger type in original configuration
            if (getOriginalConfiguration().contentsEqual(getConfiguration())) {
                // Only debugger might have been changed, update original configuration
                ILaunchConfigurationWorkingCopy wc = getOriginalConfiguration().getWorkingCopy();
                wc.setAttribute(PHPDebugCorePreferenceNames.PHP_DEBUGGER_ID, debuggerId);
                wc.doSave();
            }
            // Update in working copy
            if (getConfiguration() instanceof ILaunchConfigurationWorkingCopy) {
                ((ILaunchConfigurationWorkingCopy) getConfiguration())
                        .setAttribute(PHPDebugCorePreferenceNames.PHP_DEBUGGER_ID, debuggerId);
            }
        } catch (CoreException e) {
            Logger.logException(e);
        }
        updateDebugTest();
    }

}