/** * This file Copyright (c) 2005-2008 Aptana, Inc. This program is * dual-licensed under both the Aptana Public License and the GNU General * Public license. You may elect to use one or the other of these licenses. * * This program is distributed in the hope that it will be useful, but * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. Redistribution, except as permitted by whichever of * the GPL or APL you select, is prohibited. * * 1. For the GPL license (GPL), you can redistribute and/or modify this * program under the terms of the GNU General Public License, * Version 3, as published by the Free Software Foundation. You should * have received a copy of the GNU General Public License, Version 3 along * with this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Aptana provides a special exception to allow redistribution of this file * with certain Eclipse Public Licensed code and certain additional terms * pursuant to Section 7 of the GPL. You may view the exception and these * terms on the web at http://www.aptana.com/legal/gpl/. * * 2. For the Aptana Public License (APL), this program and the * accompanying materials are made available under the terms of the APL * v1.0 which accompanies this distribution, and is available at * http://www.aptana.com/legal/apl/. * * You may view the GPL, Aptana's exception and additional terms, and the * APL in the file titled license.html at the root of the corresponding * plugin containing this source file. * * Any modifications to this file must keep this entire header intact. */ package com.aptana.ide.server.ui.generic.dialogs; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.HashSet; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.TitleAreaDialog; 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.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.Control; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import com.aptana.ide.core.IdeLog; import com.aptana.ide.core.ui.SWTUtils; import com.aptana.ide.server.ServerCore; import com.aptana.ide.server.core.IAbstractConfiguration; import com.aptana.ide.server.core.IServer; import com.aptana.ide.server.core.ServerCorePlugin; import com.aptana.ide.server.generic.GenericServer; import com.aptana.ide.server.generic.GenericServerTypeDelegate; import com.aptana.ide.server.ui.IConfigurationDialog; import com.aptana.ide.server.ui.views.ServerLabelProvider; /** * @author Kevin Sawicki (ksawicki@aptana.com) */ public class GenericConfigurationDialog extends TitleAreaDialog implements IConfigurationDialog { private boolean isEdit; private IAbstractConfiguration configuration; private Composite displayArea; private Label serverNameLabel; private Text serverNameText; private Text healthURLText; private Text pollingIntervalText; private HashSet<String> serverNames = new HashSet<String>(); /** * Remote jaxer section */ private Label hostnameLabel; private Text hostnameText; private Label portLabel; private Text portText; private Label serverDescLabel; private Text serverDescText; private Text startText; private Text stopText; private Text pauseText; private Text resumeText; private Text path; private Button isLocal; private IServer server; private Text log; private Text docRootText; private ModifyListener validationModifyListener; /** * Default jaxer configuration dialog constructor */ public GenericConfigurationDialog() { super(Display.getDefault().getActiveShell()); validationModifyListener = new ModifyListener() { public void modifyText(ModifyEvent e) { validate(); } }; } /** * @see org.eclipse.jface.dialogs.Dialog#create() */ @Override public void create() { super.create(); PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(), "com.aptana.ide.server.ui.servers_add_generic"); //$NON-NLS-1$ } /** * @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite) */ protected Control createDialogArea(Composite parent) { this.setTitle(Messages.GenericConfigurationDialog_TITLE); this.getShell().setText(Messages.GenericConfigurationDialog_SHELL_TITLE); this.setMessage(Messages.GenericConfigurationDialog_GENERIC_); displayArea = new Composite(parent, SWT.NONE); GridLayout daLayout = new GridLayout(3, false); daLayout.marginHeight = 10; daLayout.marginWidth = 10; displayArea.setLayout(daLayout); GridData daData = new GridData(SWT.FILL, SWT.FILL, true, true); daData.widthHint = 550; displayArea.setLayoutData(daData); serverNameLabel = new Label(displayArea, SWT.LEFT); serverNameLabel.setText(Messages.GenericConfigurationDialog_SERVER_NAME); serverNameText = new Text(displayArea, SWT.BORDER | SWT.SINGLE); GridData sntData = new GridData(SWT.FILL, SWT.FILL, true, false); sntData.horizontalSpan = 2; serverNameText.setLayoutData(sntData); if (this.configuration != null) { serverNameText.setText(configuration.getStringAttribute(IServer.KEY_NAME)); } serverNameText.addModifyListener(validationModifyListener); serverDescLabel = new Label(displayArea, SWT.LEFT); serverDescLabel.setText(Messages.GenericConfigurationDialog_SERVER_DESCRIPTION); serverDescText = new Text(displayArea, SWT.BORDER | SWT.SINGLE); if (this.configuration != null) { serverDescText.setText(configuration.getStringAttribute(IServer.KEY_DESCRIPTION)); } GridData sndData = new GridData(SWT.FILL, SWT.FILL, true, false); sndData.horizontalSpan = 2; serverDescText.setLayoutData(sndData); hostnameLabel = new Label(displayArea, SWT.LEFT); hostnameLabel.setText(Messages.GenericConfigurationDialog_5); hostnameText = new Text(displayArea, SWT.SINGLE | SWT.BORDER); if (this.configuration != null) { String path = this.configuration.getStringAttribute(IServer.KEY_HOST); hostnameText.setText(path); } hostnameText.addModifyListener(validationModifyListener); GridData htData = new GridData(SWT.FILL, SWT.FILL, true, false); htData.horizontalSpan = 2; hostnameText.setLayoutData(htData); portLabel = new Label(displayArea, SWT.LEFT); portLabel.setText(Messages.GenericConfigurationDialog_HOSTNAME); portText = new Text(displayArea, SWT.SINGLE | SWT.BORDER); String port = this.configuration.getStringAttribute(IServer.KEY_PORT); portText.setText(port); portText.addModifyListener(validationModifyListener); GridData ptData = new GridData(SWT.FILL, SWT.FILL, true, false); ptData.horizontalSpan = 2; portText.setLayoutData(ptData); log = createOpenExecutable(Messages.GenericConfigurationDialog_PATH_TO_LOG_FILE, displayArea, IServer.KEY_LOG_PATH); Composite heartbeatComp = new Composite(displayArea, SWT.NONE); GridLayout layout = new GridLayout(3, false); layout.marginHeight = 0; layout.verticalSpacing = 0; layout.marginWidth = 0; heartbeatComp.setLayout(layout); GridData hbcData = new GridData(SWT.FILL, SWT.FILL, true, false); hbcData.horizontalSpan = 3; heartbeatComp.setLayoutData(hbcData); Label hbLabel = new Label(heartbeatComp, SWT.NONE); hbLabel.setText(Messages.GenericConfigurationDialog_LBL_Heartbeat); healthURLText = new Text(heartbeatComp, SWT.SINGLE | SWT.BORDER); GridData hutData = new GridData(SWT.FILL, SWT.CENTER, true, false); healthURLText.setLayoutData(hutData); if (configuration != null) { healthURLText.setText(configuration.getStringAttribute(GenericServerTypeDelegate.HEALTH_URL)); } healthURLText.addModifyListener(validationModifyListener); Composite heartbeatComp2 = new Composite(heartbeatComp, SWT.NONE); heartbeatComp2.setLayout(new GridLayout(2, false)); heartbeatComp2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); Label pollingLabel = new Label(heartbeatComp2, SWT.LEFT); pollingLabel.setText(Messages.GenericConfigurationDialog_LBL_Polling); pollingIntervalText = new Text(heartbeatComp2, SWT.SINGLE | SWT.BORDER); GridData pollData = new GridData(SWT.FILL, SWT.FILL, false, false); pollData.widthHint = 30; pollingIntervalText.setLayoutData(pollData); int interval = configuration.getIntAttribute(GenericServerTypeDelegate.POLLING_INTERVAL); if (interval > 0) { pollingIntervalText.setText(Integer.toString(interval / 1000)); } else { pollingIntervalText.setText("30"); //$NON-NLS-1$ } pollingIntervalText.addModifyListener(validationModifyListener); new Label(heartbeatComp, SWT.NONE); Label healthBanner = new Label(heartbeatComp, SWT.NONE); GridData hbData = new GridData(); hbData.verticalIndent = -5; hbData.horizontalSpan = 2; healthBanner.setLayoutData(hbData); healthBanner.setText(Messages.GenericConfigurationDialog_LBL_Banner); final Font smallFont = SWTUtils.getDefaultSmallFont(); healthBanner.setFont(smallFont); isLocal = new Button(displayArea, SWT.CHECK); ptData = new GridData(SWT.FILL, SWT.FILL, true, false); ptData.verticalIndent = 10; ptData.horizontalSpan = 3; isLocal.setText(Messages.GenericConfigurationDialog_IS_SERVER_LOCAL); isLocal.setLayoutData(ptData); path = createOpenExecutable(Messages.GenericConfigurationDialog_PATH, displayArea, IServer.KEY_PATH); docRootText = createDirecotrySelectionText(Messages.GenericConfigurationDialog_DOCUMENT_ROOT, displayArea, IServer.KEY_DOCUMENT_ROOT); startText = createText(Messages.GenericConfigurationDialog_START_SERVER, displayArea, GenericServerTypeDelegate.START_SERVER_COMMAND); stopText = createText(Messages.GenericConfigurationDialog_STOP_SERVER, displayArea, GenericServerTypeDelegate.STOP_SERVER_COMMAND); pauseText = createText(Messages.GenericConfigurationDialog_PAUSE_SERVER, displayArea, GenericServerTypeDelegate.PAUSE_SERVER_COMMAND); resumeText = createText(Messages.GenericConfigurationDialog_RESUME_SERVER, displayArea, GenericServerTypeDelegate.PAUSE_SERVER_COMMAND); isLocal.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { checkLocal(); validate(); } }); if (configuration != null) { isLocal.setSelection(configuration.getBooleanAttribute(GenericServerTypeDelegate.IS_LOCAL)); } checkLocal(); return displayArea; } /** * @param label * @param parent * @param key * @return new Text */ protected Text createText(String label, Composite parent, String key) { Label ll = new Label(parent, SWT.NONE); ll.setText(label); Text t = new Text(parent, SWT.SINGLE | SWT.BORDER); GridData ptData = new GridData(SWT.FILL, SWT.FILL, true, false); ptData.horizontalSpan = 2; t.setLayoutData(ptData); if (configuration != null) { t.setText(configuration.getStringAttribute(key)); } t.addModifyListener(validationModifyListener); return t; } /** * Creates a direcoty selection area with a label, browse button and a text. The initial value to fill in that text * is taken by the given key. * * @param parent */ protected Text createDirecotrySelectionText(String label, Composite parent, String key) { // Add the document root text field Label l = new Label(parent, SWT.NONE); l.setText(label); final Text text = new Text(parent, SWT.BORDER); if (configuration != null) { String value = configuration.getStringAttribute(key); if (value != null) { text.setText(value); } } text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); text.addModifyListener(validationModifyListener); Button browseBt = new Button(parent, SWT.PUSH); browseBt.setText(Messages.GenericConfigurationDialog_BROWSE); browseBt.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { DirectoryDialog dialog = new DirectoryDialog(getShell()); String path = dialog.open(); if (path != null) { text.setText(path); } } }); // Set the browse button as the Text data so we will be able to disable it easily when the Text is // disabled. This is a hack and we should think of a nicer way to do that. text.setData("browse", browseBt);// $NON-NLS-1$ //$NON-NLS-1$ return text; } /** * @param label * @param parent * @param key * @return new text */ protected Text createOpenExecutable(String label, Composite parent, String key) { Label ll = new Label(parent, SWT.NONE); ll.setText(label); final Text t = new Text(parent, SWT.SINGLE | SWT.BORDER); GridData ptData = new GridData(SWT.FILL, SWT.CENTER, true, false); ptData.horizontalSpan = 1; t.setLayoutData(ptData); if (configuration != null) { t.setText(configuration.getStringAttribute(key)); } t.addModifyListener(validationModifyListener); Button browser = new Button(parent, SWT.PUSH); browser.setText(Messages.GenericConfigurationDialog_BROWSE); browser.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { FileDialog fdlg = new FileDialog(getShell(), SWT.OPEN); String text = t.getText(); if (text.length() > 0) { File file = new File(text); File parentFile = file.getParentFile(); if (parentFile != null) { fdlg.setFilterPath(parentFile.getPath()); } } String open = fdlg.open(); if (open != null) { t.setText(open); } } }); // Set the browse button as the Text data so we will be able to disable it easily when the Text is // disabled. This is a hack and we should think of a nicer way to do that. t.setData("browse", browser);// $NON-NLS-1$ //$NON-NLS-1$ return t; } /** * @see org.eclipse.jface.dialogs.TitleAreaDialog#createContents(org.eclipse.swt.widgets.Composite) */ protected Control createContents(Composite parent) { Control c = super.createContents(parent); initDublicateNames(); validate(); return c; } private void initDublicateNames() { IServer[] servers = ServerCore.getServerManager().getServers(); for (IServer s : servers) { if (!s.getId().equals(configuration.getStringAttribute(IServer.KEY_ID))) { serverNames.add(s.getName()); } } } private void validate() { String name = serverNameText.getText(); String hostname = hostnameText.getText(); Button ok = getButton(IDialogConstants.OK_ID); String port = portText.getText(); boolean error = false; if (name.trim().length() == 0) { setErrorMessage(Messages.GenericConfigurationDialog_SERVER_NAME_MUST_NOT_BE_BLANK); error = true; ok.setEnabled(false); } else if (serverNames.contains(name)) { setErrorMessage(Messages.GenericConfigurationDialog_SERVER_NAME_EXISTS); error = true; } else if (hostname.trim().length() == 0) { setErrorMessage(Messages.GenericConfigurationDialog_HOST_NAME_MUST_NOT_BE_BLANK); error = true; } if (!error) { try { Integer i = Integer.parseInt(port); if (i < 0 || i > 65535) { setErrorMessage(Messages.GenericConfigurationDialog_PORT_MUST_BE_IN_RANGE); error = true; } } catch (NumberFormatException e) { setErrorMessage(Messages.GenericConfigurationDialog_PORT_MUST_BE_INTEGER); error = true; } } if (!error && isLocal.getSelection()) { File file = new File(path.getText()); if (file.exists()) { if (file.isFile()) { error = false; if (startText.getText().length() == 0) { setErrorMessage(Messages.GenericConfigurationDialog_START_IS_EMPTY); error = true; } else if (stopText.getText().length() == 0) { setErrorMessage(Messages.GenericConfigurationDialog_STOP_IS_EMPTY); error = true; } else if (log.getText().length() != 0) { file = new File(log.getText()); if (!file.exists() || !file.isFile()) { setErrorMessage(Messages.GenericConfigurationDialog_PATH_TO_LOG_FILE_SHOULD_BE_EMPTY_OR_POINT_TO_FILE); error = true; } } } else { error = true; setErrorMessage(Messages.GenericConfigurationDialog_PATH_SHOULD_NOT_POINT_TO_DIRECTORY); } } else { error = true; setErrorMessage(Messages.GenericConfigurationDialog_NO_FILE_UNDER_A_GIVEN_PATH); } if (!error) { String docRootPath = docRootText.getText().trim(); if (docRootPath.length() == 0 && !new File(docRootPath).isDirectory()) { error = true; setErrorMessage(Messages.GenericConfigurationDialog_DOCUMENT_ROOT_ERROR); } } } if (!error) { if (healthURLText.getText().trim().length() > 0) { try { new URL(healthURLText.getText().trim()); } catch (MalformedURLException e) { error = true; setErrorMessage(Messages.GenericConfigurationDialog_MSG_InvalidHeartbeat); } if (!error) { try { Integer i = Integer.parseInt(pollingIntervalText.getText()); if (i < 1) { setErrorMessage(Messages.GenericConfigurationDialog_MSG_PollingBound); error = true; } } catch (NumberFormatException e) { setErrorMessage(Messages.GenericConfigurationDialog_MSG_PollingInteger); error = true; } } } } if (!error) { boolean allowed = false; if (server instanceof GenericServer) { boolean isLocal = configuration.getBooleanAttribute(GenericServerTypeDelegate.IS_LOCAL); String healthURL = configuration.getStringAttribute(GenericServerTypeDelegate.HEALTH_URL); int pollingInterval = configuration.getIntAttribute(GenericServerTypeDelegate.POLLING_INTERVAL); // Allow edits of running servers that are just polling if (!isLocal && healthURL != null && healthURL.length() > 0 && pollingInterval > 0) { allowed = true; } } if (server != null) { if (!allowed && !(server.getServerState() == IServer.STATE_STOPPED || server.getServerState() == IServer.STATE_UNKNOWN || server.getServerState() == IServer.STATE_NOT_APPLICABLE)) { setErrorMessage(ServerLabelProvider.SERVER_IS_RUNNING_NO_EDIT); ok.setEnabled(false); return; } } setErrorMessage(null); } ok.setEnabled(!error); } /** * @see org.eclipse.jface.dialogs.Dialog#okPressed() */ protected void okPressed() { configuration.setStringAttribute(IServer.KEY_NAME, serverNameText.getText()); configuration.setStringAttribute(IServer.KEY_DESCRIPTION, serverDescText.getText()); configuration.setStringAttribute(IServer.KEY_HOST, hostnameText.getText()); configuration.setIntAttribute(IServer.KEY_PORT, Integer.parseInt(portText.getText())); configuration.setStringAttribute(IServer.KEY_PATH, path.getText()); configuration.setStringAttribute(GenericServerTypeDelegate.START_SERVER_COMMAND, startText.getText()); configuration.setStringAttribute(GenericServerTypeDelegate.STOP_SERVER_COMMAND, stopText.getText()); configuration.setStringAttribute(GenericServerTypeDelegate.PAUSE_SERVER_COMMAND, pauseText.getText()); configuration.setStringAttribute(GenericServerTypeDelegate.RESUME_SERVER_COMMAND, resumeText.getText()); configuration.setBooleanAttribute(GenericServerTypeDelegate.IS_LOCAL, isLocal.getSelection()); configuration.setStringAttribute(IServer.KEY_LOG_PATH, log.getText()); configuration.setStringAttribute(GenericServerTypeDelegate.HEALTH_URL, healthURLText.getText()); configuration.setStringAttribute(IServer.KEY_DOCUMENT_ROOT, docRootText.getText()); try { int polling = Integer.parseInt(pollingIntervalText.getText()); configuration.setIntAttribute(GenericServerTypeDelegate.POLLING_INTERVAL, polling * 1000); } catch (NumberFormatException e) { IdeLog.logInfo(ServerCorePlugin.getDefault(), Messages.GenericConfigurationDialog_INF_IntervalError, e); } super.okPressed(); } /** * @see com.aptana.ide.server.ui.IConfigurationDialog#getDialog() */ public Dialog getDialog() { return this; } /** * @see com.aptana.ide.server.ui.IConfigurationDialog#isEdit() */ public boolean isEdit() { return isEdit; } /** * @see com.aptana.ide.server.ui.IConfigurationDialog#setEdit(boolean) */ public void setEdit(boolean isEdit) { this.isEdit = isEdit; } /** * @see com.aptana.ide.server.ui.IConfigurationDialog#getConfiguration() */ public IAbstractConfiguration getConfiguration() { return configuration; } /** * @see com.aptana.ide.server.ui.IConfigurationDialog#setConfiguration(com.aptana.ide.server.core.IAbstractConfiguration) */ public void setConfiguration(IAbstractConfiguration configuration) { this.configuration = configuration; } private void checkLocal() { boolean en = isLocal.getSelection(); healthURLText.setEnabled(!en); pollingIntervalText.setEnabled(!en); path.setEnabled(en); Object browseButton = path.getData("browse");// $NON-NLS-1$ //$NON-NLS-1$ if (browseButton instanceof Button) { ((Button)browseButton).setEnabled(en); } startText.setEnabled(en); stopText.setEnabled(en); pauseText.setEnabled(en); resumeText.setEnabled(en); docRootText.setEnabled(en); browseButton = docRootText.getData("browse");// $NON-NLS-1$ //$NON-NLS-1$ if (browseButton instanceof Button) // $NON-NLS-1$ { ((Button)browseButton).setEnabled(en); } } /** * @see com.aptana.ide.server.ui.IConfigurationDialog#setServer(com.aptana.ide.server.core.IServer) */ public void setServer(IServer server) { this.server = server; } }