/******************************************************************************* * Copyright (c) 2009 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: * IBM Corporation - initial API and implementation * Zend Technologies *******************************************************************************/ /** * */ package org.eclipse.php.internal.debug.core.zend.debugger; import java.net.Inet4Address; import java.net.URL; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.preferences.DefaultScope; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.IPreferencesService; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.debug.internal.ui.SWTFactory; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.NLS; import org.eclipse.php.debug.daemon.communication.ICommunicationDaemon; import org.eclipse.php.internal.core.util.NetworkMonitor; import org.eclipse.php.internal.core.util.NetworkMonitor.IHostsValidationListener; import org.eclipse.php.internal.core.util.NetworkUtil; import org.eclipse.php.internal.debug.core.Logger; import org.eclipse.php.internal.debug.core.PHPDebugCoreMessages; import org.eclipse.php.internal.debug.core.PHPDebugPlugin; import org.eclipse.php.internal.debug.core.PHPDebugUtil; import org.eclipse.php.internal.debug.core.launching.PHPLaunchUtilities; import org.eclipse.php.internal.debug.core.preferences.AbstractDebuggerConfigurationDialog; import org.eclipse.php.internal.debug.core.preferences.PHPDebugCorePreferenceNames; import org.eclipse.php.internal.debug.core.zend.communication.BroadcastDaemon; import org.eclipse.php.internal.debug.core.zend.communication.DebuggerCommunicationDaemon; import org.eclipse.php.internal.debug.daemon.communication.DaemonsRegistry; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.events.*; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.*; import org.eclipse.ui.PlatformUI; import org.osgi.framework.Bundle; import org.osgi.service.prefs.BackingStoreException; /** * Zend debugger configuration class. * * @author Shalom Gibly * @since PDT 1.0 */ public class ZendDebuggerConfigurationDialog extends AbstractDebuggerConfigurationDialog { protected ZendDebuggerConfiguration fDebuggerConfiguration; private Button fRunWithDebugInfo; private Text fDebugTextBox; private Text fClientIP; private Button fClientIPButton; private Text fDebugResponseTimeout; private Button fUseNewProtocol; private Button fAutoModeButton; private Button fManualModeButton; private Text fBroadcastPortText; private Text fDummyFileText; private Button fUseSSLButton; private NetworkMonitor fNetworkMonitor; private Composite fClientIpComposite; private Image fTitleImage; /** * Constructs a new Zend debugger configuration dialog. * * @param zendDebuggerConfiguration * @param parentShell */ public ZendDebuggerConfigurationDialog(ZendDebuggerConfiguration zendDebuggerConfiguration, Shell parentShell) { super(parentShell); setShellStyle(getShellStyle() | SWT.RESIZE); this.fDebuggerConfiguration = zendDebuggerConfiguration; this.fNetworkMonitor = new NetworkMonitor(); } protected Control createDialogArea(Composite parent) { initializeDialogUnits(parent); parent = (Composite) super.createDialogArea(parent); GridData ptGridData = (GridData) parent.getLayoutData(); ptGridData.widthHint = convertWidthInCharsToPixels(120); // Set dialog title. image, etc. getShell().setText(PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_Dialog_title); setTitle(PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_zendDebuggerSettings); setMessage(PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_Dialog_description); fTitleImage = getDialogImage(); if (fTitleImage != null) setTitleImage(fTitleImage); getShell().addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { if (fTitleImage != null) fTitleImage.dispose(); } }); // Connection settings Composite connectionSettingsGroup = createSubsection(parent, PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_Connection_settings_group); addLabelControl(connectionSettingsGroup, PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_client_host_ip, PHPDebugCorePreferenceNames.CLIENT_IP); fAutoModeButton = new Button(connectionSettingsGroup, SWT.RADIO); fAutoModeButton.setText(PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_AutoMode); fAutoModeButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (fAutoModeButton.getSelection()) { // bring back a default value String value = DefaultScope.INSTANCE.getNode(PHPDebugPlugin.ID) .get(PHPDebugCorePreferenceNames.CLIENT_IP, "127.0.0.1"); //$NON-NLS-1$ fClientIP.setText(value); fClientIPButton.setText(PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_Reload); fClientIpComposite.layout(true); } } }); fManualModeButton = new Button(connectionSettingsGroup, SWT.RADIO); fManualModeButton.setText(PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_ManualMode); fManualModeButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { fClientIP.setEnabled(fManualModeButton.getSelection()); fClientIPButton.setText(PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_Configure); fClientIpComposite.layout(true); } }); new Label(connectionSettingsGroup, SWT.NONE); fClientIpComposite = new Composite(connectionSettingsGroup, SWT.NONE); fClientIpComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); GridLayout cicLayout = new GridLayout(3, false); cicLayout.marginHeight = 0; cicLayout.marginWidth = 0; fClientIpComposite.setLayout(cicLayout); fClientIP = addTextField(fClientIpComposite, PHPDebugCorePreferenceNames.CLIENT_IP, 0, 1); fClientIP.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { validate(); } }); GridData gridData = (GridData) fClientIP.getLayoutData(); gridData.widthHint = convertWidthInCharsToPixels(80); fClientIPButton = SWTFactory.createPushButton(fClientIpComposite, null, null); fClientIPButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } @Override public void widgetSelected(SelectionEvent e) { if (fAutoModeButton.getSelection()) { reloadIPs(); } else if (fManualModeButton.getSelection()) { openIPsDialog(); } } }); addLabelControl(connectionSettingsGroup, PHPDebugCoreMessages.DebuggerConfigurationDialog_debugPort, PHPDebugCorePreferenceNames.ZEND_DEBUG_PORT); fDebugTextBox = addTextField(connectionSettingsGroup, PHPDebugCorePreferenceNames.ZEND_DEBUG_PORT, 6, 2); gridData = (GridData) fDebugTextBox.getLayoutData(); gridData.widthHint = convertWidthInCharsToPixels(80); fDebugTextBox.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent arg0) { validate(); } }); addLabelControl(connectionSettingsGroup, PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_debug_response_timeout, PHPDebugCorePreferenceNames.DEBUG_RESPONSE_TIMEOUT); fDebugResponseTimeout = addTextField(connectionSettingsGroup, PHPDebugCorePreferenceNames.DEBUG_RESPONSE_TIMEOUT, 0, 2); gridData = (GridData) fDebugResponseTimeout.getLayoutData(); gridData.widthHint = convertWidthInCharsToPixels(80); fDebugResponseTimeout.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent arg0) { validate(); } }); createNoteComposite(connectionSettingsGroup.getFont(), connectionSettingsGroup, PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_Note_label, PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_Note_text, 3); // General settings Composite generalSettingsGroup = createSubsection(parent, PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_General_settings_group); addLabelControl(generalSettingsGroup, PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_Broadcast_port, PHPDebugCorePreferenceNames.ZEND_DEBUG_BROADCAST_PORT); fBroadcastPortText = addTextField(generalSettingsGroup, PHPDebugCorePreferenceNames.ZEND_DEBUG_BROADCAST_PORT, 6, 2); gridData = (GridData) fBroadcastPortText.getLayoutData(); gridData.widthHint = convertWidthInCharsToPixels(100); fBroadcastPortText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent arg0) { validate(); } }); addLabelControl(generalSettingsGroup, PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_Dummy_file_name, PHPDebugCorePreferenceNames.ZEND_DEBUG_DUMMY_FILE); fDummyFileText = addTextField(generalSettingsGroup, PHPDebugCorePreferenceNames.ZEND_DEBUG_DUMMY_FILE, 20, 2); gridData = (GridData) fDummyFileText.getLayoutData(); gridData.widthHint = convertWidthInCharsToPixels(100); fUseSSLButton = addCheckBox(generalSettingsGroup, PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_UseSSLEncryption, PHPDebugCorePreferenceNames.ZEND_DEBUG_ENCRYPTED_SSL_DATA, 0); fRunWithDebugInfo = addCheckBox(generalSettingsGroup, PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_runWithDebugInfo, PHPDebugCorePreferenceNames.RUN_WITH_DEBUG_INFO, 0); fUseNewProtocol = addCheckBox(generalSettingsGroup, PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_useNewProtocol, PHPDebugCorePreferenceNames.ZEND_NEW_PROTOCOL, 0); // Initialize the dialog's values. internalInitializeValues(); return parent; } private Image getDialogImage() { // TODO - whole dialog should be in debug UI plug-in ImageDescriptor desc = ImageDescriptor.getMissingImageDescriptor(); Bundle bundle = Platform.getBundle("org.eclipse.php.debug.ui"); //$NON-NLS-1$ URL url = null; if (bundle != null) { url = FileLocator.find(bundle, new Path("$nl$/icon/full/wizban/zend_debugger_conf_wiz.png"), null); //$NON-NLS-1$ desc = ImageDescriptor.createFromURL(url); return desc.createImage(); } return null; } private void internalInitializeValues() { IPreferencesService service = Platform.getPreferencesService(); fRunWithDebugInfo.setSelection( service.getBoolean(PHPDebugPlugin.ID, PHPDebugCorePreferenceNames.RUN_WITH_DEBUG_INFO, false, null)); fDebugTextBox.setText(Integer .toString(service.getInt(PHPDebugPlugin.ID, PHPDebugCorePreferenceNames.ZEND_DEBUG_PORT, 0, null))); IEclipsePreferences instanceScope = InstanceScope.INSTANCE.getNode(PHPDebugPlugin.ID); String customClientHosts = instanceScope.get(PHPDebugCorePreferenceNames.CLIENT_IP, null); fAutoModeButton.setSelection(customClientHosts == null); fManualModeButton.setSelection(customClientHosts != null); fClientIP.setEnabled(customClientHosts != null); fClientIP.setText(PHPDebugPlugin.getDebugHosts()); fDebugResponseTimeout.setText(Integer.toString( service.getInt(PHPDebugPlugin.ID, PHPDebugCorePreferenceNames.DEBUG_RESPONSE_TIMEOUT, 0, null))); fUseNewProtocol.setSelection( service.getBoolean(PHPDebugPlugin.ID, PHPDebugCorePreferenceNames.ZEND_NEW_PROTOCOL, false, null)); fBroadcastPortText.setText(Integer.toString( service.getInt(PHPDebugPlugin.ID, PHPDebugCorePreferenceNames.ZEND_DEBUG_BROADCAST_PORT, 0, null))); fDummyFileText.setText( service.getString(PHPDebugPlugin.ID, PHPDebugCorePreferenceNames.ZEND_DEBUG_DUMMY_FILE, null, null)); fUseSSLButton.setSelection(service.getBoolean(PHPDebugPlugin.ID, PHPDebugCorePreferenceNames.ZEND_DEBUG_ENCRYPTED_SSL_DATA, false, null)); fClientIPButton.setText( fManualModeButton.getSelection() ? PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_Configure : PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_Reload); } private String getClientIPs(String userHosts) { final List<Inet4Address> detectedIPs = new ArrayList<Inet4Address>(); BusyIndicator.showWhile(PlatformUI.getWorkbench().getDisplay(), new Runnable() { public void run() { detectedIPs.addAll(fNetworkMonitor.getAllAddresses()); } }); String[] userHostsArray = PHPDebugUtil.getZendHostsArray(userHosts); List<Inet4Address> userIPs = new ArrayList<Inet4Address>(); for (String userHost : userHostsArray) { Inet4Address address = NetworkUtil.getByName(userHost, 2000); if (address != null) userIPs.add(address); } ConfigureHostsDialog configureIPs = new ConfigureHostsDialog(userIPs, detectedIPs); int choice = configureIPs.open(); if (choice != Window.OK) return ""; //$NON-NLS-1$ List<Inet4Address> selectdIPs = configureIPs.getSelectedIPs(); StringBuffer stringBuffer = new StringBuffer(); Iterator<Inet4Address> ipsIterator = selectdIPs.iterator(); if (ipsIterator.hasNext()) stringBuffer.append(ipsIterator.next().getHostAddress()); while (ipsIterator.hasNext()) { stringBuffer.append(", " + ipsIterator.next().getHostAddress()); //$NON-NLS-1$ } return stringBuffer.toString(); } private void reloadIPs() { BusyIndicator.showWhile(PlatformUI.getWorkbench().getDisplay(), new Runnable() { public void run() { // Reset network monitor to have the latest results fNetworkMonitor = new NetworkMonitor(); List<Inet4Address> addresses = new ArrayList<Inet4Address>(); addresses.addAll(fNetworkMonitor.getPrivateAddresses()); addresses.add(NetworkUtil.LOCALHOST); StringBuffer addressesString = new StringBuffer(); for (Inet4Address address : addresses) { addressesString.append((addressesString.length() != 0 ? ", " : "") + address.getHostAddress()); } fClientIP.setText(addressesString.toString()); } }); validate(); } private void openIPsDialog() { String clientIPs = getClientIPs(fClientIP.getText()); if (!clientIPs.isEmpty()) { fClientIP.setText(clientIPs); validate(); } } protected void okPressed() { IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode(PHPDebugPlugin.ID); prefs.putBoolean(PHPDebugCorePreferenceNames.RUN_WITH_DEBUG_INFO, fRunWithDebugInfo.getSelection()); prefs.put(PHPDebugCorePreferenceNames.ZEND_DEBUG_PORT, fDebugTextBox.getText()); prefs.putInt(PHPDebugCorePreferenceNames.ZEND_DEBUG_BROADCAST_PORT, Integer.parseInt(fBroadcastPortText.getText())); prefs.put(PHPDebugCorePreferenceNames.ZEND_DEBUG_DUMMY_FILE, fDummyFileText.getText().trim()); if (fAutoModeButton.getSelection()) { prefs.remove(PHPDebugCorePreferenceNames.CLIENT_IP); } else { prefs.put(PHPDebugCorePreferenceNames.CLIENT_IP, fClientIP.getText()); } prefs.putInt(PHPDebugCorePreferenceNames.DEBUG_RESPONSE_TIMEOUT, Integer.parseInt(fDebugResponseTimeout.getText())); prefs.putBoolean(PHPDebugCorePreferenceNames.ZEND_NEW_PROTOCOL, fUseNewProtocol.getSelection()); prefs.putBoolean(PHPDebugCorePreferenceNames.ZEND_DEBUG_ENCRYPTED_SSL_DATA, fUseSSLButton.getSelection()); try { prefs.flush(); } catch (BackingStoreException e) { Logger.logException(e); } super.okPressed(); } protected void validate() { // Reset state setMessage(PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_Dialog_description); // Check errors String debugPort = fDebugTextBox.getText(); Integer debugPortNumber = null; try { debugPortNumber = Integer.valueOf(debugPort); int i = debugPortNumber.intValue(); if (i < 1 || i > 65535) { setMessage(PHPDebugCoreMessages.DebugConfigurationDialog_invalidPortRange, IMessageProvider.ERROR); return; } } catch (NumberFormatException ex) { setMessage(PHPDebugCoreMessages.DebugConfigurationDialog_invalidPort, IMessageProvider.ERROR); return; } catch (Exception e) { setMessage(PHPDebugCoreMessages.DebugConfigurationDialog_invalidPort, IMessageProvider.ERROR); return; } String broadcastPort = fBroadcastPortText.getText(); Integer broadcastPortNumber = null; try { broadcastPortNumber = Integer.valueOf(broadcastPort); int i = broadcastPortNumber.intValue(); if (i < 1 || i > 65535) { setMessage(PHPDebugCoreMessages.DebugConfigurationDialog_invalidPortRange, IMessageProvider.ERROR); return; } } catch (NumberFormatException ex) { setMessage(PHPDebugCoreMessages.DebugConfigurationDialog_invalidPort, IMessageProvider.ERROR); return; } catch (Exception e) { setMessage(PHPDebugCoreMessages.DebugConfigurationDialog_invalidPort, IMessageProvider.ERROR); return; } String responseTime = fDebugResponseTimeout.getText(); Integer responseTimeout = null; try { responseTimeout = Integer.valueOf(responseTime); int i = responseTimeout.intValue(); if (i < 5000) { setMessage(NLS.bind(PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_invalid_response_time, 5000), IMessageProvider.ERROR); return; } } catch (Exception exc) { setMessage(PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_invalid_response_time_exc, IMessageProvider.ERROR); return; } // Check warnings String[] clientHosts = PHPDebugUtil.getZendHostsArray(fClientIP.getText()); fNetworkMonitor.validate(clientHosts, new IHostsValidationListener[] { new IHostsValidationListener() { public void validated(List<String> invalidAddresses) { if (!invalidAddresses.isEmpty()) { StringBuilder addresses = new StringBuilder(); for (String address : invalidAddresses) { addresses.append((addresses.length() != 0 ? ", " : "") //$NON-NLS-1$ //$NON-NLS-2$ + '\'' + address + '\''); } String message; if (invalidAddresses.size() == 1) { message = MessageFormat.format( PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_ClientIPWarning, addresses.toString()); } else { message = MessageFormat.format( PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_ClientIPsWarning, addresses.toString()); } final String warningMessage = message; PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { public void run() { if (!getShell().isDisposed() && getButton(IDialogConstants.OK_ID).isEnabled()) setMessage(warningMessage, IMessageProvider.WARNING); } }); } } } }); if (!PHPLaunchUtilities.isPortAvailable(debugPortNumber) && !PHPLaunchUtilities .isDebugDaemonActive(debugPortNumber, DebuggerCommunicationDaemon.ZEND_DEBUGGER_ID)) { setMessage(NLS.bind(PHPDebugCoreMessages.DebugConfigurationDialog_PortInUse, debugPort), IMessageProvider.WARNING); } if (!PHPLaunchUtilities.isPortAvailable(broadcastPortNumber)) { for (ICommunicationDaemon daemon : DaemonsRegistry.getDaemons()) { if (daemon instanceof BroadcastDaemon && !((BroadcastDaemon) daemon).isListening(broadcastPortNumber)) { setMessage(NLS.bind(PHPDebugCoreMessages.DebugConfigurationDialog_PortInUse, broadcastPort), IMessageProvider.WARNING); } } } } }