/******************************************************************************* * 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.wizards; import static org.eclipse.php.internal.debug.core.zend.debugger.ZendDebuggerSettingsConstants.PROP_CLIENT_IP; import static org.eclipse.php.internal.debug.core.zend.debugger.ZendDebuggerSettingsConstants.PROP_CLIENT_PORT; import static org.eclipse.php.internal.debug.core.zend.debugger.ZendDebuggerSettingsConstants.PROP_RESPONSE_TIMEOUT; import java.net.Inet4Address; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.debug.internal.ui.SWTFactory; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.NLS; import org.eclipse.php.debug.ui.DebugServerConnectionTestRegistry; import org.eclipse.php.debug.ui.IDebugServerConnectionTest; 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.PHPDebugCoreMessages; import org.eclipse.php.internal.debug.core.PHPDebugUtil; import org.eclipse.php.internal.debug.core.daemon.AbstractDebuggerCommunicationDaemon; import org.eclipse.php.internal.debug.core.debugger.IDebuggerSettingsWorkingCopy; import org.eclipse.php.internal.debug.core.launching.PHPLaunchUtilities; import org.eclipse.php.internal.debug.core.zend.communication.DebuggerCommunicationDaemon; import org.eclipse.php.internal.debug.core.zend.debugger.ConfigureHostsDialog; import org.eclipse.php.internal.debug.core.zend.debugger.ZendDebuggerConfiguration; import org.eclipse.php.internal.debug.core.zend.debugger.ZendDebuggerHostProposalComputer; import org.eclipse.php.internal.debug.core.zend.debugger.ZendDebuggerSettingsUtil; import org.eclipse.php.internal.server.core.Server; import org.eclipse.php.internal.server.core.manager.ServersManager; import org.eclipse.php.internal.ui.wizards.CompositeFragment; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; 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.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.*; import org.eclipse.ui.PlatformUI; /** * Zend debugger settings section for PHP server. * * @author Bartlomiej Laczkowski */ @SuppressWarnings("restriction") public class ZendDebuggerServerSettingsSection implements IDebuggerSettingsSection { private IDebuggerSettingsWorkingCopy settingsWorkingCopy; private CompositeFragment compositeFragment; private Composite settingsComposite; private Text clientIpText; private NetworkMonitor networkMonitor; private boolean skipNetworkMonitor = false; /** * Constructor. */ public ZendDebuggerServerSettingsSection(final CompositeFragment compositeFragment, final Composite debuggerSettingsComposite, final IDebuggerSettingsWorkingCopy settingsWorkingCopy) { this.settingsWorkingCopy = settingsWorkingCopy; this.compositeFragment = compositeFragment; this.settingsComposite = debuggerSettingsComposite; this.networkMonitor = new NetworkMonitor(); createContents(); } /* * (non-Javadoc) * * @see org.eclipse.php.internal.debug.ui.wizards.IDebuggerSettingsSection# * performOK () */ @Override public boolean performOK() { return true; } /* * (non-Javadoc) * * @see org.eclipse.php.internal.debug.ui.wizards.IDebuggerSettingsSection# * performCancel() */ @Override public boolean performCancel() { return true; } /* * (non-Javadoc) * * @see org.eclipse.php.internal.debug.ui.wizards.IDebuggerSettingsSection# * validate () */ public void validate() { // Reset state compositeFragment.setMessage(compositeFragment.getDescription(), IMessageProvider.NONE); // Check errors String clientIp = (String) settingsWorkingCopy.getAttribute(PROP_CLIENT_IP); if (clientIp == null || clientIp.isEmpty()) { compositeFragment.setMessage(Messages.ZendDebuggerServerSettingsSection_Client_IP_is_missing, IMessageProvider.ERROR); return; } String clientPort = (String) settingsWorkingCopy.getAttribute(PROP_CLIENT_PORT); if (clientPort == null || clientPort.isEmpty()) { compositeFragment.setMessage(Messages.ZendDebuggerServerSettingsSection_Client_port_is_missing, IMessageProvider.ERROR); return; } String responseTime = (String) settingsWorkingCopy.getAttribute(PROP_RESPONSE_TIMEOUT); Integer responseTimeout = null; try { responseTimeout = Integer.valueOf(responseTime); int i = responseTimeout.intValue(); if (i < 5000) { compositeFragment.setMessage( NLS.bind(PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_invalid_response_time, 5000), IMessageProvider.ERROR); return; } } catch (Exception exc) { compositeFragment.setMessage(PHPDebugCoreMessages.ZendDebuggerConfigurationDialog_invalid_response_time_exc, IMessageProvider.ERROR); return; } // Check warnings String[] clientHosts = PHPDebugUtil.getZendHostsArray(clientIpText.getText()); // Check invalid addresses if (!skipNetworkMonitor) { networkMonitor.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( Messages.ZendDebuggerServerSettingsSection_Client_host_IP_might_be_invalid, addresses.toString()); } else { message = MessageFormat.format( Messages.ZendDebuggerServerSettingsSection_Client_hosts_IPs_might_be_invalid, addresses.toString()); } final String warningMessage = message; PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { public void run() { if (!compositeFragment.isDisposed() && compositeFragment.isVisible() && compositeFragment.isComplete()) compositeFragment.setMessage(warningMessage, IMessageProvider.WARNING); } }); } else { skipNetworkMonitor = true; PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { public void run() { if (!compositeFragment.isDisposed() && compositeFragment.isVisible()) validate(); } }); } } } }); } else { skipNetworkMonitor = false; } // Check redundant hosts if (clientHosts.length > 1) { compositeFragment.setMessage(Messages.ZendDebuggerServerSettingsSection_Client_host_IPS_might_be_redundant, IMessageProvider.WARNING); return; } Integer portNumber = null; try { portNumber = Integer.valueOf(clientPort); int i = portNumber.intValue(); if (i < 1 || i > 65535) { compositeFragment.setMessage(PHPDebugCoreMessages.DebugConfigurationDialog_invalidPortRange, IMessageProvider.ERROR); return; } } catch (NumberFormatException ex) { compositeFragment.setMessage(PHPDebugCoreMessages.DebugConfigurationDialog_invalidPort, IMessageProvider.ERROR); return; } catch (Exception e) { compositeFragment.setMessage(PHPDebugCoreMessages.DebugConfigurationDialog_invalidPort, IMessageProvider.ERROR); return; } // Check ports if (!PHPLaunchUtilities.isPortAvailable(portNumber) && !PHPLaunchUtilities.isDebugDaemonActive(portNumber, DebuggerCommunicationDaemon.ZEND_DEBUGGER_ID)) { compositeFragment.setMessage( MessageFormat.format(Messages.DebuggerCommonSettingsSection_Port_is_already_in_use, clientPort), IMessageProvider.WARNING); return; } } /* * (non-Javadoc) * * @see org.eclipse.php.internal.debug.ui.wizards.IDebuggerSettingsSection# * canTest () */ @Override public boolean canTest() { return true; } /* * (non-Javadoc) * * @see org.eclipse.php.internal.debug.ui.wizards.IDebuggerSettingsSection# * performTest() */ @Override public void performTest() { IDebugServerConnectionTest[] tests = DebugServerConnectionTestRegistry.getTests(ZendDebuggerConfiguration.ID); Server server = (Server) compositeFragment.getData(); int port = ZendDebuggerSettingsUtil.getDebugPort(settingsWorkingCopy.getOwnerId()); Set<Integer> allDebugPorts = PHPDebugUtil.getDebugPorts(ZendDebuggerConfiguration.ID); AbstractDebuggerCommunicationDaemon tmpDaemon = null; if (!allDebugPorts.contains(port)) tmpDaemon = DebuggerCommunicationDaemon.createDaemon(port); for (IDebugServerConnectionTest test : tests) { test.testConnection(server, PlatformUI.getWorkbench().getDisplay().getActiveShell()); } if (tmpDaemon != null) { tmpDaemon.stopListen(); } } protected void createContents() { // Main composite Composite settingsSection = new Composite(settingsComposite, SWT.NONE); GridLayout ssLayout = new GridLayout(); ssLayout.marginHeight = 0; ssLayout.marginWidth = 0; settingsSection.setLayout(ssLayout); GridData sGridData = new GridData(SWT.FILL, SWT.FILL, true, true); sGridData.horizontalSpan = 2; settingsSection.setLayoutData(sGridData); // Connection settings group createSettingsGroup(settingsSection); } private void createSettingsGroup(Composite settingsSection) { Group connectionGroup = new Group(settingsSection, SWT.NONE); connectionGroup.setFont(compositeFragment.getFont()); GridLayout cgLayout = new GridLayout(3, false); connectionGroup.setLayout(cgLayout); GridData cgGridData = new GridData(GridData.FILL_HORIZONTAL); connectionGroup.setLayoutData(cgGridData); connectionGroup.setText(Messages.ZendDebuggerServerSettingsSection_Connection_settings); createConnectionSection(connectionGroup); } private void createConnectionSection(Group connectionGroup) { // Client IP Label clientIpLabel = new Label(connectionGroup, SWT.None); clientIpLabel.setText(Messages.ZendDebuggerServerSettingsSection_Client_IPs); clientIpText = new Text(connectionGroup, SWT.BORDER); GridData citLayoutData = new GridData(GridData.FILL_HORIZONTAL); clientIpText.setLayoutData(citLayoutData); clientIpText.setText(settingsWorkingCopy.getAttribute(PROP_CLIENT_IP)); clientIpText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { String clientIp = clientIpText.getText(); settingsWorkingCopy.setAttribute(PROP_CLIENT_IP, clientIp); validate(); } }); String ipTextProposal = getIPsProposal(); if (ipTextProposal != null) { clientIpText.setText(ipTextProposal); } Button configureIPs = SWTFactory.createPushButton(connectionGroup, Messages.ZendDebuggerServerSettingsSection_Configure_button, null); configureIPs.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { widgetDefaultSelected(e); } public void widgetDefaultSelected(SelectionEvent e) { String clientIPs = getClientIPs(clientIpText.getText()); if (!clientIPs.isEmpty()) { clientIpText.setText(clientIPs); validate(); } } }); // Client port Label clientPortLabel = new Label(connectionGroup, SWT.None); clientPortLabel.setText(Messages.ZendDebuggerServerSettingsSection_Client_port); final Text clientPortText = new Text(connectionGroup, SWT.BORDER); GridData cptLayoutData = new GridData(GridData.FILL_HORIZONTAL); cptLayoutData.horizontalSpan = 2; clientPortText.setLayoutData(cptLayoutData); clientPortText.setText(settingsWorkingCopy.getAttribute(PROP_CLIENT_PORT)); clientPortText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { String port = clientPortText.getText(); settingsWorkingCopy.setAttribute(PROP_CLIENT_PORT, port); validate(); } }); // Response timeout Label responseTimeoutLabel = new Label(connectionGroup, SWT.None); responseTimeoutLabel.setText(Messages.ZendDebuggerServerSettingsSection_Response_timeout); final Text responseTimeoutText = new Text(connectionGroup, SWT.BORDER); GridData rttLayoutData = new GridData(GridData.FILL_HORIZONTAL); rttLayoutData.horizontalSpan = 2; responseTimeoutText.setLayoutData(rttLayoutData); responseTimeoutText.setText(settingsWorkingCopy.getAttribute(PROP_RESPONSE_TIMEOUT)); responseTimeoutText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { String responseTimeout = responseTimeoutText.getText(); settingsWorkingCopy.setAttribute(PROP_RESPONSE_TIMEOUT, responseTimeout); validate(); } }); } private String getIPsProposal() { final Server server = (Server) compositeFragment.getData(); // Check if server exists and is not registered yet (wizard context) if (server == null || ServersManager.findServer(server.getUniqueId()) != null) return null; final StringBuilder bestMatches = new StringBuilder(); BusyIndicator.showWhile(PlatformUI.getWorkbench().getDisplay(), new Runnable() { public void run() { String proposals = (new ZendDebuggerHostProposalComputer()).computeProposals(server); if (proposals != null) bestMatches.append(proposals); } }); return bestMatches.length() != 0 ? bestMatches.toString() : null; } private String getClientIPs(String userHosts) { final List<Inet4Address> detectedIPs = new ArrayList<Inet4Address>(); BusyIndicator.showWhile(PlatformUI.getWorkbench().getDisplay(), new Runnable() { public void run() { // Reset network monitor to have latest results networkMonitor = new NetworkMonitor(); detectedIPs.addAll(networkMonitor.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(); } }