org2.eclipse.php.internal.debug.ui.launching.server.ServerLaunchConfigurationTab.java Source code

Java tutorial

Introduction

Here is the source code for org2.eclipse.php.internal.debug.ui.launching.server.ServerLaunchConfigurationTab.java

Source

/*******************************************************************************
 * Copyright (c) 2005, 2008 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:
 *   Zend and IBM - Initial implementation
 *******************************************************************************/
package org2.eclipse.php.internal.debug.ui.launching.server;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.window.SameShellProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.custom.CLabel;
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.graphics.Point;
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.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org2.eclipse.php.debug.core.debugger.parameters.IDebugParametersKeys;
import org2.eclipse.php.debug.core.debugger.pathmapper.PathMapper;
import org2.eclipse.php.internal.core.util.ElementCreationProxy;
import org2.eclipse.php.internal.core.util.ScrolledCompositeImpl;
import org2.eclipse.php.internal.debug.core.IPHPDebugConstants;
import org2.eclipse.php.internal.debug.core.debugger.AbstractDebuggerConfiguration;
import org2.eclipse.php.internal.debug.core.debugger.IDebuggerConfiguration;
import org2.eclipse.php.internal.debug.core.launching.PHPLaunchDelegateProxy;
import org2.eclipse.php.internal.debug.core.pathmapper.PathMapperRegistry;
import org2.eclipse.php.internal.debug.core.preferences.PHPDebuggersRegistry;
import org2.eclipse.php.internal.debug.core.preferences.PHPProjectPreferences;
import org2.eclipse.php.internal.debug.core.zend.communication.DebuggerCommunicationDaemon;
import org2.eclipse.php.internal.debug.ui.IDebugServerConnectionTest;
import org2.eclipse.php.internal.debug.ui.launching.LaunchUtilities;
import org2.eclipse.php.util.SWTUtil;

import com.aptana.core.logging.IdeLog;
import com.aptana.php.debug.core.IPHPDebugCorePreferenceKeys;
import com.aptana.php.debug.core.server.PHPServersManager;
import com.aptana.php.debug.epl.PHPDebugEPLPlugin;
import com.aptana.php.debug.ui.launching.PathMappingUpdater;
import com.aptana.php.debug.ui.pathmapper.PathMapperDialog;
import com.aptana.ui.IPropertyDialog;
import com.aptana.ui.PropertyDialogsRegistry;
import com.aptana.ui.UIPlugin;
import com.aptana.ui.util.SWTUtils;
import com.aptana.ui.util.UIUtils;
import com.aptana.webserver.core.IServer;
import com.aptana.webserver.core.WebServerCorePlugin;
import com.aptana.webserver.ui.internal.ExternalWebServerPropertyDialog;

public class ServerLaunchConfigurationTab extends AbstractLaunchConfigurationTab {

    protected IFile selectedFile = null;
    protected Text fFile;
    protected Label fURLLabel;
    protected Text fURLHost;
    protected Text fURLPath;
    protected Button projectButton;
    protected Button fileButton;
    protected Button publish;
    protected Button createNewServer;
    protected Button configureServers;
    protected Button mapPaths;
    protected Button breakOnFirstLine;
    protected Button autoGeneratedURL;
    protected CLabel pathMapperNotification;
    protected Button validateDebuggerBtn;
    protected String[] serverTypeIds;
    protected Combo fDebuggersCombo;
    protected Combo serverCombo;
    protected IServer server;
    protected boolean serverCanPublish = false;
    // list of servers that are in combo
    protected List<IServer> servers;
    protected boolean init = true;
    // flag to be used to decide whether to enable combo in launch config dialog
    // after the user requests a launch, they cannot change it
    private static final String READ_ONLY = "read-only"; //$NON-NLS-1$
    protected WidgetListener fListener = new WidgetListener();
    private boolean saveWorkingCopy;
    private Set<String> fDebuggerIds;
    private IDebugServerConnectionTest[] debugTesters = new IDebugServerConnectionTest[0];

    /**
     * Use current page button.
     */
    // private Button useCurrentPage;

    /**
     * Use specific page button.
     */
    // private Button useSpecific;
    private ILaunchConfiguration workingCopy;

    /**
     * Create a new server launch configuration tab.
     */
    public ServerLaunchConfigurationTab() {
    }

    /**
     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(Composite)
     */
    public void createControl(Composite parent) {

        ScrolledCompositeImpl scrolledComposite = new ScrolledCompositeImpl(parent, SWT.V_SCROLL);
        Composite composite = new Composite(scrolledComposite, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.marginWidth = 5;
        layout.marginHeight = 5;
        layout.numColumns = 1;
        composite.setLayout(layout);

        createServerControl(composite);
        createFileComponent(composite);
        createBreakControl(composite);
        createURLControl(composite);
        createExtensionControls(composite);

        Dialog.applyDialogFont(composite);
        scrolledComposite.setContent(composite);
        Point size = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
        scrolledComposite.setMinSize(size.x, size.y);

        // PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IPHPHelpContextIds.DEBUGGING_A_PHP_WEB_PAGE);
        setControl(scrolledComposite);
    }

    public void createExtensionControls(Composite composite) {
        return;
    }

    public void createURLControl(Composite composite) {
        Group group = new Group(composite, SWT.NONE);
        String projectLabel = PHPServerUIMessages.getString("ServerTab.url"); //$NON-NLS-1$
        group.setText(projectLabel);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        group.setLayout(layout);
        group.setLayoutData(gridData);

        autoGeneratedURL = new Button(group, SWT.CHECK);
        autoGeneratedURL.setText(PHPServerUIMessages.getString("ServerTab.autoGenerate")); //$NON-NLS-1$
        autoGeneratedURL.setSelection(true);
        gridData = new GridData();
        gridData.horizontalSpan = 2;
        autoGeneratedURL.setLayoutData(gridData);
        autoGeneratedURL.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                initializeURLControl();
                updateLaunchConfigurationDialog();
            }
        });

        Composite urlComposite = new Composite(group, SWT.NONE);
        GridLayout gridLayout = new GridLayout(3, false);
        urlComposite.setLayout(gridLayout);
        gridData = new GridData(GridData.FILL_HORIZONTAL);
        urlComposite.setLayoutData(gridData);

        fURLLabel = new Label(urlComposite, SWT.NONE);
        fURLLabel.setText(PHPServerUIMessages.getString("ServerTab.urlLabel")); //$NON-NLS-1$
        gridData = new GridData();
        gridData.horizontalIndent = 20;
        gridData.horizontalSpan = 1;
        fURLLabel.setLayoutData(gridData);

        fURLHost = new Text(urlComposite, SWT.SINGLE | SWT.BORDER);
        gridData = new GridData(GridData.FILL_HORIZONTAL);
        fURLHost.setLayoutData(gridData);
        fURLHost.setEnabled(false);

        fURLPath = new Text(urlComposite, SWT.SINGLE | SWT.BORDER);
        gridData = new GridData(GridData.FILL_HORIZONTAL);
        fURLPath.setLayoutData(gridData);
        fURLPath.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                updateLaunchConfigurationDialog();
            }
        });
        new Label(urlComposite, SWT.NONE); // filler
        pathMapperNotification = new CLabel(urlComposite, SWT.LEFT | SWT.WRAP);
        // pathMapperNotification.setText(PHPServerUIMessages.getString("ServerTab.mapperModifiedURLMessage")); //$NON-NLS-1$
        // pathMapperNotification.setImage(ServersPluginImages.get(ServersPluginImages.IMG_PATH_MAPPING_NOTICE));
        Display standardDisplay = SWTUtil.getStandardDisplay();
        if (standardDisplay != null) {
            pathMapperNotification.setForeground(standardDisplay.getSystemColor(SWT.COLOR_DARK_RED));
        }
        gridData = new GridData(GridData.FILL_HORIZONTAL);
        gridData.horizontalSpan = 2;
        pathMapperNotification.setLayoutData(gridData);

    }

    protected void createServerSelectionControl(Composite parent) {
        Font font = parent.getFont();
        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.marginWidth = 5;
        layout.marginHeight = 5;
        layout.numColumns = 2;
        composite.setLayout(layout);
        composite.setLayoutData(data);

        Group group = new Group(composite, SWT.NONE);
        group.setText(PHPServerUIMessages.getString("ServerTab.server")); //$NON-NLS-1$
        GridLayout ly = new GridLayout();
        ly.numColumns = 1;
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        group.setLayout(ly);
        group.setLayoutData(gridData);

        Composite debuggerServerComp = new Composite(group, SWT.NONE);
        layout = new GridLayout(2, false);
        debuggerServerComp.setLayout(layout);
        debuggerServerComp.setFont(font);

        // Add the debuggers combo
        Label label = new Label(debuggerServerComp, SWT.WRAP);
        data = new GridData(GridData.BEGINNING);
        data.widthHint = 100;
        label.setLayoutData(data);
        label.setFont(font);
        label.setText("Server Debugger:");

        fDebuggersCombo = new Combo(debuggerServerComp, SWT.DROP_DOWN | SWT.READ_ONLY);
        fDebuggersCombo.setFont(font);
        data = new GridData(GridData.FILL_HORIZONTAL);
        data.widthHint = 100;
        fDebuggersCombo.setLayoutData(data);
        fDebuggersCombo.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(final SelectionEvent e) {
                updateLaunchConfigurationDialog();
                updateDebugServerTesters();
            }
        });

        Composite phpServerComp = new Composite(group, SWT.NONE);
        layout = new GridLayout(6, false);
        phpServerComp.setLayout(layout);
        data = new GridData(GridData.FILL_HORIZONTAL);
        phpServerComp.setLayoutData(data);
        phpServerComp.setFont(font);

        label = new Label(phpServerComp, SWT.WRAP);
        data = new GridData(GridData.BEGINNING);
        data.widthHint = 100;
        label.setLayoutData(data);
        label.setFont(font);
        label.setText("PHP Server:");

        serverCombo = new Combo(phpServerComp, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY);
        data = new GridData(GridData.FILL_HORIZONTAL);
        data.widthHint = 250;
        serverCombo.setLayoutData(data);
        serverCombo.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                handleServerSelection();
            }
        });

        createNewServer = createPushButton(phpServerComp, null,
                SWTUtils.getImage(UIPlugin.getDefault(), "/icons/add.gif")); //$NON-NLS-1$
        createNewServer.setToolTipText(PHPServerUIMessages.getString("ServerTab.new")); //$NON-NLS-1$
        createNewServer.addSelectionListener(fListener);
        Object gd = createNewServer.getLayoutData();
        if (gd instanceof GridData) {
            ((GridData) gd).widthHint = -1;
        }

        configureServers = createPushButton(phpServerComp, null,
                ServersPluginImages.get(ServersPluginImages.IMG_CONFIG_SERVER));
        configureServers.setToolTipText(PHPServerUIMessages.getString("ServerTab.configure")); //$NON-NLS-1$
        configureServers.addSelectionListener(fListener);
        gd = configureServers.getLayoutData();
        if (gd instanceof GridData) {
            ((GridData) gd).widthHint = -1;
        }

        mapPaths = createPushButton(phpServerComp, null,
                ServersPluginImages.get(ServersPluginImages.IMG_PATH_MAPPING));
        mapPaths.setToolTipText(PHPServerUIMessages.getString("ServerTab.mapPaths")); //$NON-NLS-1$
        mapPaths.addSelectionListener(fListener);
        gd = mapPaths.getLayoutData();
        if (gd instanceof GridData) {
            ((GridData) gd).widthHint = -1;
        }

        validateDebuggerBtn = createPushButton(phpServerComp, null,
                ServersPluginImages.get(ServersPluginImages.IMG_DEBUGGER_TEST));
        validateDebuggerBtn.setToolTipText(PHPServerUIMessages.getString("ServerTab.debuggerTest")); //$NON-NLS-1$
        gd = validateDebuggerBtn.getLayoutData();
        if (gd instanceof GridData) {
            ((GridData) gd).widthHint = -1;
        }
        validateDebuggerBtn.addSelectionListener(fListener);

        servers = PHPServersManager.getServers();

        // initialize the servers list
        if (!servers.isEmpty()) {
            for (int i = 0; i < servers.size(); i++) {
                IServer svr = servers.get(i);
                serverCombo.add(svr.getName());
            }
        }

        // select first item in list
        if (serverCombo.getItemCount() > 0) {
            serverCombo.select(0);
            configureServers.setEnabled(true);
            mapPaths.setEnabled(true);
        } else {
            configureServers.setEnabled(false);
            mapPaths.setEnabled(false);
        }

        // initialize the debuggers list
        fillDebuggers();

        serverCombo.forceFocus();
    }

    private void updateDebugServerTesters() {
        int selectedDebuggerIndex = fDebuggersCombo.getSelectionIndex();
        final String currentDebuggerType = fDebuggersCombo.getItem(selectedDebuggerIndex);
        debugTesters = retrieveAllServerTestExtensions(currentDebuggerType);
        if (debugTesters.length == 0) {
            validateDebuggerBtn.setEnabled(false);
        } else {
            validateDebuggerBtn.setEnabled(true);
        }
    }

    private IDebugServerConnectionTest[] retrieveAllServerTestExtensions(final String currentDebuggerType) {
        String debugServerTestExtensionName = "com.aptana.php.debug.epl.debugServerConnectionTest"; //$NON-NLS-1$
        Map<String, IDebugServerConnectionTest> filtersMap = new HashMap<String, IDebugServerConnectionTest>();
        IConfigurationElement[] elements = Platform.getExtensionRegistry()
                .getConfigurationElementsFor(debugServerTestExtensionName);
        for (int i = 0; i < elements.length; i++) {
            IConfigurationElement element = elements[i];
            if ("debugServerTest".equals(element.getName())) { //$NON-NLS-1$
                ElementCreationProxy ecProxy = new ElementCreationProxy(element, debugServerTestExtensionName);
                String debuggerTypeName = elements[i].getAttribute("debuggerTypeName"); //$NON-NLS-1$
                String overridesIds = elements[i].getAttribute("overridesId"); //$NON-NLS-1$
                if (debuggerTypeName.equals(currentDebuggerType)) {// must be equal to the current selected type
                    String id = element.getAttribute("id"); //$NON-NLS-1$
                    if (!filtersMap.containsKey(id)) {
                        if (overridesIds != null) {
                            StringTokenizer st = new StringTokenizer(overridesIds, ", "); //$NON-NLS-1$
                            while (st.hasMoreTokens()) {
                                filtersMap.put(st.nextToken(), null);
                            }
                        }
                        try {
                            filtersMap.put(id,
                                    (IDebugServerConnectionTest) element.createExecutableExtension("class")); //$NON-NLS-1$
                        } catch (CoreException e) {
                            PHPDebugEPLPlugin.logError(e);
                        }
                    }

                }
            }
        }
        Collection<IDebugServerConnectionTest> l = filtersMap.values();
        while (l.remove(null))
            ; // remove null elements
        debugTesters = l.toArray(new IDebugServerConnectionTest[l.size()]);
        return debugTesters;
    }

    /**
     * Populates the debuggers with the debuggers defined in the workspace.
     */
    protected void fillDebuggers() {
        fDebuggerIds = PHPDebuggersRegistry.getDebuggersIds();
        for (String id : fDebuggerIds) {
            // Insert the debuggers names
            fDebuggersCombo.add(PHPDebuggersRegistry.getDebuggerName(id));
        }
        // Select the default debugger
        String defaultName = PHPDebuggersRegistry.getDebuggerName(PHPDebuggersRegistry.getDefaultDebuggerId());
        int index = fDebuggersCombo.indexOf(defaultName);
        if (index > -1) {
            fDebuggersCombo.select(index);
        } else if (fDebuggersCombo.getItemCount() > 0) {
            fDebuggersCombo.select(0);
        }
    }

    public void createServerControl(Composite parent) {
        createServerSelectionControl(parent);
        GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.marginWidth = 5;
        layout.marginHeight = 5;
        layout.numColumns = 2;
        composite.setLayout(layout);
        composite.setLayoutData(data);
        handleServerSelection();
    }

    protected void createFileComponent(Composite parent) {
        Group group = new Group(parent, SWT.NONE);
        String projectLabel = PHPServerUIMessages.getString("ServerTab.file_project"); //$NON-NLS-1$
        group.setText(projectLabel);
        GridLayout layout = new GridLayout(3, false);
        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
        group.setLayout(layout);
        group.setLayoutData(gd);
        group.setFont(parent.getFont());
        // useCurrentPage = new Button(group,SWT.RADIO);
        // useCurrentPage.setText("Use selected script");
        // useCurrentPage.setLayoutData(GridDataFactory.swtDefaults().span(3, 1).create());
        // useSpecific = new Button(group,SWT.RADIO);
        // useSpecific.setText("Use specified script:");
        // useCurrentPage.setLayoutData(GridDataFactory.swtDefaults().span(3, 1).create());
        // useSpecific.addSelectionListener(new SelectionAdapter(){
        // public void widgetSelected(SelectionEvent e)
        // {
        // fFile.setEnabled(useSpecific.getSelection());
        // fileButton.setEnabled(useSpecific.getSelection());
        // setDirty(true);
        // updateLaunchConfigurationDialog();
        // initializeURLControl();
        // }
        //
        // });
        Label label = new Label(group, SWT.NONE);
        label.setText("Initial Script: ");
        fFile = new Text(group, SWT.SINGLE | SWT.BORDER);
        gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.horizontalSpan = 1;
        // gridData = new GridData();
        // gridData.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
        fFile.setLayoutData(gd);
        fFile.addModifyListener(fListener);

        fileButton = createPushButton(group, PHPServerUIMessages.getString("ServerTab.browse"), null); //$NON-NLS-1$
        gd = (GridData) fileButton.getLayoutData();
        gd.horizontalSpan = 1;
        fileButton.addSelectionListener(fListener);

        handleServerSelection();
    }

    public String[] getRequiredNatures() {
        return null;
    }

    protected void handleServerButtonSelected() {
        final IServer newServer = getServerFromWizard();
        if (newServer != null) {
            Display.getDefault().asyncExec(new Runnable() {
                public void run() {
                    serverCombo.add(newServer.getName());
                    serverCombo.select(serverCombo.indexOf(newServer.getName()));
                    handleServerSelection();
                    configureServers.setEnabled(true);
                    mapPaths.setEnabled(true);
                }
            });
        }
    }

    protected void handleConfigureButtonSelected() {
        int selectionIndex = serverCombo.getSelectionIndex();
        IServer server = servers.get(selectionIndex);
        String serverName = server.getName();
        try {
            Dialog dlg = PropertyDialogsRegistry.getInstance().createPropertyDialog(server,
                    new SameShellProvider(UIUtils.getActiveShell()));
            if (dlg != null) {
                if (dlg instanceof IPropertyDialog) {
                    ((IPropertyDialog) dlg).setPropertySource(server);
                }
                if (dlg.open() == Window.OK) {
                    String newName = server.getName();
                    if (!newName.equals(serverName)) {
                        serverCombo.remove(selectionIndex);
                        serverCombo.add(newName, selectionIndex);
                        serverCombo.select(selectionIndex);
                    }
                    saveWorkingCopy = true;
                    handleServerSelection();
                }
            }
        } catch (CoreException e) {
            IdeLog.logError(PHPDebugEPLPlugin.getDefault(), e);
        }
    }

    /**
     * Set the path mapping for the selected server.
     */
    protected void handlePathMapping() {
        // SG: Aptana addition
        PathMapperDialog dialog = new PathMapperDialog(getShell(), server);
        if (dialog.open() == Window.OK) {
            // notify the change to all other launch configurations that use this server.
            (new PathMappingUpdater()).updatePaths(server, new String[] { workingCopy.getName() });
            // apply the change into this config in case needed.
            initializeFrom(workingCopy);
        }
    }

    /**
     * Test the remote debugger.
     */
    protected void handleDebuggerValidation() {
        updateDebugServerTesters();
        int selectedServerIndex = serverCombo.getSelectionIndex();
        IServer server = servers.get(selectedServerIndex);
        final Shell shell = getShell();
        for (IDebugServerConnectionTest debugServerTester : debugTesters) {
            debugServerTester.testConnection(server, shell);
        }
    }

    public String[] getFileExtensions() {
        return null;
    }

    private IResource getFileFromDialog(IProject project) {
        return LaunchUtilities.getFileFromDialog(project, getShell(), getFileExtensions(), getRequiredNatures(),
                false);
    }

    protected void handleFileButtonSelected() {

        IResource file = null;
        file = getFileFromDialog(null);

        if (file == null)
            return;

        String fName = file.getFullPath().toString();
        fFile.setText(fName);

        // SG: Removed - The updateURLComponents is already called from the WidgetListener#modifyText
        // if (autoGeneratedURL.getSelection()) {
        // updateURLComponents(computeURL(formatFileName(fName)));
        // }
    }

    protected void updateURLComponents(String urlStr) {
        try {
            if (urlStr != null && urlStr.length() > 0) {
                URL url = new URL(urlStr);
                String port = (url.getPort() == -1 || url.getPort() == 80) ? "" : ":" + url.getPort(); //$NON-NLS-1$ //$NON-NLS-2$
                fURLHost.setText(url.getProtocol() + "://" + url.getHost() + port + "/"); //$NON-NLS-1$ //$NON-NLS-2$
                if (url.getQuery() != null) {
                    fURLPath.setText(url.getPath() + "?" + url.getQuery()); //$NON-NLS-1$
                } else {
                    fURLPath.setText(url.getPath());
                }
            }
        } catch (MalformedURLException e) {
            PHPDebugEPLPlugin.logError(e);
        }
    }

    protected IProject getProject(String name) {
        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
        IProject[] projects = workspaceRoot.getProjects();

        if (projects == null || projects.length == 0)
            return null;

        for (IProject project : projects) {
            if (project.getName().equals(name))
                return project;
        }

        return null;
    }

    /**
     * Called when a server is selected. This method should not be called directly.
     */
    protected void handleServerSelection() {
        int numEntries = serverCombo.getItemCount();
        int index = serverCombo.getSelectionIndex();

        if (!servers.isEmpty()) {
            Object obj = servers.get(serverCombo.getSelectionIndex());
            if (obj != null && obj instanceof IServer) {
                server = servers.get(serverCombo.getSelectionIndex());
                initializeURLControl();
            }
        }

        if (server == null && (index + 1) != numEntries)
            setErrorMessage(PHPServerUIMessages.getString("ServerTab.noSelectedServerError")); //$NON-NLS-1$
        else {
            setErrorMessage(null);
        }
        updateLaunchConfigurationDialog();
    }

    /**
     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(ILaunchConfigurationWorkingCopy)
     */
    public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
        setErrorMessage(null);
        try {
            selectDefaultServer(configuration);
            selectDefaultDebugger(configuration);
        } catch (CoreException e) {
            PHPDebugEPLPlugin.logError(e);
        }
    }

    /**
     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(ILaunchConfiguration)
     */
    public void initializeFrom(ILaunchConfiguration configuration) {
        workingCopy = configuration;
        serverCombo.setEnabled(true);
        // remove error message that other instances may have set
        setErrorMessage(null);

        try {
            String fileName = configuration.getAttribute(IPHPDebugCorePreferenceKeys.ATTR_SERVER_FILE_NAME, ""); //$NON-NLS-1$
            String url = configuration.getAttribute(IPHPDebugCorePreferenceKeys.ATTR_SERVER_BASE_URL, ""); //$NON-NLS-1$
            boolean isAutoGeneratedURL = configuration
                    .getAttribute(IPHPDebugCorePreferenceKeys.ATTR_AUTO_GENERATED_URL, true);

            try {
                boolean attribute = configuration.getAttribute(IPHPDebugCorePreferenceKeys.ATTR_USE_SPECIFIC_FILE,
                        true);
                // this.useSpecific.setSelection(attribute);
                // this.useCurrentPage.setSelection(!attribute);
                this.fFile.setEnabled(attribute);
                this.fileButton.setEnabled(attribute);
            } catch (CoreException e1) {
                PHPDebugEPLPlugin.logError("Error initializing the Server launch configuration tab", e1);//$NON-NLS-1$
            }

            initializeDebuggerControl(configuration);
            initializeServerControl(configuration);

            if (isAutoGeneratedURL) {
                autoGeneratedURL.setSelection(true);
                String computedURL = computeURL(formatFileName(fileName));
                fURLLabel.setEnabled(false);
                updateURLComponents(computedURL);
                fURLPath.setEnabled(false);
            } else {
                autoGeneratedURL.setSelection(false);
                fURLLabel.setEnabled(true);
                updateURLComponents(url);
                fURLPath.setEnabled(true);
                pathMapperNotification.setVisible(false);
            }

            fFile.setText(fileName);

            if (breakOnFirstLine != null) {
                // init the breakpoint settings
                breakOnFirstLine.setSelection(configuration.getAttribute(IDebugParametersKeys.FIRST_LINE_BREAKPOINT,
                        PHPDebugEPLPlugin.getStopAtFirstLine()));
            }
        } catch (CoreException e) {
            // ignore
        }
        initializeExtensionControls(configuration);
        isValid(configuration);
    }

    protected void initializeExtensionControls(ILaunchConfiguration configuration) {
        return;
    }

    /**
     * Constructs the URL string according to the given context root and the file name.
     * 
     * @param fileName
     * @return
     */
    protected String computeURL(String fileName) {
        if (server == null) {
            return ""; //$NON-NLS-1$
        }
        String urlString = server.getBaseURL().toString();

        if (urlString.equals("")) { //$NON-NLS-1$
            urlString = "http://localhost"; //$NON-NLS-1$
        }
        StringBuffer url = new StringBuffer(urlString);
        boolean displayMapperNotification = false;
        if (!fileName.equals("")) { //$NON-NLS-1$
            if (autoGeneratedURL.getSelection() && server != null) {
                PathMapper pathMapper = PathMapperRegistry.getByServer(server);
                String remoteFile = pathMapper.getRemoteFile(fileName);
                // In case the Path Mapper contains a mapping, notify the user.
                if (remoteFile != null && !"".equals(remoteFile) && !remoteFile.equals(fileName)) //$NON-NLS-1$
                {
                    displayMapperNotification = true;
                    // Since the path mapper can replace the path to the local path on the machine (in case the sever is
                    // installed locally), we have to check for that and don't touch the initial URL path in this case.
                    // Check if the URL string is actually a local file path
                    if (new File(remoteFile).exists()) {
                        pathMapperNotification
                                .setText(PHPServerUIMessages.getString("ServerTab.autoGeneratedConflictMapper")); //$NON-NLS-1$
                        pathMapperNotification.setToolTipText("The mapped path for \'" + url.toString() + fileName
                                + "' \nis mapped to: \n" + remoteFile);
                    } else {
                        pathMapperNotification
                                .setText(PHPServerUIMessages.getString("ServerTab.mapperHasMappingMessage")); //$NON-NLS-1$
                        pathMapperNotification.setToolTipText("The target path has a mapping from: \n"
                                + url.toString() + fileName + " \n  To: \n" + url.toString() + remoteFile);
                    }
                }
            }
            url.append(fileName);
        }
        pathMapperNotification.setVisible(displayMapperNotification);
        return url.toString();
    }

    private String formatFileName(String fileName) {
        String formatFile = null;

        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
        IResource resource = root.findMember(fileName);
        if (resource == null) {
            return fileName;
        }
        int type = resource.getType();
        if (type == IResource.FILE || type == IResource.FOLDER) {
            formatFile = resource.getFullPath().toString();
        } else {
            formatFile = "/"; //$NON-NLS-1$
        }
        if (!formatFile.startsWith("/")) { //$NON-NLS-1$
            formatFile = "/" + formatFile; //$NON-NLS-1$
        }
        /*
         * TODO - Implement this? PreviewInfo info = null; if (formatFile.length() <= 1) { info =
         * ServerFileTypeHandlers.getPreviewInfoByExtension(getDefaultExtension()); } else { info =
         * ServerFileTypeHandlers.getPreviewInfoFromURL(fileName); } if (info != null) { //if additional information is
         * available, using it to modify path part of the url if (server != null) { String currentServerTypeID =
         * server.getServer().getServerType().getId(); String currentServerID = server.getServer().getId(); if
         * (currentServerTypeID != null && currentServerTypeID.equals(info.serverTypeID)) { if (info.serverID != null &&
         * (info.serverID.length() == 0 || info.serverID.equals(currentServerID))) { formatFile = "/" + info.pathHeader
         * + formatFile; } } } }
         */
        return formatFile;
    }

    /**
     * Gets default extensions for using with "selected scripts".
     * 
     * @return default extension.
     */
    protected String getDefaultExtension() {
        return null;
    }

    protected void initializeURLControl() {
        if (fFile == null || fURLPath == null || fURLHost == null) {
            return;
        }
        String file;
        if (autoGeneratedURL.getSelection()) {
            // if (useSpecific.getSelection()) {
            file = formatFileName(fFile.getText());
            // } else {
            // file = formatFileName("");
            // pathMapperNotification.setVisible(false);
            // }
        } else {
            file = fURLPath.getText();
            pathMapperNotification.setVisible(false);
        }
        updateURLComponents(computeURL(file));
    }

    protected void initializeServerControl(ILaunchConfiguration configuration) {
        try {
            String serverName = configuration.getAttribute(IPHPDebugCorePreferenceKeys.ATTR_SERVER_NAME, ""); //$NON-NLS-1$
            if (serverName != null && !serverName.equals("")) { //$NON-NLS-1$
                server = PHPServersManager.getServer(serverName);
                if (server == null) { // server no longer exists
                    setErrorMessage(PHPServerUIMessages.getString("ServerTab.invalidServerError")); //$NON-NLS-1$
                    selectDefaultServer(configuration);
                } else {
                    serverCombo.setText(server.getName());
                }
            } else {
                selectDefaultServer(configuration);
            }
            // flag should only be set if launch has been attempted on the config
            if (configuration.getAttribute(READ_ONLY, false)) {
                serverCombo.setEnabled(false);
            }
        } catch (Exception e) {
        }
    }

    protected void initializeDebuggerControl(ILaunchConfiguration configuration) {
        try {
            String debuggerID = configuration.getAttribute(IPHPDebugCorePreferenceKeys.PHP_DEBUGGER_ID, "");
            if (debuggerID != null && !debuggerID.equals("")) { //$NON-NLS-1$
                fDebuggersCombo.setText(PHPDebuggersRegistry.getDebuggerName(debuggerID));
            } else {
                selectDefaultDebugger(configuration);
            }
            // flag should only be set if launch has been attempted on the config
            if (configuration.getAttribute(READ_ONLY, false)) {
                fDebuggersCombo.setEnabled(false);
            }
        } catch (Exception e) {
        }
    }

    /*
     * Select the default server.
     */
    private void selectDefaultServer(ILaunchConfiguration configuration) throws CoreException {
        if (serverCombo != null && serverCombo.getItemCount() > 0) {
            // Select the default server
            String projectName = configuration.getAttribute(IPHPDebugConstants.PHP_Project, (String) null);
            IProject project = null;
            if (projectName != null) {
                project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
            }
            IServer defaultServer = PHPServersManager.getDefaultServer(project);
            int nameIndex = serverCombo.indexOf(defaultServer.getName());
            if (nameIndex > -1) {
                serverCombo.select(nameIndex);
            } else {
                serverCombo.select(0);
            }
            server = PHPServersManager.getServer(serverCombo.getText());
        }
    }

    /*
     * Select the default debugger for this launch configuration.
     */
    private void selectDefaultDebugger(ILaunchConfiguration configuration) throws CoreException {
        if (fDebuggersCombo != null && fDebuggersCombo.getItemCount() > 0) {
            String projectName = configuration.getAttribute(IPHPDebugConstants.PHP_Project, (String) null);
            IProject project = null;
            if (projectName != null) {
                project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
            }
            String defaultDebuggerID = PHPProjectPreferences.getDefaultDebuggerID(project);
            String debuggerName = PHPDebuggersRegistry.getDebuggerName(defaultDebuggerID);
            int nameIndex = fDebuggersCombo.indexOf(debuggerName);
            if (nameIndex > -1) {
                fDebuggersCombo.select(nameIndex);
            } else {
                fDebuggersCombo.select(0);
            }
        }
    }

    /**
     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(ILaunchConfigurationWorkingCopy)
     */
    public void performApply(ILaunchConfigurationWorkingCopy configuration) {
        configuration.setAttribute(IPHPDebugCorePreferenceKeys.PHP_DEBUGGER_ID, getSelectedDebuggerId());
        if (server != null) {
            configuration.setAttribute(IPHPDebugCorePreferenceKeys.ATTR_SERVER_NAME, server.getName());
        } else {
            configuration.setAttribute(IPHPDebugCorePreferenceKeys.ATTR_SERVER_NAME, (String) null);
        }
        String fileName = fFile.getText();

        String urlPath = fURLPath.getText().replace('\\', '/');
        if (urlPath.startsWith("/")) {
            urlPath = urlPath.substring(1);
        }
        String url = fURLHost.getText() + urlPath;
        configuration.setAttribute(IPHPDebugCorePreferenceKeys.ATTR_SERVER_FILE_NAME, fileName);
        configuration.setAttribute(IPHPDebugCorePreferenceKeys.ATTR_SERVER_BASE_URL, url);
        configuration.setAttribute(IPHPDebugCorePreferenceKeys.ATTR_AUTO_GENERATED_URL,
                autoGeneratedURL.getSelection());
        configuration.setAttribute(IDebugParametersKeys.FIRST_LINE_BREAKPOINT, breakOnFirstLine.getSelection());

        // if (this.useCurrentPage.getSelection()) {
        // configuration.setAttribute(IPHPDebugConstants.ATTR_USE_SPECIFIC_FILE, false);
        // } else {
        // Always use specific file selection for the remote debug
        configuration.setAttribute(IPHPDebugCorePreferenceKeys.ATTR_USE_SPECIFIC_FILE, true);
        // }

        boolean autoGenerateURL = autoGeneratedURL.getSelection();
        fURLLabel.setEnabled(!autoGenerateURL);
        fURLPath.setEnabled(!autoGenerateURL);

        applyExtension(configuration);

        if (saveWorkingCopy) {
            try {
                configuration.doSave();
            } catch (CoreException e) {
            }
            saveWorkingCopy = false;
        }
        applyLaunchDelegateConfiguration(configuration);
    }

    /**
     * Apply the launch configuration delegate class that will be used when using this launch with the
     * {@link PHPLaunchDelegateProxy}. This method sets the class name of the launch delegate that is associated with
     * the debugger that was defined to this launch configuration. The class name is retrieved from the debugger's
     * {@link IDebuggerConfiguration}.
     * 
     * @param configuration
     *            A ILaunchConfigurationWorkingCopy
     */
    protected void applyLaunchDelegateConfiguration(final ILaunchConfigurationWorkingCopy configuration) {
        String debuggerID = null;
        try {
            debuggerID = configuration.getAttribute(IPHPDebugCorePreferenceKeys.PHP_DEBUGGER_ID,
                    PHPDebugEPLPlugin.getCurrentDebuggerId());
            AbstractDebuggerConfiguration debuggerConfiguration = PHPDebuggersRegistry
                    .getDebuggerConfiguration(debuggerID);
            configuration.setAttribute(IPHPDebugCorePreferenceKeys.CONFIGURATION_DELEGATE_CLASS,
                    debuggerConfiguration.getWebLaunchDelegateClass());
        } catch (Exception e) {
            PHPDebugEPLPlugin.logError(e);
        }
        updateDebugServerTesters();
    }

    // In case this is a debug mode, display 'Break on first line' attribute checkbox.
    protected void createBreakControl(Composite parent) {

        Group group = new Group(parent, SWT.NONE);
        group.setText("Breakpoint");
        GridLayout layout = new GridLayout();
        layout.numColumns = 1;
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        group.setLayout(layout);
        group.setLayoutData(gridData);

        breakOnFirstLine = createCheckButton(group, "Break at First Line");
        breakOnFirstLine.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                setDirty(true);
                updateLaunchConfigurationDialog();
            }
        });
        // Disables/Enables all the controls according the the debug mode.
        String mode = getLaunchConfigurationDialog().getMode();
        boolean isDebugMode = ILaunchManager.DEBUG_MODE.equals(mode);
        breakOnFirstLine.setEnabled(isDebugMode);
    }

    protected void applyExtension(ILaunchConfigurationWorkingCopy configuration) {
        return;
    }

    /**
     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(ILaunchConfiguration)
     */
    public boolean isValid(ILaunchConfiguration launchConfig) {
        setMessage(null);
        setErrorMessage(null);
        // TODO - Note that this method of removing invalid launches is still buggy
        // In order to fix it completely, we might have to perform similar checks when removing or renaming a server
        // from
        // the PHP Servers preferences page.
        try {
            String serverName = launchConfig.getAttribute(IPHPDebugCorePreferenceKeys.ATTR_SERVER_NAME, ""); //$NON-NLS-1$
            if (!serverName.equals("")) { //$NON-NLS-1$
                IServer server = PHPServersManager.getServer(serverName);
                if (server == null) {
                    deleteLaunchConfiguration(launchConfig);
                    ILaunchConfiguration[] allConfigurations = DebugPlugin.getDefault().getLaunchManager()
                            .getLaunchConfigurations();
                    for (ILaunchConfiguration element : allConfigurations) {
                        launchConfig = element;
                        serverName = launchConfig.getAttribute(IPHPDebugCorePreferenceKeys.ATTR_SERVER_NAME, ""); //$NON-NLS-1$
                        if (!serverName.equals("") && PHPServersManager.getServer(serverName) == null) { //$NON-NLS-1$
                            // The server was removed, so remove this launch configuration!
                            deleteLaunchConfiguration(launchConfig);
                        }
                    }
                    setErrorMessage(PHPServerUIMessages.getString("ServerTab.missingServer"));//$NON-NLS-1$
                    return false;
                }
            } else {
                setErrorMessage(PHPServerUIMessages.getString("ServerTab.missingServer"));//$NON-NLS-1$
                return false;
            }

            // if (!useCurrentPage.getSelection()) {
            // Always use specific file selection for the remote debug
            String fileName = launchConfig.getAttribute(IPHPDebugCorePreferenceKeys.ATTR_SERVER_FILE_NAME, ""); //$NON-NLS-1$
            IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(fileName);
            if (!(resource instanceof IFile)) {
                if (fileName.trim().length() == 0) {
                    setErrorMessage(PHPServerUIMessages.getString("ServerTab.specifyInitialScript")); //$NON-NLS-1$
                } else {
                    setErrorMessage(PHPServerUIMessages.getString("ServerTab.file_project_doesNotExist")); //$NON-NLS-1$
                }
                return false;
            }
            // }
        } catch (CoreException e) {
            // ignore
        }
        return isValidExtension(launchConfig);
    }

    private void deleteLaunchConfiguration(final ILaunchConfiguration launchConfig) throws CoreException {
        Display.getDefault().asyncExec(new Runnable() {
            public void run() {
                ILaunchConfiguration config = launchConfig;
                try {
                    if (config instanceof ILaunchConfigurationWorkingCopy) {
                        config = ((ILaunchConfigurationWorkingCopy) config).getOriginal();
                    }
                    if (config != null) {
                        config.delete();
                    }
                } catch (CoreException ce) {
                    // Ignore
                }
            }
        });

    }

    protected boolean isValidExtension(ILaunchConfiguration launchConfig) {
        return true;
    }

    /**
     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage()
     */
    public Image getImage() {
        return null; // TODO - ImageResource.getImage(ImageResource.IMG_SERVER);
    }

    /**
     * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
     */
    public String getName() {
        return PHPServerUIMessages.getString("ServerTab.server"); //$NON-NLS-1$
    }

    /*
     * Fix for Bug 60163 Accessibility: New Builder Dialog missing object info for textInput controls
     */
    public void addControlAccessibleListener(Control control, String controlName) {
        // strip mnemonic (&)
        String[] strs = controlName.split("&"); //$NON-NLS-1$
        StringBuffer stripped = new StringBuffer();
        for (String element : strs) {
            stripped.append(element);
        }
        control.getAccessible().addAccessibleListener(new ControlAccessibleListener(stripped.toString()));
    }

    private class ControlAccessibleListener extends AccessibleAdapter {
        private String controlName;

        ControlAccessibleListener(String name) {
            controlName = name;
        }

        public void getName(AccessibleEvent e) {
            e.result = controlName;
        }

    }

    /**
     * Returns the id of the selected debugger.
     * 
     * @return The debugger's id.
     */
    private String getSelectedDebuggerId() {
        int selectedIndex = fDebuggersCombo.getSelectionIndex();
        String debuggerId = DebuggerCommunicationDaemon.ZEND_DEBUGGER_ID; // default
        if (selectedIndex > -1 && fDebuggerIds.size() > selectedIndex) {
            debuggerId = fDebuggerIds.toArray()[selectedIndex].toString();
        }
        return debuggerId;
    }

    /**
     * Returns a new server after creating it using the servers wizard.
     * 
     * @return A new external web server; Null, if the wizard did not create a new server.
     */
    protected IServer getServerFromWizard() {
        // TODO - Right now we only display an ExternalServer dialog. Later we should add more specific types, such as
        // XAMPP etc.
        try {
            IServer newServer = WebServerCorePlugin.getDefault().getServerManager()
                    .createServer("com.aptana.webserver.external");
            if (newServer != null) {
                Dialog dlg = new ExternalWebServerPropertyDialog.Provider()
                        .createPropertyDialog(new SameShellProvider(getShell()));
                if (dlg != null) {
                    if (dlg instanceof IPropertyDialog) {
                        ((IPropertyDialog) dlg).setPropertySource(newServer);
                    }
                    if (dlg.open() == Window.OK) {
                        WebServerCorePlugin.getDefault().getServerManager().add(newServer);
                        return newServer;
                    }
                }
            }
        } catch (CoreException e) {
            IdeLog.logError(PHPDebugEPLPlugin.getDefault(), e);
        }
        return null;

        // ExternalWebServerPropertyDialog dialog = new ExternalWebServerPropertyDialog(getShell());
        // dialog.open();
        // return (IServer) dialog.getPropertySource();
    }

    protected class WidgetListener extends SelectionAdapter implements ModifyListener {
        public void modifyText(ModifyEvent e) {
            updateLaunchConfigurationDialog();
            initializeURLControl();
        }

        public void widgetSelected(SelectionEvent e) {
            setDirty(true);
            Object source = e.getSource();

            if (source == fileButton) {
                handleFileButtonSelected();
            } else if (source == createNewServer) {
                handleServerButtonSelected();
            } else if (source == configureServers) {
                handleConfigureButtonSelected();
            } else if (source == mapPaths) {
                handlePathMapping();
            } else if (source == validateDebuggerBtn) {
                handleDebuggerValidation();
            }
        }
    }
}